How can I write files in Deno?
You can use ensureDir
to safely write files to possibly non-existent directories:
import { ensureDir } from "https://deno.land/[email protected]/fs/ensure_dir.ts";
ensureDir("./my/dir")
.then(() => Deno.writeTextFile("./my/dir/file.txt", "some content"));
The containing file directory can be derived via dirname
:
import { dirname } from "https://deno.land/[email protected]/path/mod.ts";
const file = "./my/dir/file.txt";
ensureDir(dirname(file)).then(() => Deno.writeTextFile(file, "some content"));
An alternative is ensureFile
to assert file existence:
import { ensureFile } from "https:deno.land/std/fs/ensure_file.ts";
ensureFile(file).then(/* your file write method */)
This variant is slightly less verbose, with the cost of one additional write operation (file creation, if not exists).
There are multiple ways to write a file in Deno, all of them require --allow-write
flag and will throw
if an error occurred, so you should handle errors correctly.
Using Deno.writeFile
This API takes a Uint8Array
, not a string, the reason why you get that error. It also takes an optional WriteFileOptions
object
const res = await fetch('http://example.com/image.png');
const imageBytes = new Uint8Array(await res.arrayBuffer());
await Deno.writeFile('./image.png', imageBytes);
There's also the synchronous API (it blocks the event loop as it does in Node.js).
Deno.writeFileSync('./image.png', imageBytes);
Writing strings
The easiest way is to use Deno.writeTextFile
await Deno.writeTextFile('./file.txt', 'some content');
You can also use Deno.writeFile
with TextEncoder
.
const encoder = new TextEncoder(); // to convert a string to Uint8Array
await Deno.writeFile('./file.txt', encoder.encode('some content'));
Streaming
Deno.open
returns a FsFile which contains a WritableStream
in .writable
property, so you can just pipe a stream directly to it.
const res = await fetch('https://example.com/csv');
const file = await Deno.open('./some.csv', { create: true, write: true })
await res.body.pipeTo(file.writable);
file.close();
If you have a Reader
instead of a ReadableStream
you can convert it to a ReadableStream
using readableStreamFromReader
from std/streams
:
import { readableStreamFromReader } from "https://deno.land/[email protected]/streams/mod.ts?s=readableStreamFromReader";
// ...
const readable = readableStreamFromReader(someReader);
await readable.pipeTo(file.writeable)
Low-level APIs
Using Deno.open
and Deno.writeAll
(or Deno.writeAllSync
)
const file = await Deno.open('./image.png', { write: true, create: true });
/* ... */
await Deno.writeAll(file, imageBytes);
file.close(); // You need to close it!
See OpenOptions
here. If you want to append you would do:
{ append: true }
And you can also use even lower-level APIs such as Deno.write
or Writer.write