mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +00:00
feat: allow passing a ReadableStream to Deno.writeFile/Deno.writeTextFile (#17329)
Closes #13229
This commit is contained in:
parent
692f9af14a
commit
a6b3910bdf
4 changed files with 70 additions and 14 deletions
|
@ -393,3 +393,19 @@ function pathExists(path: string | URL) {
|
||||||
return false;
|
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]));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -198,3 +198,19 @@ Deno.test(
|
||||||
assertEquals(Deno.readTextFileSync(filename), "Hello");
|
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");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
4
cli/tsc/dts/lib.deno.ns.d.ts
vendored
4
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -3364,7 +3364,7 @@ declare namespace Deno {
|
||||||
*/
|
*/
|
||||||
export function writeFile(
|
export function writeFile(
|
||||||
path: string | URL,
|
path: string | URL,
|
||||||
data: Uint8Array,
|
data: Uint8Array | ReadableStream<Uint8Array>,
|
||||||
options?: WriteFileOptions,
|
options?: WriteFileOptions,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
|
@ -3407,7 +3407,7 @@ declare namespace Deno {
|
||||||
*/
|
*/
|
||||||
export function writeTextFile(
|
export function writeTextFile(
|
||||||
path: string | URL,
|
path: string | URL,
|
||||||
data: string,
|
data: string | ReadableStream<string>,
|
||||||
options?: WriteFileOptions,
|
options?: WriteFileOptions,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
const ops = core.ops;
|
const ops = core.ops;
|
||||||
const { abortSignal } = window.__bootstrap;
|
const { abortSignal } = window.__bootstrap;
|
||||||
const { pathFromURL } = window.__bootstrap.util;
|
const { pathFromURL } = window.__bootstrap.util;
|
||||||
|
const { open } = window.__bootstrap.files;
|
||||||
|
const { ReadableStreamPrototype } = window.__bootstrap.streams;
|
||||||
|
const { ObjectPrototypeIsPrototypeOf } = window.__bootstrap.primordials;
|
||||||
|
|
||||||
function writeFileSync(
|
function writeFileSync(
|
||||||
path,
|
path,
|
||||||
|
@ -36,16 +39,29 @@
|
||||||
options.signal[abortSignal.add](abortHandler);
|
options.signal[abortSignal.add](abortHandler);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await core.opAsync(
|
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
|
||||||
"op_write_file_async",
|
const file = await open(path, {
|
||||||
pathFromURL(path),
|
mode: options.mode,
|
||||||
options.mode,
|
append: options.append ?? false,
|
||||||
options.append ?? false,
|
create: options.create ?? true,
|
||||||
options.create ?? true,
|
createNew: options.createNew ?? false,
|
||||||
options.createNew ?? false,
|
write: true,
|
||||||
data,
|
});
|
||||||
cancelRid,
|
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 {
|
} finally {
|
||||||
if (options.signal) {
|
if (options.signal) {
|
||||||
options.signal[abortSignal.remove](abortHandler);
|
options.signal[abortSignal.remove](abortHandler);
|
||||||
|
@ -70,8 +86,16 @@
|
||||||
data,
|
data,
|
||||||
options = {},
|
options = {},
|
||||||
) {
|
) {
|
||||||
const encoder = new TextEncoder();
|
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
|
||||||
return writeFile(path, encoder.encode(data), options);
|
return writeFile(
|
||||||
|
path,
|
||||||
|
data.pipeThrough(new TextEncoderStream()),
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
return writeFile(path, encoder.encode(data), options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.__bootstrap.writeFile = {
|
window.__bootstrap.writeFile = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue