mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 04:52:26 -05:00
parent
7616429436
commit
9cb089f6db
8 changed files with 118 additions and 80 deletions
|
@ -487,7 +487,7 @@ deno_core::extension!(deno_node,
|
||||||
"_fs/_fs_watch.ts",
|
"_fs/_fs_watch.ts",
|
||||||
"_fs/_fs_write.mjs",
|
"_fs/_fs_write.mjs",
|
||||||
"_fs/_fs_writeFile.ts",
|
"_fs/_fs_writeFile.ts",
|
||||||
"_fs/_fs_writev.mjs",
|
"_fs/_fs_writev.ts",
|
||||||
"_next_tick.ts",
|
"_next_tick.ts",
|
||||||
"_process/exiting.ts",
|
"_process/exiting.ts",
|
||||||
"_process/process.ts",
|
"_process/process.ts",
|
||||||
|
|
65
ext/node/polyfills/_fs/_fs_writev.d.ts
vendored
65
ext/node/polyfills/_fs/_fs_writev.d.ts
vendored
|
@ -1,65 +0,0 @@
|
||||||
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
||||||
// Forked from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d9df51e34526f48bef4e2546a006157b391ad96c/types/node/fs.d.ts
|
|
||||||
|
|
||||||
import { ErrnoException } from "ext:deno_node/_global.d.ts";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write an array of `ArrayBufferView`s to the file specified by `fd` using`writev()`.
|
|
||||||
*
|
|
||||||
* `position` is the offset from the beginning of the file where this data
|
|
||||||
* should be written. If `typeof position !== 'number'`, the data will be written
|
|
||||||
* at the current position.
|
|
||||||
*
|
|
||||||
* The callback will be given three arguments: `err`, `bytesWritten`, and`buffers`. `bytesWritten` is how many bytes were written from `buffers`.
|
|
||||||
*
|
|
||||||
* If this method is `util.promisify()` ed, it returns a promise for an`Object` with `bytesWritten` and `buffers` properties.
|
|
||||||
*
|
|
||||||
* It is unsafe to use `fs.writev()` multiple times on the same file without
|
|
||||||
* waiting for the callback. For this scenario, use {@link createWriteStream}.
|
|
||||||
*
|
|
||||||
* On Linux, positional writes don't work when the file is opened in append mode.
|
|
||||||
* The kernel ignores the position argument and always appends the data to
|
|
||||||
* the end of the file.
|
|
||||||
* @since v12.9.0
|
|
||||||
*/
|
|
||||||
export function writev(
|
|
||||||
fd: number,
|
|
||||||
buffers: ReadonlyArray<ArrayBufferView>,
|
|
||||||
cb: (
|
|
||||||
err: ErrnoException | null,
|
|
||||||
bytesWritten: number,
|
|
||||||
buffers: ArrayBufferView[],
|
|
||||||
) => void,
|
|
||||||
): void;
|
|
||||||
export function writev(
|
|
||||||
fd: number,
|
|
||||||
buffers: ReadonlyArray<ArrayBufferView>,
|
|
||||||
position: number | null,
|
|
||||||
cb: (
|
|
||||||
err: ErrnoException | null,
|
|
||||||
bytesWritten: number,
|
|
||||||
buffers: ArrayBufferView[],
|
|
||||||
) => void,
|
|
||||||
): void;
|
|
||||||
export interface WriteVResult {
|
|
||||||
bytesWritten: number;
|
|
||||||
buffers: ArrayBufferView[];
|
|
||||||
}
|
|
||||||
export namespace writev {
|
|
||||||
function __promisify__(
|
|
||||||
fd: number,
|
|
||||||
buffers: ReadonlyArray<ArrayBufferView>,
|
|
||||||
position?: number,
|
|
||||||
): Promise<WriteVResult>;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* For detailed information, see the documentation of the asynchronous version of
|
|
||||||
* this API: {@link writev}.
|
|
||||||
* @since v12.9.0
|
|
||||||
* @return The number of bytes written.
|
|
||||||
*/
|
|
||||||
export function writevSync(
|
|
||||||
fd: number,
|
|
||||||
buffers: ReadonlyArray<ArrayBufferView>,
|
|
||||||
position?: number,
|
|
||||||
): number;
|
|
|
@ -5,15 +5,53 @@
|
||||||
// deno-lint-ignore-file prefer-primordials
|
// deno-lint-ignore-file prefer-primordials
|
||||||
|
|
||||||
import { Buffer } from "node:buffer";
|
import { Buffer } from "node:buffer";
|
||||||
|
import process from "node:process";
|
||||||
|
import { ErrnoException } from "ext:deno_node/_global.d.ts";
|
||||||
import { validateBufferArray } from "ext:deno_node/internal/fs/utils.mjs";
|
import { validateBufferArray } from "ext:deno_node/internal/fs/utils.mjs";
|
||||||
import { getValidatedFd } from "ext:deno_node/internal/fs/utils.mjs";
|
import { getValidatedFd } from "ext:deno_node/internal/fs/utils.mjs";
|
||||||
|
import { WriteVResult } from "ext:deno_node/internal/fs/handle.ts";
|
||||||
import { maybeCallback } from "ext:deno_node/_fs/_fs_common.ts";
|
import { maybeCallback } from "ext:deno_node/_fs/_fs_common.ts";
|
||||||
import * as io from "ext:deno_io/12_io.js";
|
import * as io from "ext:deno_io/12_io.js";
|
||||||
import { op_fs_seek_async, op_fs_seek_sync } from "ext:core/ops";
|
import { op_fs_seek_async, op_fs_seek_sync } from "ext:core/ops";
|
||||||
|
|
||||||
export function writev(fd, buffers, position, callback) {
|
export interface WriteVResult {
|
||||||
|
bytesWritten: number;
|
||||||
|
buffers: ReadonlyArray<ArrayBufferView>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type writeVCallback = (
|
||||||
|
err: ErrnoException | null,
|
||||||
|
bytesWritten: number,
|
||||||
|
buffers: ReadonlyArray<ArrayBufferView>,
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an array of `ArrayBufferView`s to the file specified by `fd` using`writev()`.
|
||||||
|
*
|
||||||
|
* `position` is the offset from the beginning of the file where this data
|
||||||
|
* should be written. If `typeof position !== 'number'`, the data will be written
|
||||||
|
* at the current position.
|
||||||
|
*
|
||||||
|
* The callback will be given three arguments: `err`, `bytesWritten`, and`buffers`. `bytesWritten` is how many bytes were written from `buffers`.
|
||||||
|
*
|
||||||
|
* If this method is `util.promisify()` ed, it returns a promise for an`Object` with `bytesWritten` and `buffers` properties.
|
||||||
|
*
|
||||||
|
* It is unsafe to use `fs.writev()` multiple times on the same file without
|
||||||
|
* waiting for the callback. For this scenario, use {@link createWriteStream}.
|
||||||
|
*
|
||||||
|
* On Linux, positional writes don't work when the file is opened in append mode.
|
||||||
|
* The kernel ignores the position argument and always appends the data to
|
||||||
|
* the end of the file.
|
||||||
|
* @since v12.9.0
|
||||||
|
*/
|
||||||
|
export function writev(
|
||||||
|
fd: number,
|
||||||
|
buffers: ReadonlyArray<ArrayBufferView>,
|
||||||
|
position?: number | null,
|
||||||
|
callback?: writeVCallback,
|
||||||
|
): void {
|
||||||
const innerWritev = async (fd, buffers, position) => {
|
const innerWritev = async (fd, buffers, position) => {
|
||||||
const chunks = [];
|
const chunks: Buffer[] = [];
|
||||||
const offset = 0;
|
const offset = 0;
|
||||||
for (let i = 0; i < buffers.length; i++) {
|
for (let i = 0; i < buffers.length; i++) {
|
||||||
if (Buffer.isBuffer(buffers[i])) {
|
if (Buffer.isBuffer(buffers[i])) {
|
||||||
|
@ -45,16 +83,24 @@ export function writev(fd, buffers, position, callback) {
|
||||||
if (typeof position !== "number") position = null;
|
if (typeof position !== "number") position = null;
|
||||||
|
|
||||||
innerWritev(fd, buffers, position).then(
|
innerWritev(fd, buffers, position).then(
|
||||||
(nwritten) => {
|
(nwritten) => callback(null, nwritten, buffers),
|
||||||
callback(null, nwritten, buffers);
|
|
||||||
},
|
|
||||||
(err) => callback(err),
|
(err) => callback(err),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writevSync(fd, buffers, position) {
|
/**
|
||||||
|
* For detailed information, see the documentation of the asynchronous version of
|
||||||
|
* this API: {@link writev}.
|
||||||
|
* @since v12.9.0
|
||||||
|
* @return The number of bytes written.
|
||||||
|
*/
|
||||||
|
export function writevSync(
|
||||||
|
fd: number,
|
||||||
|
buffers: ArrayBufferView[],
|
||||||
|
position?: number | null,
|
||||||
|
): number {
|
||||||
const innerWritev = (fd, buffers, position) => {
|
const innerWritev = (fd, buffers, position) => {
|
||||||
const chunks = [];
|
const chunks: Buffer[] = [];
|
||||||
const offset = 0;
|
const offset = 0;
|
||||||
for (let i = 0; i < buffers.length; i++) {
|
for (let i = 0; i < buffers.length; i++) {
|
||||||
if (Buffer.isBuffer(buffers[i])) {
|
if (Buffer.isBuffer(buffers[i])) {
|
||||||
|
@ -85,3 +131,16 @@ export function writevSync(fd, buffers, position) {
|
||||||
|
|
||||||
return innerWritev(fd, buffers, position);
|
return innerWritev(fd, buffers, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function writevPromise(
|
||||||
|
fd: number,
|
||||||
|
buffers: ArrayBufferView[],
|
||||||
|
position?: number,
|
||||||
|
): Promise<WriteVResult> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
writev(fd, buffers, position, (err, bytesWritten, buffers) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve({ bytesWritten, buffers });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -119,7 +119,7 @@ import {
|
||||||
// @deno-types="./_fs/_fs_write.d.ts"
|
// @deno-types="./_fs/_fs_write.d.ts"
|
||||||
import { write, writeSync } from "ext:deno_node/_fs/_fs_write.mjs";
|
import { write, writeSync } from "ext:deno_node/_fs/_fs_write.mjs";
|
||||||
// @deno-types="./_fs/_fs_writev.d.ts"
|
// @deno-types="./_fs/_fs_writev.d.ts"
|
||||||
import { writev, writevSync } from "ext:deno_node/_fs/_fs_writev.mjs";
|
import { writev, writevSync } from "ext:deno_node/_fs/_fs_writev.ts";
|
||||||
import { readv, readvSync } from "ext:deno_node/_fs/_fs_readv.ts";
|
import { readv, readvSync } from "ext:deno_node/_fs/_fs_readv.ts";
|
||||||
import {
|
import {
|
||||||
writeFile,
|
writeFile,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { EventEmitter } from "node:events";
|
import { EventEmitter } from "node:events";
|
||||||
import { Buffer } from "node:buffer";
|
import { Buffer } from "node:buffer";
|
||||||
import { Mode, promises, read, write } from "node:fs";
|
import { Mode, promises, read, write } from "node:fs";
|
||||||
export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
|
import { core } from "ext:core/mod.js";
|
||||||
import {
|
import {
|
||||||
BinaryOptionsArgument,
|
BinaryOptionsArgument,
|
||||||
FileOptionsArgument,
|
FileOptionsArgument,
|
||||||
|
@ -14,7 +14,8 @@ import {
|
||||||
TextOptionsArgument,
|
TextOptionsArgument,
|
||||||
} from "ext:deno_node/_fs/_fs_common.ts";
|
} from "ext:deno_node/_fs/_fs_common.ts";
|
||||||
import { ftruncatePromise } from "ext:deno_node/_fs/_fs_ftruncate.ts";
|
import { ftruncatePromise } from "ext:deno_node/_fs/_fs_ftruncate.ts";
|
||||||
import { core } from "ext:core/mod.js";
|
export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts";
|
||||||
|
import { writevPromise, WriteVResult } from "ext:deno_node/_fs/_fs_writev.ts";
|
||||||
|
|
||||||
interface WriteResult {
|
interface WriteResult {
|
||||||
bytesWritten: number;
|
bytesWritten: number;
|
||||||
|
@ -64,7 +65,7 @@ export class FileHandle extends EventEmitter {
|
||||||
position,
|
position,
|
||||||
(err, bytesRead, buffer) => {
|
(err, bytesRead, buffer) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else resolve({ buffer: buffer, bytesRead: bytesRead });
|
else resolve({ buffer, bytesRead });
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -72,7 +73,7 @@ export class FileHandle extends EventEmitter {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
read(this.fd, bufferOrOpt, (err, bytesRead, buffer) => {
|
read(this.fd, bufferOrOpt, (err, bytesRead, buffer) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else resolve({ buffer: buffer, bytesRead: bytesRead });
|
else resolve({ buffer, bytesRead });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -137,6 +138,10 @@ export class FileHandle extends EventEmitter {
|
||||||
return fsCall(promises.writeFile, this, data, options);
|
return fsCall(promises.writeFile, this, data, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writev(buffers: ArrayBufferView[], position?: number): Promise<WriteVResult> {
|
||||||
|
return fsCall(writevPromise, this, buffers, position);
|
||||||
|
}
|
||||||
|
|
||||||
close(): Promise<void> {
|
close(): Promise<void> {
|
||||||
// Note that Deno.close is not async
|
// Note that Deno.close is not async
|
||||||
return Promise.resolve(core.close(this.fd));
|
return Promise.resolve(core.close(this.fd));
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { errorOrDestroy } from "ext:deno_node/internal/streams/destroy.mjs";
|
||||||
import { open as fsOpen } from "ext:deno_node/_fs/_fs_open.ts";
|
import { open as fsOpen } from "ext:deno_node/_fs/_fs_open.ts";
|
||||||
import { read as fsRead } from "ext:deno_node/_fs/_fs_read.ts";
|
import { read as fsRead } from "ext:deno_node/_fs/_fs_read.ts";
|
||||||
import { write as fsWrite } from "ext:deno_node/_fs/_fs_write.mjs";
|
import { write as fsWrite } from "ext:deno_node/_fs/_fs_write.mjs";
|
||||||
import { writev as fsWritev } from "ext:deno_node/_fs/_fs_writev.mjs";
|
import { writev as fsWritev } from "ext:deno_node/_fs/_fs_writev.ts";
|
||||||
import { close as fsClose } from "ext:deno_node/_fs/_fs_close.ts";
|
import { close as fsClose } from "ext:deno_node/_fs/_fs_close.ts";
|
||||||
import { Buffer } from "node:buffer";
|
import { Buffer } from "node:buffer";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -118,6 +118,45 @@ Deno.test("[node/fs filehandle.writeFile] Write to file", async function () {
|
||||||
assertEquals(decoder.decode(data), "hello world");
|
assertEquals(decoder.decode(data), "hello world");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs filehandle.writev] Write array of buffers to file",
|
||||||
|
async function () {
|
||||||
|
const tempFile: string = await Deno.makeTempFile();
|
||||||
|
const fileHandle = await fs.open(tempFile, "w");
|
||||||
|
|
||||||
|
const buffer1 = Buffer.from("hello ");
|
||||||
|
const buffer2 = Buffer.from("world");
|
||||||
|
const res = await fileHandle.writev([buffer1, buffer2]);
|
||||||
|
|
||||||
|
const data = Deno.readFileSync(tempFile);
|
||||||
|
await Deno.remove(tempFile);
|
||||||
|
await fileHandle.close();
|
||||||
|
|
||||||
|
assertEquals(res.bytesWritten, 11);
|
||||||
|
assertEquals(decoder.decode(data), "hello world");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
"[node/fs filehandle.writev] Write array of buffers to file with position",
|
||||||
|
async function () {
|
||||||
|
const tempFile: string = await Deno.makeTempFile();
|
||||||
|
const fileHandle = await fs.open(tempFile, "w");
|
||||||
|
|
||||||
|
const buffer1 = Buffer.from("hello ");
|
||||||
|
const buffer2 = Buffer.from("world");
|
||||||
|
await fileHandle.writev([buffer1, buffer2], 0);
|
||||||
|
const buffer3 = Buffer.from("lorem ipsum");
|
||||||
|
await fileHandle.writev([buffer3], 6);
|
||||||
|
|
||||||
|
const data = Deno.readFileSync(tempFile);
|
||||||
|
await Deno.remove(tempFile);
|
||||||
|
await fileHandle.close();
|
||||||
|
|
||||||
|
assertEquals(decoder.decode(data), "hello lorem ipsum");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Deno.test(
|
Deno.test(
|
||||||
"[node/fs filehandle.truncate] Truncate file with length",
|
"[node/fs filehandle.truncate] Truncate file with length",
|
||||||
async function () {
|
async function () {
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
"ext:deno_node/_fs/_fs_stat.ts": "../ext/node/polyfills/_fs/_fs_stat.ts",
|
"ext:deno_node/_fs/_fs_stat.ts": "../ext/node/polyfills/_fs/_fs_stat.ts",
|
||||||
"ext:deno_node/_fs/_fs_watch.ts": "../ext/node/polyfills/_fs/_fs_watch.ts",
|
"ext:deno_node/_fs/_fs_watch.ts": "../ext/node/polyfills/_fs/_fs_watch.ts",
|
||||||
"ext:deno_node/_fs/_fs_write.mjs": "../ext/node/polyfills/_fs/_fs_write.mjs",
|
"ext:deno_node/_fs/_fs_write.mjs": "../ext/node/polyfills/_fs/_fs_write.mjs",
|
||||||
"ext:deno_node/_fs/_fs_writev.mjs": "../ext/node/polyfills/_fs/_fs_writev.mjs",
|
"ext:deno_node/_fs/_fs_writev.ts": "../ext/node/polyfills/_fs/_fs_writev.ts",
|
||||||
"ext:deno_node/_global.d.ts": "../ext/node/polyfills/_global.d.ts",
|
"ext:deno_node/_global.d.ts": "../ext/node/polyfills/_global.d.ts",
|
||||||
"node:_http_agent": "../ext/node/polyfills/_http_agent.mjs",
|
"node:_http_agent": "../ext/node/polyfills/_http_agent.mjs",
|
||||||
"node:_http_common": "../ext/node/polyfills/_http_common.ts",
|
"node:_http_common": "../ext/node/polyfills/_http_common.ts",
|
||||||
|
|
Loading…
Add table
Reference in a new issue