diff options
author | nasa <htilcs1115@gmail.com> | 2023-06-08 23:47:12 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-08 08:47:12 -0600 |
commit | caad79ef7807bbd8f53b0338e23d281c5c45519b (patch) | |
tree | c26d874f1bd5f8ac52c129329ca26a50bf13a2fd | |
parent | 262571e63e3086e0a4ea6125b3836c357a21af86 (diff) |
feat(node_compat): Add a write method to the FileHandle class (#19385)
## WHY
ref: https://github.com/denoland/deno/issues/19165
The FileHandle class has many missing methods compared to node.
## WHAT
Add write method
-rw-r--r-- | cli/tests/unit_node/_fs/_fs_handle_test.ts | 39 | ||||
-rw-r--r-- | ext/node/polyfills/internal/fs/handle.ts | 63 |
2 files changed, 96 insertions, 6 deletions
diff --git a/cli/tests/unit_node/_fs/_fs_handle_test.ts b/cli/tests/unit_node/_fs/_fs_handle_test.ts index 2865fc785..8cfbf6490 100644 --- a/cli/tests/unit_node/_fs/_fs_handle_test.ts +++ b/cli/tests/unit_node/_fs/_fs_handle_test.ts @@ -1,21 +1,22 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. import * as path from "../../../../test_util/std/path/mod.ts"; +import { Buffer } from "node:buffer"; 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"); +const decoder = new TextDecoder(); Deno.test("readFileSuccess", async function () { const fileHandle = await fs.open(testData); const data = await fileHandle.readFile(); assert(data instanceof Uint8Array); - assertEquals(new TextDecoder().decode(data as Uint8Array), "hello world"); + assertEquals(decoder.decode(data as Uint8Array), "hello world"); await fileHandle.close(); }); @@ -27,7 +28,7 @@ Deno.test("read", async function () { const buf = new Buffer(byteLength); await fileHandle.read(buf, 0, byteLength, 0); - assertEquals(new TextDecoder().decode(buf as Uint8Array), "hello world"); + assertEquals(decoder.decode(buf as Uint8Array), "hello world"); await fileHandle.close(); }); @@ -54,7 +55,37 @@ Deno.test("read specify opt", async function () { res = await fileHandle.read(opt2); assertEquals(res.bytesRead, byteLength); - assertEquals(new TextDecoder().decode(res.buffer as Uint8Array), "hello"); + assertEquals(decoder.decode(res.buffer as Uint8Array), "hello"); + + await fileHandle.close(); +}); + +Deno.test("[node/fs filehandle.write] Write from Buffer", async function () { + const tempFile: string = await Deno.makeTempFile(); + const fileHandle = await fs.open(tempFile, "a+"); + + const buffer = Buffer.from("hello world"); + const res = await fileHandle.write(buffer, 0, 5, 0); + const data = Deno.readFileSync(tempFile); + await Deno.remove(tempFile); await fileHandle.close(); + + assertEquals(res.bytesWritten, 5); + assertEquals(decoder.decode(data), "hello"); +}); + +Deno.test("[node/fs filehandle.write] Write from string", async function () { + const tempFile: string = await Deno.makeTempFile(); + const fileHandle = await fs.open(tempFile, "a+"); + + const str = "hello world"; + const res = await fileHandle.write(str); + + const data = Deno.readFileSync(tempFile); + await Deno.remove(tempFile); + await fileHandle.close(); + + assertEquals(res.bytesWritten, 11); + assertEquals(decoder.decode(data), "hello world"); }); diff --git a/ext/node/polyfills/internal/fs/handle.ts b/ext/node/polyfills/internal/fs/handle.ts index 199457787..fbe535840 100644 --- a/ext/node/polyfills/internal/fs/handle.ts +++ b/ext/node/polyfills/internal/fs/handle.ts @@ -1,8 +1,7 @@ // 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, read } from "ext:deno_node/fs.ts"; -import type { Buffer } from "ext:deno_node/buffer.ts"; +import { promises, read, write } from "ext:deno_node/fs.ts"; import { BinaryOptionsArgument, FileOptionsArgument, @@ -10,6 +9,11 @@ import { TextOptionsArgument, } from "ext:deno_node/_fs/_fs_common.ts"; +interface WriteResult { + bytesWritten: number; + buffer: Buffer | string; +} + interface ReadResult { bytesRead: number; buffer: Buffer; @@ -69,6 +73,61 @@ export class FileHandle extends EventEmitter { return promises.readFile(this, opt); } + write( + buffer: Buffer, + offset: number, + length: number, + position: number, + ): Promise<WriteResult>; + write( + str: string, + position: number, + encoding: string, + ): Promise<WriteResult>; + write( + bufferOrStr: Buffer | string, + offsetOrPotition: number, + lengthOrEncoding: number | string, + position?: number, + ): Promise<WriteResult> { + if (bufferOrStr instanceof Buffer) { + const buffer = bufferOrStr; + const offset = offsetOrPotition; + const length = lengthOrEncoding; + + return new Promise((resolve, reject) => { + write( + this.fd, + buffer, + offset, + length, + position, + (err, bytesWritten, buffer) => { + if (err) reject(err); + else resolve({ buffer, bytesWritten }); + }, + ); + }); + } else { + const str = bufferOrStr; + const position = offsetOrPotition; + const encoding = lengthOrEncoding; + + return new Promise((resolve, reject) => { + write( + this.fd, + str, + position, + encoding, + (err, bytesWritten, buffer) => { + if (err) reject(err); + else resolve({ buffer, bytesWritten }); + }, + ); + }); + } + } + close(): Promise<void> { // Note that Deno.close is not async return Promise.resolve(Deno.close(this.fd)); |