Search code examples
javascriptfileapi

How to create file in the local fs using modern FileApi?


I have this code:

document.querySelector('#myfile').onchange = function(e) {
  var files = this.files;
  window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function(fs) {
    let file = files[0];
    let nem_file_name = file.name + '_copy';
    fs.root.getFile(nem_file_name, {
      create: true,
      exclusive: true
    }, function(fileEntry) {
      fileEntry.createWriter(fileWriter => {
        fileWriter.write(file);
      }, () => alert('error 1'));
    }, err => alert('error 2 ' + err));
  }, () => alert('error 3'));
};
<input type="file" id="myfile" ref="myfile" multiple />

I want to create a copy of my file when I select it with the input control. What's wrong with my code? I got no errors and nothing happens


Solution

  • The "modern" API is called File System Access, it is still only a proposal, but is expected to supersede the previous and deprecated File System API, and is already available in Chromium browsers.

    To write a file using this API, you first request a FileHandle using the showSaveFilePicker() method, then you can create a writer from that handle and append data using that writer:

    onclick = async (e) => { // needs to be initiated by an user gesture
      const handle = await showSaveFilePicker(); // prompt "Save As"
      const writer = await handle.createWritable(); // request writable stream
      await writer.write( new Blob( [ "some data" ] ) ); // write the Blob directly
      writer.close(); // end writing
    };
    

    But this API is still overprotected, so it unfortunately can't be ran in cross-origin iframes like the ones used here by StackSnippet or most popular fiddling services. So in order to make a live demo, I had to make a plunker, that you must run in windowed mode.

    And if you need to set the name of the file yourself, you need to request for a directory access using showDirectoryPicker() and then to get a FileHandle from that directory handle using its getFileHandle() method. plnkr