With Chrome FileSystem, let the user choose a Directory, load files inside. And save files in that directory without prompting again

二次信任 提交于 2019-11-30 15:22:33

Your save method should work fine (mostly, see below) for your second requirement (write to a code-chosen filename without another user prompt), but there are a couple of bugs in open (at least as presented in the question):

  • Inside the chooseEntry callback, this !== fileHandler because the callback is invoked with a different this (probably the background page’s window object).
    You can work around this in several ways:
    • Use fileHandler instead of this (if you are not using it as any kind of prototype).
    • Use .bind(this) to bind each of your callback functions to the same context.
    • Use var self = this; at the top of open and use self.entry (et cetera) in the callbacks.
  • You may want to call cb for the success case. Maybe you have another way of postponing calls to (e.g.) fileHandler.save (clicking on some element to trigger the save?), but adding something like

    ⋮
    cb && cb(self.entry);
    ⋮
    

    after self.entry = dirEntry makes it easy to (e.g.) chain open and save:

    fileHandler.open(function(ent) {
        fileHandler.save('newfile','This is the text\nto save in the (possibly) new file.');
    });
    

There is a latent bug in save: if you ever overwrite an existing file, then you will want to call writer.truncate() (unless you always write more bytes than the file originally held).

⋮
writer.onwrite = function() {
    writer.onwrite = null;
    writer.truncate(writer.position);
};
writer.write(…);
⋮

It looks like you have a good start on the file listing part. If you want to reference the list of files later, then you might want to save them in your object instead of just logging them; this can get a bit hairy if you want to recurse into subdirectories (and also not assume that readEntries returns everything for its first call).

function list_dir(dirent, cb, listing) {
    if (listing === undefined) listing = [];
    var reader = dirent.createReader();
    var read_some = reader.readEntries.bind(reader, function(ents) {
        if (ents.length === 0)
            return cb && cb(listing);
        process_some(ents, 0);
        function process_some(ents, i) {
            for(; i < ents.length; i++) {
                listing.push(ents[i]);
                if (ents[i].isDirectory)
                    return list_dir(ents[i], process_some.bind(null, ents, i + 1), listing);
            }
            read_some();
        }
    }, function() {
        console.error('error reading directory');
    });
    read_some();
}

You could use it in the open callback (assuming you add its success callback) like this:

fileHandler.open(function(ent) {
    ent && list_dir(ent, function(listing) {
        fileHandler.listing = listing;
        console.log('listing', fileHandler.listing.map(function(ent){return ent.fullPath}).join('\n'));
        fileHandler.save('a_dir/somefile','This is some data.');
    });
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!