1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 15:49:44 -05:00

feat(node_compat): Add a read method to the FileHandle class (#19359)

ref: #19165

The FileHandle class has many missing methods compared to node.
This commit is contained in:
nasa 2023-06-08 21:37:19 +09:00 committed by GitHub
parent 0197f42e6b
commit 262571e63e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 12 deletions

View file

@ -1,15 +1,16 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import * as path from "../../../../test_util/std/path/mod.ts";
import * as fs from "node:fs/promises";
import {
assert,
assertEquals,
} from "../../../../test_util/std/testing/asserts.ts";
import { Buffer } from "node:buffer";
const moduleDir = path.dirname(path.fromFileUrl(import.meta.url));
const testData = path.resolve(moduleDir, "testdata", "hello.txt");
Deno.test("readFileSuccess", async function () {
const fs = await import("node:fs/promises");
const fileHandle = await fs.open(testData);
const data = await fileHandle.readFile();
@ -18,3 +19,42 @@ Deno.test("readFileSuccess", async function () {
await fileHandle.close();
});
Deno.test("read", async function () {
const fileHandle = await fs.open(testData);
const byteLength = "hello world".length;
const buf = new Buffer(byteLength);
await fileHandle.read(buf, 0, byteLength, 0);
assertEquals(new TextDecoder().decode(buf as Uint8Array), "hello world");
await fileHandle.close();
});
Deno.test("read specify opt", async function () {
const fileHandle = await fs.open(testData);
const byteLength = "hello world".length;
const opt = {
buffer: new Buffer(byteLength),
offset: 6,
length: 5,
};
let res = await fileHandle.read(opt);
assertEquals(res.bytesRead, byteLength);
assertEquals(new TextDecoder().decode(res.buffer as Uint8Array), "world");
const opt2 = {
buffer: new Buffer(byteLength),
length: 5,
position: 0,
};
res = await fileHandle.read(opt2);
assertEquals(res.bytesRead, byteLength);
assertEquals(new TextDecoder().decode(res.buffer as Uint8Array), "hello");
await fileHandle.close();
});

View file

@ -33,6 +33,13 @@ export type BinaryOptionsArgument =
| ({ encoding: BinaryEncodings } & FileOptions);
export type FileOptionsArgument = Encodings | FileOptions;
export type ReadOptions = {
buffer: Buffer | Uint8Array;
offset: number;
length: number;
position: number | null;
};
export interface WriteFileOptions extends FileOptions {
mode?: number;
}

View file

@ -3,6 +3,7 @@ import { Buffer } from "ext:deno_node/buffer.ts";
import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts";
import * as io from "ext:deno_io/12_io.js";
import * as fs from "ext:deno_fs/30_fs.js";
import { ReadOptions } from "ext:deno_node/_fs/_fs_common.ts";
import {
validateOffsetLengthRead,
validatePosition,
@ -12,13 +13,6 @@ import {
validateInteger,
} from "ext:deno_node/internal/validators.mjs";
type readOptions = {
buffer: Buffer | Uint8Array;
offset: number;
length: number;
position: number | null;
};
type readSyncOptions = {
offset: number;
length: number;
@ -35,7 +29,7 @@ type Callback = BinaryCallback;
export function read(fd: number, callback: Callback): void;
export function read(
fd: number,
options: readOptions,
options: ReadOptions,
callback: Callback,
): void;
export function read(
@ -48,7 +42,7 @@ export function read(
): void;
export function read(
fd: number,
optOrBufferOrCb?: Buffer | Uint8Array | readOptions | Callback,
optOrBufferOrCb?: Buffer | Uint8Array | ReadOptions | Callback,
offsetOrCallback?: number | Callback,
length?: number,
position?: number | null,
@ -86,7 +80,7 @@ export function read(
length = buffer.byteLength;
position = null;
} else {
const opt = optOrBufferOrCb as readOptions;
const opt = optOrBufferOrCb as ReadOptions;
if (
!(opt.buffer instanceof Buffer) && !(opt.buffer instanceof Uint8Array)
) {

View file

@ -1,13 +1,20 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import { EventEmitter } from "ext:deno_node/events.ts";
import { Buffer } from "ext:deno_node/buffer.ts";
import { promises } from "ext:deno_node/fs.ts";
import { promises, read } from "ext:deno_node/fs.ts";
import type { Buffer } from "ext:deno_node/buffer.ts";
import {
BinaryOptionsArgument,
FileOptionsArgument,
ReadOptions,
TextOptionsArgument,
} from "ext:deno_node/_fs/_fs_common.ts";
interface ReadResult {
bytesRead: number;
buffer: Buffer;
}
export class FileHandle extends EventEmitter {
#rid: number;
constructor(rid: number) {
@ -19,6 +26,43 @@ export class FileHandle extends EventEmitter {
return this.rid;
}
read(
buffer: Buffer,
offset?: number,
length?: number,
position?: number | null,
): Promise<ReadResult>;
read(options?: ReadOptions): Promise<ReadResult>;
read(
bufferOrOpt: Buffer | ReadOptions,
offset?: number,
length?: number,
position?: number | null,
): Promise<ReadResult> {
if (bufferOrOpt instanceof Buffer) {
return new Promise((resolve, reject) => {
read(
this.fd,
bufferOrOpt,
offset,
length,
position,
(err, bytesRead, buffer) => {
if (err) reject(err);
else resolve({ buffer: buffer, bytesRead: bytesRead });
},
);
});
} else {
return new Promise((resolve, reject) => {
read(this.fd, bufferOrOpt, (err, bytesRead, buffer) => {
if (err) reject(err);
else resolve({ buffer: buffer, bytesRead: bytesRead });
});
});
}
}
readFile(
opt?: TextOptionsArgument | BinaryOptionsArgument | FileOptionsArgument,
): Promise<string | Buffer> {