Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js fs.writeFile Not Completely Overwriting File

I have a file that is of length X and it is being overwritten by a string that is of length X-Y. Problem is, that the file is still retaining the information past X-Y so that it is as long as the first longer file. So here is my test output that is giving me fits:

File started as:

{
    "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"
    }
}

Changed the data being written to the following:

{
    "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"
    }
}

After this, the file is now:

{
    "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"
    }
}}

See the garbage on the end of the object? It's left over from the previous file, even though I wrote it out with the following code:

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);
};

I have checked to make sure that the sNewFile variable is the correct length, and it is. I also have paused as long as 6 seconds between subsequent writes out to disk, so I can't see how this could be a timing issue.

If I use writeFileSync the problem goes away, but I really don't have the option to do synchronous writes for this application as I'm timing critical and don't want to have to slow down to write to the disk.

I'm on node.js 0.8.21, but it doesn't look like the interface has changed any for fs between that and the up to date version.

Anyone else hit anything like this? This is giving me fits. . .

like image 980
Brian Avatar asked Sep 11 '13 20:09

Brian


People also ask

Does FS writeFile overwrite?

fs. writeFileSync and fs. writeFile both overwrite the file by default. Therefore, we don't have to add any extra checks.

How do I overwrite a node in FS?

In node. js, you can require fs , and then call fs. writeFile with the filename, and data to write to that file (as a string or a buffer). That will overwrite the entire file, so to just append that data to the file instead, pass an options object with the flag key set to a .

What is the difference between writeFileSync and writeFile?

The only difference between writeFile and writeFileSync is in catching and handling the errors; otherwise, all parameters mentioned are available in both functions.

Is FS writeFile synchronous?

The fs. writeFileSync() is a synchronous method. The fs. writeFileSync() creates a new file if the specified file does not exist.


1 Answers

I've just tested this on 0.8.21 ( linux ) and this works as expected.

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
like image 51
supernova Avatar answered Sep 22 '22 11:09

supernova