【问题标题】:node.js fs.writeFile Not Completely Overwriting Filenode.js fs.writeFile 未完全覆盖文件
【发布时间】:2013-09-11 20:20:51
【问题描述】:

我有一个长度为 X 的文件,它被长度为 X-Y 的字符串覆盖。问题是,该文件仍然保留 X-Y 之后的信息,因此它与第一个较长的文件一样长。所以这是我的测试输出,非常适合我:

文件开始于:

{
    "sOption1": "String",
    "nOption2": 23.5,
    "sOption3": "String",
    "bOption3B": true,
    "anOption4": [
        5,
        6,
        7
    ],
    "sNewString": "FruitSalad",
    "bNewBoolean": false,
    "iNewNumber": 14.2,
    "anNewArray": [
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10
    ],
    "oNewObject": {
        "bToBeOrNotToBe": true,
        "sFinishQuote": "That is the question"
    }
}

将正在写入的数据更改为:

{
    "sOption1": "String",
    "nOption2": 23.5,
    "sOption3": "String",
    "bOption3B": true,
    "anOption4": [
        5,
        6,
        7
    ],
    "sNewString": "YummyYummy",
    "bNewBoolean": true,
    "iNewNumber": 2.14,
    "anNewArray": [
        10,
        9
    ],
    "oNewObject": {
        "bToBeOrNotToBe": false,
        "sNewQuote": "To die, to sleep, no more"
    }
}

在此之后,文件现在是:

{
    "sOption1": "String",
    "nOption2": 23.5,
    "sOption3": "String",
    "bOption3B": true,
    "anOption4": [
        5,
        6,
        7
    ],
    "sNewString": "YummyYummy",
    "bNewBoolean": true,
    "iNewNumber": 2.14,
    "anNewArray": [
        10,
        9
    ],
    "oNewObject": {
        "bToBeOrNotToBe": false,
        "sNewQuote": "To die, to sleep, no more"
    }
}       "bToBeOrNotToBe": true,
        "sFinishQuote": "That is the question"
    }
}}

看到对象末尾的垃圾了吗?它是从上一个文件中遗留下来的,即使我用以下代码写出来:

DeviceConfiguration.prototype.SetPersistentUserOption = function(sNewOptionName, NewOption)
{
    var sNewFile = "";
    var fs = require('fs');

    //if one of the primitive types, it's simple, just add it to object
    if(typeof(NewOption) == "string" || typeof(NewOption) == "number" || typeof(NewOption) == "boolean")
    {
        this.oPersistentUserOptions[sNewOptionName] = NewOption;
    }
    else if(NewOption instanceof Array)
    {
        //blank out array if it was there already
        this.oPersistentUserOptions[sNewOptionName] = [];   

        //now go back and copy each element over one at a time
        for(var nIndex = 0; nIndex < NewOption.length; nIndex++)
        {   this.oPersistentUserOptions[sNewOptionName][nIndex] = NewOption[nIndex];    }
    }
    else if(NewOption instanceof Object)
    {
        //blank out object if it was there already
        this.oPersistentUserOptions[sNewOptionName] = {};   

        //now go back and copy each element over one at a time
        for(Member in NewOption)
        {   this.oPersistentUserOptions[sNewOptionName][Member] = NewOption[Member];    
        }
    }

    //stringify the object, and make it pretty with options null, 4
    sNewFile = JSON.stringify(this.oPersistentUserOptions, null, 4);

    //write to the file, parameter is immediately in object memory though
    fs.writeFile(PERSISTENT_USER_SELECTED_OPTIONS_FILENAME, sNewFile, function(err){console.log(err);});
    //fs.writeFileSync(PERSISTENT_USER_SELECTED_OPTIONS_FILENAME, sNewFile);

    console.log(sNewFile.length);
    console.log(sNewFile);
};

我已检查以确保 sNewFile 变量的长度正确,并且确实如此。在随后的写入磁盘之间,我也暂停了长达 6 秒,所以我看不出这怎么可能是时间问题。

如果我使用 writeFileSync,问题就会消失,但我真的没有选择为此应用程序执行同步写入,因为我对时间很关键,并且不想放慢速度来写入磁盘。

我在 node.js 0.8.21 上,但它看起来并没有改变 fs 和最新版本之间的任何接口。

其他人打过这样的事吗?这让我很适应。 . .

【问题讨论】:

  • 这是什么操作系统?听起来好像是默认以r+模式打开,这没什么意义。
  • 我的代码在 ubuntu 上对你有用吗?
  • 确实如此,只是运行它。在发布之前,我做了一些类似的简单测试,并且无法让它失败。
  • 在 0.10 上对其进行测试,或者在编写新内容之前通过删除文件(如果存在)来破解它。
  • 我刚刚用正在编写的整个函数更新了问题。我现在真的不想更新 0.10。您对在写出文件之前如何删除文件有任何建议吗?我尝试使用 fs.truncate 进行破解,但我显然在文档中遗漏了一些内容,因为我无法让它退出崩溃:fs.truncate(PERSISTENT_USER_SELECTED_OPTIONS_FILENAME, 0, function(err){});

标签: javascript node.js file-io


【解决方案1】:

我刚刚在 0.8.21 ( linux ) 上对此进行了测试,并且按预期工作。

var fs = require('fs')

var str1 = "aaaaaaaaaa"
var str2 = "bbbbbb"
var str3 = "bbbbbbaaaa"

fs.writeFile('test',str1,function(){
  fs.writeFile('test',str2,function(){
    fs.readFile('test','utf8',function(err,buff){
      console.log(buff === str2)
      console.log(buff === str3)
    })
  })
})

output
> node test.js
true
false

【讨论】:

  • 我刚刚更新了问题以显示我正在写出的内容,该数据在 write 调用之后直接来自控制台。
  • 发现我的问题,writeFile 工作正常。非常感谢你的帮助。我的问题是,在我的上游代码中,我连续 6 次写入文件而没有暂停。这导致了一个非常可重复的比赛条件,看起来好像不是时间安排。我找错地方了。
猜你喜欢
  • 2016-03-23
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 2019-09-18
  • 2014-08-19
  • 2013-05-01
相关资源
最近更新 更多