4

我在我的项目中使用 HTML5 的文件系统功能。并尝试使用 for 循环将文本追加到文件中。但实际上它只影响最后一次写入的一次写入,即使我得到了5 个“写入完成”。(这应该意味着它成功写入 5 次)。这是我的代码:

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

function initFS() {
    console.log("init filesystem")
    window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (filesystem) {
        fs = filesystem;
        console.log(fs);
    }, 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.seek(fileWriter.length);
            fileWriter.onwriteend = function (e) {
                console.log('Write completed.');
            };
            fileWriter.onerror = function (e) {
                console.log('Write failed: ' + e.toString());
            };
            // Create a new Blob and write it to log.txt.
            var bb = new Blob([cont]);
            fileWriter.write(bb);
        }, errorHandler);
    }, errorHandler);
}

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

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

您可以在jsfiddle上尝试并从此链接 获取结果:文件系统:http ://fiddle.jshell.net:0/temporary/

我在想是不是写得这么快就不能及时保存了。所以我在它上面尝试了'setTimeout',它可以工作并完全写入。

有谁知道为什么?我怎样才能实现我想要的?如果你能帮助我,请先欣赏。

4

1 回答 1

5

fileWriter.write()是一个异步操作。你基本上在这里创造了一场比赛。没有超时会发生什么(如果写入速度很慢,甚至超时):

  • receiveFile(0)
  • fileWriter.seek(fileWriter.length /* == 0 */)
  • queue write(0)
  • receiveFile(1)
  • fileWriter.seek(fileWriter.length /* == 0 */)- 是的,仍然0没有执行实际的写入操作。
  • queue write(1)
  • ...
  • actual async write(0)
  • actual async write(1)
  • ...

剩下的事情就是实现细节和错误。总而言之:在进行另一次写入之前,始终等待写入操作完成。

当前的规范草案实际上不允许调用seek/writewhen readyState === WRITING,并指出一旦调用函数就readyState应该设置为。Chrome 还没有实现这个版本的规范,或者仍然有问题,或者如果会赶上你的比赛并在第二次调用(无超时版本)时抛出。WRITING writeInvalidStateError.seek()

于 2013-10-25T10:40:21.477 回答