<p dir="auto">Consider implementing an asynchronous file system API.</p>
<p dir="auto">On the Web, the Native File System API implements an API surface that provides file and directory access.</p>
<ul dir="auto">
<li>Spec: <a href="https://wicg.github.io/native-file-system/" rel="nofollow">https://wicg.github.io/native-file-system/</a></li>
<li>Explainer: <a href="https://github.com/WICG/native-file-system/blob/master/EXPLAINER.md">https://github.com/WICG/native-file-system/blob/master/EXPLAINER.md</a></li>
</ul>
<p dir="auto">A similar API shape for asynchronous file access would be great for interop between server/command-line and web code.</p>
<p dir="auto">The API has a shape that allows streaming to a file, creating new files, opening an existing file, cloberring or not, iterating through directories, etc.</p>
<p dir="auto">Adapted from the explainer, here's an example:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const dir_ref = ... // Some mechanism to obtain a directory handle TBD.

for await (const [name, entry] of dir_ref) {
    // Iterate through a directory.
    // entry is a FileSystemFileHandle or a FileSystemDirectoryHandle.
    // name is equal to entry.name
}

const new_file = await dir_ref.getFile('foo.txt', {create: true}); // Create a file.

// Write to a file using an API resembling something like pwrite.
const new_file_writer = await new_file.createWritable();
await new_file_writer.write(await file_ref.getFile());
await new_file_writer.close();

// Or using streams.
const file_ref = await dir_ref.getFile('foo.js'); // Get a file from a directory.
const copy2 = await dir_ref.getFile('foo2.txt', {create: true});
(await file_ref.getFile()).stream().pipeTo(await copy2.createWritable());
...

"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">dir_ref</span> <span class="pl-c1">=</span> ... <span class="pl-c">// Some mechanism to obtain a directory handle TBD.</span>

<span class="pl-k">for</span> <span class="pl-k">await</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-kos">[</span><span class="pl-s1">name</span><span class="pl-kos">,</span> <span class="pl-s1">entry</span><span class="pl-kos">]</span> <span class="pl-k">of</span> <span class="pl-s1">dir_ref</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c">// Iterate through a directory.</span>
    <span class="pl-c">// entry is a FileSystemFileHandle or a FileSystemDirectoryHandle.</span>
    <span class="pl-c">// name is equal to entry.name</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-s1">new_file</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">dir_ref</span><span class="pl-kos">.</span><span class="pl-en">getFile</span><span class="pl-kos">(</span><span class="pl-s">'foo.txt'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">create</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Create a file.</span>

<span class="pl-c">// Write to a file using an API resembling something like pwrite.</span>
<span class="pl-k">const</span> <span class="pl-s1">new_file_writer</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">new_file</span><span class="pl-kos">.</span><span class="pl-en">createWritable</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">await</span> <span class="pl-s1">new_file_writer</span><span class="pl-kos">.</span><span class="pl-en">write</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-s1">file_ref</span><span class="pl-kos">.</span><span class="pl-en">getFile</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-k">await</span> <span class="pl-s1">new_file_writer</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Or using streams.</span>
<span class="pl-k">const</span> <span class="pl-s1">file_ref</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">dir_ref</span><span class="pl-kos">.</span><span class="pl-en">getFile</span><span class="pl-kos">(</span><span class="pl-s">'foo.js'</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-c">// Get a file from a directory.</span>
<span class="pl-k">const</span> <span class="pl-s1">copy2</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">dir_ref</span><span class="pl-kos">.</span><span class="pl-en">getFile</span><span class="pl-kos">(</span><span class="pl-s">'foo2.txt'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">create</span>: <span class="pl-c1">true</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-s1">file_ref</span><span class="pl-kos">.</span><span class="pl-en">getFile</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">stream</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">pipeTo</span><span class="pl-kos">(</span><span class="pl-k">await</span> <span class="pl-s1">copy2</span><span class="pl-kos">.</span><span class="pl-en">createWritable</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
...
</pre></div>
<p dir="auto">The proposal for <a href="https://github.com/WICG/native-file-system">native file system</a> is out.<br>
Where does deno stand?</p>