Using Chrome FileSystem, let the user select a directory, upload files inside. And save the files in this directory without prompting again

I could not find examples with this scenario, so we go:

I want the user to select a directory, upload all files to it, change them and save this file, redefining it or saving a new file in the same directory without asking where it wants to save.

  • I do not know how to list directory files
  • I do not know how to save a file in a directory without prompting for a filechooser window

I believe this is possible because I see something similar here (last paragraph): http://www.developer.com/lang/using-the-file-api-outside-the-sandbox-in-chrome-packaged -apps.html

Any answer would be appreciated, thanks

EDIT: Thanks to Chris Johnson for giving me this great answer:

var fileHandler = function() {

  var _entry = null;

  this.open = function(cb) {

    chrome.fileSystem.chooseEntry({
      type: 'openDirectory'
    }, function(dirEntry) {

      if (!dirEntry || !dirEntry.isDirectory) {
        cb && cb(null);
        return;
      }

      _entry = dirEntry;

      listDir(_entry, cb);
    });


  };

  this.save = function(filename, source) {

    chrome.fileSystem.getWritableEntry(_entry, function(entry) {

      entry.getFile(filename, {
        create: true
      }, function(entry) {
        entry.createWriter(function(writer) {

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

          writer.write(new Blob([source], {
            type: 'text/javascript'
          }));
        });
      });

    });

  };

  this.saveAs = function(filename, source) {

    chrome.fileSystem.chooseEntry({
      type: 'openDirectory'
    }, function(entry) {

      chrome.fileSystem.getWritableEntry(entry, function(entry) {

        entry.getFile(filename, {
          create: true
        }, function(entry) {
          entry.createWriter(function(writer) {

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

            writer.write(new Blob([source], {
              type: 'text/javascript'
            }));
          });
        });

      });
    });

  };

  var listDir = function(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);
        }

        var process_some = function(ents, i) {

            for (; i < ents.length; i++) {
              listing.push(ents[i]);

              if (ents[i].isDirectory) {
                return listDir(ents[i], process_some.bind(null, ents, i + 1), listing);
              }
            }

            read_some();
          };

        process_some(ents, 0);

      }, function() {
        console.error('error reading directory');
      });

      read_some();
    };

};
+4
source share
1 answer

Your method saveshould work fine (basically, see below) for your second requirement (write to the name of the selected code without the username), but there are a few errors in open(at least as presented in the question):

  • In the callback chooseEntry this !== fileHandler, because the callback is called using another this(possibly background pages window).
    You can get around this in several ways:
    • Use fileHandlerinstead this(if you are not using it as any prototype).
    • .bind(this) .
    • var self = this; open self.entry (et cetera) .
  • cb . , (,) fileHandler.save ( - ?), -

    cb && cb(self.entry);
    

    self.entry = dirEntry () open save:

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

save : - , writer.truncate() ( , ).


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

, , . , , ; , ( , readEntries ).

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();
}

open ( , ) :

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.');
    });
});
+5

Source: https://habr.com/ru/post/1527803/


All Articles