overwrite a file with HTML5 FileWriter
Asked Answered
P

5

14

I'm using HTML5 FileWriter API to save the state of my webapp. I have bit of JS that periodically calls FileWriter.write to do that (so , over time, the write method is called several times). By default FileWriter API use an 'append' approach to writing files which does not suits my needs since I wan't to overwrite the file content.

I first tried this:

this._writer.seek(0);
this._writer.write(content);

This is not working when you are writing a text shorter than the file content. I then tried this:

this._writer.truncate(0);
this._writer.write(content);

This code is supposed to clear the file and then write my new content but I'm getting the following error when write method is called:

Uncaught InvalidStateError: An operation that depends on state cached in an interface object was made but the state had changed since it was read from disk.

Odd thing: when I debug the code (with a breakpoint), the error does not occur, as if FileWriter.truncate was an asynchronous method...

I am stuck here, any ideas?

I am using Chrome 30.0.1599.69

Penology answered 17/10, 2013 at 12:25 Comment(0)
T
22

Here is a correct code that won't waste 500ms on waiting

fileWriter.onwriteend = function() {
    if (fileWriter.length === 0) {
        //fileWriter has been reset, write file
        fileWriter.write(blob);
    } else {
        //file has been overwritten with blob
        //use callback or resolve promise
    }
};
fileWriter.truncate(0);
Trichoid answered 5/12, 2013 at 8:5 Comment(3)
Could you elaborate? What is "d"?Penology
@htulipe, it's my jQuery.Deffered object I use externally to be notified when both truncation and writing is done. You may disregard it or add any other code you want to execute when writing is done.Trichoid
infinite loop detectedVanmeter
H
3

You can truncate and then write with two different FileWriter objects.

fileEntry.createWriter(function (fileWriter) {

        fileWriter.truncate(0);

    }, errorHandler);

fileEntry.createWriter(function (fileWriter) {

        var blob = new Blob(["New text"], { type: 'text/plain' });

        fileWriter.write(blob);

    }, errorHandler);
Homosexuality answered 14/11, 2015 at 16:14 Comment(0)
K
2

If you want to always override it, you can use this method

function save(path,data){
    window.resolveLocalFileSystemURL(dataDirectory, function(dir){
        dir.getFile(path, {create:true}, function(file){
            file.createWriter(function(fileWriter){
                fileWriter.seek(0);
                fileWriter.truncate(0);
                var blob = new Blob([data], {type:'text/plain'});
                fileWriter.write(blob);
            }, function(e){
                console.log(e);
            });
        });
    });
};
Kutchins answered 16/3, 2016 at 0:24 Comment(0)
P
1

A workaround is the following code:

this._writer.truncate(0);
window.setTimeout(function(){
    this._writer.write(content);
}.bind(this),500)

This simply wait 500 milliseconds before writing. Not great but it works...

Penology answered 17/10, 2013 at 14:3 Comment(0)
M
1

This is the simplest way how i use to delete the content of a file with syncFileSystem in my Chrome App.

Two createWriter, the first one truncates then the second one overwrites with nothing (you can change with your new value) :

file.createWriter((fileWriter)=>fileWriter.truncate(0));

file.createWriter((fileWriter)=> {

  fileWriter.onwriteend = function() {
    console.log('New Actions!');
  };

  var blob = new Blob([''], {type: 'text/plain'});
  fileWriter.write(blob);

});
Maltese answered 22/6, 2017 at 19:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.