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_write.mjs",
|
||||
"_fs/_fs_writeFile.ts",
|
||||
"_fs/_fs_writev.mjs",
|
||||
"_fs/_fs_writev.ts",
|
||||
"_next_tick.ts",
|
||||
"_process/exiting.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
|
||||
|
||||
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 { 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 * as io from "ext:deno_io/12_io.js";
|
||||
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 chunks = [];
|
||||
const chunks: Buffer[] = [];
|
||||
const offset = 0;
|
||||
for (let i = 0; i < buffers.length; i++) {
|
||||
if (Buffer.isBuffer(buffers[i])) {
|
||||
|
@ -45,16 +83,24 @@ export function writev(fd, buffers, position, callback) {
|
|||
if (typeof position !== "number") position = null;
|
||||
|
||||
innerWritev(fd, buffers, position).then(
|
||||
(nwritten) => {
|
||||
callback(null, nwritten, buffers);
|
||||
},
|
||||
(nwritten) => callback(null, nwritten, buffers),
|
||||
(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 chunks = [];
|
||||
const chunks: Buffer[] = [];
|
||||
const offset = 0;
|
||||
for (let i = 0; i < buffers.length; i++) {
|
||||
if (Buffer.isBuffer(buffers[i])) {
|
||||
|
@ -85,3 +131,16 @@ export function writevSync(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"
|
||||
import { write, writeSync } from "ext:deno_node/_fs/_fs_write.mjs";
|
||||
// @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 {
|
||||
writeFile,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { EventEmitter } from "node:events";
|
||||
import { Buffer } from "node:buffer";
|
||||
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 {
|
||||
BinaryOptionsArgument,
|
||||
FileOptionsArgument,
|
||||
|
@ -14,7 +14,8 @@ import {
|
|||
TextOptionsArgument,
|
||||
} from "ext:deno_node/_fs/_fs_common.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 {
|
||||
bytesWritten: number;
|
||||
|
@ -64,7 +65,7 @@ export class FileHandle extends EventEmitter {
|
|||
position,
|
||||
(err, bytesRead, buffer) => {
|
||||
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) => {
|
||||
read(this.fd, bufferOrOpt, (err, bytesRead, buffer) => {
|
||||
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);
|
||||
}
|
||||
|
||||
writev(buffers: ArrayBufferView[], position?: number): Promise<WriteVResult> {
|
||||
return fsCall(writevPromise, this, buffers, position);
|
||||
}
|
||||
|
||||
close(): Promise<void> {
|
||||
// Note that Deno.close is not async
|
||||
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 { read as fsRead } from "ext:deno_node/_fs/_fs_read.ts";
|
||||
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 { Buffer } from "node:buffer";
|
||||
import {
|
||||
|
|
|
@ -118,6 +118,45 @@ Deno.test("[node/fs filehandle.writeFile] Write to file", async function () {
|
|||
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(
|
||||
"[node/fs filehandle.truncate] Truncate file with length",
|
||||
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_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_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",
|
||||
"node:_http_agent": "../ext/node/polyfills/_http_agent.mjs",
|
||||
"node:_http_common": "../ext/node/polyfills/_http_common.ts",
|
||||
|
|
Loading…
Add table
Reference in a new issue