Take the 2-minute tour ×

I use HTML5's filesystem feature in my project. And try to write text append to a file continuously by using for-loop. But actually it just effect one write which is the last write, even though I got 5 "Write completed."(That should means it success writing 5 times). Here is my code:

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
var fs;

function initFS() {
    console.log("init filesystem")
    window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (filesystem) {
        fs = filesystem;
    }, errorHandler);

function errorHandler(e) {
    var msg = '';
    switch (e.code) {
    console.log('Error: ' + msg);

function receiveFile(cont) {
    fs.root.getFile('log.txt', {
        create: true
    }, function (fileEntry) {
        // Create a FileWriter object for our FileEntry (log.txt).
        fileEntry.createWriter(function (fileWriter) {
            fileWriter.onwriteend = function (e) {
                console.log('Write completed.');
            fileWriter.onerror = function (e) {
            // Create a new Blob and write it to log.txt.
            var bb = new Blob([cont]);
        }, errorHandler);
    }, errorHandler);

function foo() {
        setTimeout(function () { // // it works, BTW: Why it didn't write the num in ascending order as expected
            (function (x) {
        }, i * 1000);
        //receiveFile(i); // didn't work, just write once

window.addEventListener("load", initFS, false);

You can try it on jsfiddle and get result from this link: filesystem:http://fiddle.jshell.net:0/temporary/

I am thinking about whether if it write so fast that can not be save in time. So I try 'setTimeout' on it and it works and write completely.

Anyone know why?. How I can implement what I want? Appreciate first if you can help me.

share|improve this question
add comment

1 Answer

up vote 0 down vote accepted

fileWriter.write() is an asynchronous operation. You basically created a race here. What happens without the timeouts (or even with the timeouts if the writes are slow):

  • receiveFile(0)
  • fileWriter.seek(fileWriter.length /* == 0 */)
  • queue write(0)
  • receiveFile(1)
  • fileWriter.seek(fileWriter.length /* == 0 */) - Yeah, still 0 as there was no actual write performed yet.
  • queue write(1)
  • ...
  • actual async write(0)
  • actual async write(1)
  • ...

The rest of what happens is down the implementation details and bugs. So in conclusion: Always wait for write operations to finish before doing another write.

The current spec draft actually disallows calling seek/write when readyState === WRITING, and states that readyState should be set to WRITING as soon as the write function gets called. Chrome does not implement this version of the spec yet, or is still buggy, or else if would have caught your race and thrown InvalidStateError on the second call to .seek() (timeout-less version).

share|improve this answer
Thanks a lot for your answer. It helps, especially the detail of asynchronous mechanism and link providing. I finally have idea to approach my will : 1. create first, and set size to it. 2.write content to it after seek corresponding offset of each loop. 3. make synchronous between 1.&2. –  xsuii Oct 25 '13 at 11:56
add comment

Your Answer


