1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 08:33:43 -05:00

feat: allow passing a ReadableStream to Deno.writeFile/Deno.writeTextFile (#17329)

Closes #13229
This commit is contained in:
Leo Kettmeir 2023-01-12 03:37:23 +01:00 committed by GitHub
parent 692f9af14a
commit a6b3910bdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 14 deletions

View file

@ -393,3 +393,19 @@ function pathExists(path: string | URL) {
return false;
}
}
Deno.test(
{ permissions: { read: true, write: true } },
async function writeFileStream() {
const stream = new ReadableStream({
pull(controller) {
controller.enqueue(new Uint8Array([1]));
controller.enqueue(new Uint8Array([2]));
controller.close();
},
});
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeFile(filename, stream);
assertEquals(Deno.readFileSync(filename), new Uint8Array([1, 2]));
},
);

View file

@ -198,3 +198,19 @@ Deno.test(
assertEquals(Deno.readTextFileSync(filename), "Hello");
},
);
Deno.test(
{ permissions: { read: true, write: true } },
async function writeTextFileStream() {
const stream = new ReadableStream({
pull(controller) {
controller.enqueue("Hello");
controller.enqueue("World");
controller.close();
},
});
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeTextFile(filename, stream);
assertEquals(Deno.readTextFileSync(filename), "HelloWorld");
},
);

View file

@ -3364,7 +3364,7 @@ declare namespace Deno {
*/
export function writeFile(
path: string | URL,
data: Uint8Array,
data: Uint8Array | ReadableStream<Uint8Array>,
options?: WriteFileOptions,
): Promise<void>;
@ -3407,7 +3407,7 @@ declare namespace Deno {
*/
export function writeTextFile(
path: string | URL,
data: string,
data: string | ReadableStream<string>,
options?: WriteFileOptions,
): Promise<void>;

View file

@ -5,6 +5,9 @@
const ops = core.ops;
const { abortSignal } = window.__bootstrap;
const { pathFromURL } = window.__bootstrap.util;
const { open } = window.__bootstrap.files;
const { ReadableStreamPrototype } = window.__bootstrap.streams;
const { ObjectPrototypeIsPrototypeOf } = window.__bootstrap.primordials;
function writeFileSync(
path,
@ -36,16 +39,29 @@
options.signal[abortSignal.add](abortHandler);
}
try {
await core.opAsync(
"op_write_file_async",
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
cancelRid,
);
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
const file = await open(path, {
mode: options.mode,
append: options.append ?? false,
create: options.create ?? true,
createNew: options.createNew ?? false,
write: true,
});
await data.pipeTo(file.writable, {
signal: options.signal,
});
} else {
await core.opAsync(
"op_write_file_async",
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
cancelRid,
);
}
} finally {
if (options.signal) {
options.signal[abortSignal.remove](abortHandler);
@ -70,8 +86,16 @@
data,
options = {},
) {
const encoder = new TextEncoder();
return writeFile(path, encoder.encode(data), options);
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
return writeFile(
path,
data.pipeThrough(new TextEncoderStream()),
options,
);
} else {
const encoder = new TextEncoder();
return writeFile(path, encoder.encode(data), options);
}
}
window.__bootstrap.writeFile = {