Using the HTML5 FileWriter truncate() method?
Asked Answered
E

2

10

I'm experimenting with the HTML5 File API, and I'm needing to use a method which I don't know enough about (simply because it's hardly documented anywhere).

I'm talking about the FileWriter truncate() method, and I know it does what I need to do. Basically, rather than appending text to some file data or using seek() to overwrite a certain portion, I want to overwrite all of the data with something else (e.g. from "somedata" to "").

Here's a snippet of the FileWriter setup from HTML5Rocks, with truncate() added in.

function onInitFs(fs) {

  fs.root.getFile('log.txt', {create: false}, function(fileEntry) {

    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function(fileWriter) {

      fileWriter.seek(fileWriter.length); // Start write position at EOF.
      fileWriter.truncate(1);

      // Create a new Blob and write it to log.txt.
      var bb = new BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.
      bb.append('Hello World');
      fileWriter.write(bb.getBlob('text/plain'));

    }, errorHandler);

  }, errorHandler);

}

window.requestFileSystem(window.PERSISTENT, 1024*1024, onInitFs, errorHandler);

When it gets to calling writer.truncate(), calling writer.write() throws a File Exception error. I believe this is because the readyState is set to WRITING. Unfortunately, I don't know how to get around that.

I've already tried looking through the HTML5Rocks section on this, but it doesn't tell me anything about a truncate() method (although I know it exists from what the Webkit JS Console tells me).

Long story short, how I can I use the truncate() method correctly without getting an error?

Eatable answered 22/7, 2011 at 15:50 Comment(2)
W3C truncate spec enjoy.Bridgetbridgetown
Why truncate(1)? Why not truncate(0) to get a zero-sized file?Farthing
Q
11

Something like this might be a little more to the point:

truncate Changes the length of the file to that specified

fileEntry.createWriter(function(fileWriter) {
    var truncated = false;
    fileWriter.onwriteend = function(e) {
        if (!truncated) {
            truncated = true;
            this.truncate(this.position);
            return;
        }
        console.log('Write completed.');
    };
    fileWriter.onerror = function(e) {
        console.log('Write failed: ' + e.toString());
    };
    var blob = new Blob(['helo'], {type: 'plain/text'});
    fileWriter.write(blob);
}, errorHandler);
Quasar answered 15/1, 2013 at 22:38 Comment(0)
S
7

You need to be more async'y. :)

fileEntry.createWriter(function(fileWriter) {

  fileWriter.onwriteend = function(trunc) {
    fileWriter.onwriteend = null; // Avoid an infinite loop.
    // Create a new Blob and write it to log.txt.
    var bb = new BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.
    bb.append('Hello World');
    fileWriter.write(bb.getBlob('text/plain'));
  }

  fileWriter.seek(fileWriter.length); // Start write position at EOF.
  fileWriter.truncate(1);

}, errorHandler);
Simmonds answered 29/7, 2011 at 2:26 Comment(2)
I could be wrong, but I believe that this will cause infinite recursion since you're constantly triggering onwriteend. So you may need to nullify onwriteend from within it.Farthing
Good catch. In code I've written, I've always wanted to replace onwriteend anyway to establish the followup code. I was rewriting the original code to use the async truncate, but I didn't think about replacing/nullifying the onwriteend function.Simmonds

© 2022 - 2024 — McMap. All rights reserved.