2

I'm trying to use the FileSystem API to write an uploaded file on a SPA to a Local sandboxed FileSystem using the FileSystem API.

The File Is uploaded with drop acion and I can get the File object array in the call back. From the File I can get the ReadableStream calling the stream method (yes, it return only readable sream).

Considering that the uploaded file could be big enough, I would go for a streaming than loading entirely into a blob and then writing into FileSystem api.

So, following the docs the steps are:

  1. get a FileSystem (DOMFileSystem) through the async webkitRequestFileSystem call.
  2. get the prop root that is a FileSystemDirectoryEntry
  3. create a file through getFile (with flag create:true) that returns (async) a FileSystemFileEntry

Now from the FileEntry I can get a FileWriter using createWriter but it is obsolete (in MDN), and in any case it is a FileWriter while I would look to obtain a WritableStream instead in order to use the pipeTo from the uploaded file Handler->ReadableStream.

So, I see that in the console the class (interface) FileSystemFileHandler is defined but I cannot understand how to get an instance from the FileSystemFileEntry. If I can obtain a FileSystemFileHandler I can call the createWritable to obtain a FileSystemWritableFileStream that I can "pipe" with the ReadStream.

Anyone who can clarify this mess ?

references: https://web.dev/file-system-access/ https://wicg.github.io/file-system-access/#filesystemhandle https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry

alexroat
  • 1,687
  • 3
  • 23
  • 34

1 Answers1

2

You have the solution in your "references" links at the bottom. Specifically, this is the section to read. You can create files or directories like so:

// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
  create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });

Once you have a file handle, you can then pipe to it or write to it:

async function writeFile(fileHandle, contents) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Write the contents of the file to the stream.
  await writable.write(contents);
  // Close the file and write the contents to disk.
  await writable.close();
}

…or…

async function writeURLToFile(fileHandle, url) {
  // Create a FileSystemWritableFileStream to write to.
  const writable = await fileHandle.createWritable();
  // Make an HTTP request for the contents.
  const response = await fetch(url);
  // Stream the response into the file.
  await response.body.pipeTo(writable);
  // pipeTo() closes the destination pipe by default, no need to close it.
}
DenverCoder9
  • 2,024
  • 11
  • 32