fs-stream-sync 2.0.21 → 2.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/index.d.ts +55 -1
- package/index.js +15 -1
- package/index.js.map +1 -0
- package/lib/errors.d.ts +46 -0
- package/lib/errors.js +43 -0
- package/lib/errors.js.map +1 -0
- package/lib/interface.d.ts +84 -0
- package/lib/interface.js +7 -0
- package/lib/interface.js.map +1 -0
- package/lib/internal.d.ts +90 -0
- package/lib/internal.js +109 -0
- package/lib/internal.js.map +1 -0
- package/lib/util.js.map +1 -0
- package/package.json +2 -2
- package/read-sync.d.ts +73 -0
- package/read-sync.js +104 -8
- package/read-sync.js.map +1 -0
- package/read.d.ts +49 -0
- package/read.js +41 -0
- package/read.js.map +1 -0
- package/write-sync.d.ts +101 -1
- package/write-sync.js +93 -5
- package/write-sync.js.map +1 -0
- package/write.d.ts +83 -2
- package/write.js +52 -0
- package/write.js.map +1 -0
package/lib/internal.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 檔案系統流內部工具函數
|
|
4
|
+
* File System Stream Internal Utility Functions
|
|
5
|
+
*
|
|
6
|
+
* 提供開啟、關閉、銷毀流等核心功能
|
|
7
|
+
* Provides core functions for opening, closing, and destroying streams
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.SYM_FS_STREAM_DATA = void 0;
|
|
4
11
|
exports.open = open;
|
|
@@ -9,40 +16,100 @@ exports.closeFsStreamSync = closeFsStreamSync;
|
|
|
9
16
|
exports._destroy = _destroy;
|
|
10
17
|
exports.getFsStreamData = getFsStreamData;
|
|
11
18
|
const fs_1 = require("fs");
|
|
19
|
+
/**
|
|
20
|
+
* 流資料符號鍵 / Stream data symbol key
|
|
21
|
+
* 用於存取流的內部資料 / Used to access stream's internal data
|
|
22
|
+
*/
|
|
12
23
|
exports.SYM_FS_STREAM_DATA = Symbol('FsStreamData');
|
|
24
|
+
/**
|
|
25
|
+
* 開啟檔案流
|
|
26
|
+
* Open file stream
|
|
27
|
+
*
|
|
28
|
+
* 使用同步方式開啟檔案並發送相關事件
|
|
29
|
+
* Opens file synchronously and emits relevant events
|
|
30
|
+
*
|
|
31
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
32
|
+
* @param {any[]} [argv] - 額外參數 / Additional arguments
|
|
33
|
+
*/
|
|
13
34
|
function open(thisArgv, argv) {
|
|
14
35
|
if (typeof thisArgv.fd !== 'number') {
|
|
15
36
|
let fd;
|
|
16
37
|
try {
|
|
38
|
+
// 使用同步方式開啟檔案 / Open file synchronously
|
|
17
39
|
// @ts-ignore
|
|
18
40
|
fd = (0, fs_1.openSync)(thisArgv.path, thisArgv.flags, thisArgv.mode);
|
|
19
41
|
}
|
|
20
42
|
catch (er) {
|
|
43
|
+
// 發生錯誤時發射錯誤事件 / Emit error on failure
|
|
21
44
|
_error_emit(thisArgv, er);
|
|
22
45
|
return;
|
|
23
46
|
}
|
|
24
47
|
thisArgv.fd = fd;
|
|
25
48
|
}
|
|
49
|
+
// 發送開啟和就緒事件 / Emit open and ready events
|
|
26
50
|
thisArgv.emit('open', thisArgv.fd);
|
|
27
51
|
thisArgv.emit('ready');
|
|
28
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* 發射錯誤事件
|
|
55
|
+
* Emit error event
|
|
56
|
+
*
|
|
57
|
+
* 關閉流並發射錯誤事件
|
|
58
|
+
* Closes stream and emits error event
|
|
59
|
+
*
|
|
60
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
61
|
+
* @param {T} e - 錯誤物件 / Error object
|
|
62
|
+
*/
|
|
29
63
|
function _error_emit(thisArgv, e) {
|
|
30
64
|
__close(thisArgv);
|
|
31
65
|
thisArgv.emit('error', e);
|
|
32
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* 內部關閉函數
|
|
69
|
+
* Internal close function
|
|
70
|
+
*
|
|
71
|
+
* 根據 autoClose 設定決定是否銷毀流
|
|
72
|
+
* Destroys stream based on autoClose setting
|
|
73
|
+
*
|
|
74
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
75
|
+
*/
|
|
33
76
|
function __close(thisArgv) {
|
|
77
|
+
// 如果啟用自動關閉,則銷毀流 / Destroy stream if autoClose is enabled
|
|
34
78
|
// @ts-ignore
|
|
35
79
|
if (thisArgv.autoClose) {
|
|
36
80
|
thisArgv.destroy();
|
|
37
81
|
}
|
|
38
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* 錯誤回調處理
|
|
85
|
+
* Error callback handler
|
|
86
|
+
*
|
|
87
|
+
* 關閉流並執行錯誤回調
|
|
88
|
+
* Closes stream and executes error callback
|
|
89
|
+
*
|
|
90
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
91
|
+
* @param {T} e - 錯誤物件 / Error object
|
|
92
|
+
* @param {Function} callback - 回調函數 / Callback function
|
|
93
|
+
*/
|
|
39
94
|
function _error_callback(thisArgv, e, callback) {
|
|
40
95
|
__close(thisArgv);
|
|
41
96
|
callback(e);
|
|
42
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* 同步關閉檔案流
|
|
100
|
+
* Close file stream synchronously
|
|
101
|
+
*
|
|
102
|
+
* 同步關閉檔案描述符並發送關閉事件
|
|
103
|
+
* Closes file descriptor synchronously and emits close event
|
|
104
|
+
*
|
|
105
|
+
* @param {fs.WriteStream | fs.ReadStream | SyncWriteStream | SyncReadStream} stream - 流實例 / Stream instance
|
|
106
|
+
* @param {Function} cb - 回調函數 / Callback function
|
|
107
|
+
* @param {any} [err] - 錯誤物件 / Error object
|
|
108
|
+
*/
|
|
43
109
|
function closeFsStreamSync(stream, cb, err) {
|
|
44
110
|
let er;
|
|
45
111
|
try {
|
|
112
|
+
// 同步關閉檔案描述符 / Close file descriptor synchronously
|
|
46
113
|
// @ts-ignore
|
|
47
114
|
(0, fs_1.closeSync)(stream.fd);
|
|
48
115
|
}
|
|
@@ -50,28 +117,52 @@ function closeFsStreamSync(stream, cb, err) {
|
|
|
50
117
|
er = e || err;
|
|
51
118
|
}
|
|
52
119
|
cb(er);
|
|
120
|
+
// 標記流為已關閉 / Mark stream as closed
|
|
53
121
|
// @ts-ignore
|
|
54
122
|
stream.closed = true;
|
|
55
123
|
if (!er) {
|
|
124
|
+
// 無錯誤時發送關閉事件 / Emit close event on success
|
|
56
125
|
stream.emit('close');
|
|
57
126
|
}
|
|
58
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* 銷毀流
|
|
130
|
+
* Destroy stream
|
|
131
|
+
*
|
|
132
|
+
* 處理流的銷毀邏輯,包括關閉檔案描述符
|
|
133
|
+
* Handles stream destruction logic including closing file descriptor
|
|
134
|
+
*
|
|
135
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
136
|
+
* @param {Error | null} error - 錯誤物件或 null / Error object or null
|
|
137
|
+
* @param {(error: Error | null) => void} callback - 完成回調 / Completion callback
|
|
138
|
+
*/
|
|
59
139
|
function _destroy(thisArgv, error, callback) {
|
|
140
|
+
// 檢查檔案是否已開啟 / Check if file is open
|
|
60
141
|
// @ts-ignore
|
|
61
142
|
const isOpen = typeof thisArgv.fd !== 'number';
|
|
62
143
|
if (isOpen) {
|
|
144
|
+
// 等待開啟事件後再關閉 / Wait for open event before closing
|
|
63
145
|
// @ts-ignore
|
|
64
146
|
thisArgv.once('open', closeFsStreamSync.bind(null, thisArgv, callback, error));
|
|
65
147
|
return;
|
|
66
148
|
}
|
|
67
149
|
closeFsStreamSync(thisArgv, callback);
|
|
150
|
+
// 清除檔案描述符 / Clear file descriptor
|
|
68
151
|
// @ts-ignore
|
|
69
152
|
thisArgv.fd = null;
|
|
70
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* 發射錯誤和關閉事件(下一個 tick)
|
|
156
|
+
* Emit error and close events (next tick)
|
|
157
|
+
*/
|
|
71
158
|
function emitErrorAndCloseNT(self, err) {
|
|
72
159
|
emitErrorNT(self, err);
|
|
73
160
|
emitCloseNT(self);
|
|
74
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* 發射關閉事件(下一個 tick)
|
|
164
|
+
* Emit close event (next tick)
|
|
165
|
+
*/
|
|
75
166
|
function emitCloseNT(self) {
|
|
76
167
|
if (self._writableState && !self._writableState.emitClose) {
|
|
77
168
|
return;
|
|
@@ -81,11 +172,29 @@ function emitCloseNT(self) {
|
|
|
81
172
|
}
|
|
82
173
|
self.emit('close');
|
|
83
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* 發射錯誤事件(下一個 tick)
|
|
177
|
+
* Emit error event (next tick)
|
|
178
|
+
*/
|
|
84
179
|
function emitErrorNT(self, err) {
|
|
85
180
|
self.emit('error', err);
|
|
86
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* 取得流資料
|
|
184
|
+
* Get stream data
|
|
185
|
+
*
|
|
186
|
+
* 取得或初始化流的內部資料物件
|
|
187
|
+
* Gets or initializes stream's internal data object
|
|
188
|
+
*
|
|
189
|
+
* @param {IThisFsStream} thisArgv - 流實例 / Stream instance
|
|
190
|
+
* @returns {IFsStreamData} 流資料物件 / Stream data object
|
|
191
|
+
*/
|
|
87
192
|
function getFsStreamData(thisArgv) {
|
|
88
193
|
return thisArgv[exports.SYM_FS_STREAM_DATA] = thisArgv[exports.SYM_FS_STREAM_DATA] || {};
|
|
89
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* 預設導出 - 內部模組
|
|
197
|
+
* Default export - internal module
|
|
198
|
+
*/
|
|
90
199
|
exports.default = exports;
|
|
91
200
|
//# sourceMappingURL=internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["internal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 檔案系統流內部工具函數\n * File System Stream Internal Utility Functions\n *\n * 提供開啟、關閉、銷毀流等核心功能\n * Provides core functions for opening, closing, and destroying streams\n */\n\nimport { ReadStream } from '../read';\nimport { WriteStream } from '../write';\nimport { SyncReadStream } from '../read-sync';\nimport { SyncWriteStream } from '../write-sync';\nimport { IFsStreamData } from './interface';\nimport fs, { openSync, closeSync } from 'fs';\n\n/**\n * 流資料符號鍵 / Stream data symbol key\n * 用於存取流的內部資料 / Used to access stream's internal data\n */\nexport const SYM_FS_STREAM_DATA = Symbol('FsStreamData')\n\n/**\n * 檔案流類型聯合 / File stream type union\n */\nexport type IThisFsStream = WriteStream | ReadStream | SyncWriteStream | SyncReadStream\n\n/**\n * 開啟檔案流\n * Open file stream\n *\n * 使用同步方式開啟檔案並發送相關事件\n * Opens file synchronously and emits relevant events\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n * @param {any[]} [argv] - 額外參數 / Additional arguments\n */\nexport function open(thisArgv: IThisFsStream, argv?: any[])\n{\n\tif (typeof thisArgv.fd !== 'number')\n\t{\n\t\tlet fd: number\n\t\ttry\n\t\t{\n\t\t\t// 使用同步方式開啟檔案 / Open file synchronously\n\t\t\t// @ts-ignore\n\t\t\tfd = openSync(thisArgv.path, thisArgv.flags, thisArgv.mode)\n\t\t}\n\t\tcatch (er)\n\t\t{\n\t\t\t// 發生錯誤時發射錯誤事件 / Emit error on failure\n\t\t\t_error_emit(thisArgv, er)\n\t\t\treturn;\n\t\t}\n\n\t\tthisArgv.fd = fd;\n\t}\n\n\t// 發送開啟和就緒事件 / Emit open and ready events\n\tthisArgv.emit('open', thisArgv.fd);\n\tthisArgv.emit('ready');\n}\n\n/**\n * 發射錯誤事件\n * Emit error event\n *\n * 關閉流並發射錯誤事件\n * Closes stream and emits error event\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n * @param {T} e - 錯誤物件 / Error object\n */\nexport function _error_emit<T extends Error>(thisArgv: IThisFsStream, e: T): void\n{\n\t__close(thisArgv)\n\tthisArgv.emit('error', e);\n}\n\n/**\n * 內部關閉函數\n * Internal close function\n *\n * 根據 autoClose 設定決定是否銷毀流\n * Destroys stream based on autoClose setting\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n */\nexport function __close(thisArgv: IThisFsStream): void\n{\n\t// 如果啟用自動關閉,則銷毀流 / Destroy stream if autoClose is enabled\n\t// @ts-ignore\n\tif (thisArgv.autoClose)\n\t{\n\t\tthisArgv.destroy();\n\t}\n}\n\n/**\n * 錯誤回調處理\n * Error callback handler\n *\n * 關閉流並執行錯誤回調\n * Closes stream and executes error callback\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n * @param {T} e - 錯誤物件 / Error object\n * @param {Function} callback - 回調函數 / Callback function\n */\nexport function _error_callback<T extends Error>(thisArgv: IThisFsStream, e: T, callback: Function): void\n{\n\t__close(thisArgv)\n\tcallback(e);\n}\n\n/**\n * 同步關閉檔案流\n * Close file stream synchronously\n *\n * 同步關閉檔案描述符並發送關閉事件\n * Closes file descriptor synchronously and emits close event\n *\n * @param {fs.WriteStream | fs.ReadStream | SyncWriteStream | SyncReadStream} stream - 流實例 / Stream instance\n * @param {Function} cb - 回調函數 / Callback function\n * @param {any} [err] - 錯誤物件 / Error object\n */\nexport function closeFsStreamSync(stream: fs.WriteStream | fs.ReadStream | SyncWriteStream | SyncReadStream,\n\tcb: Function,\n\terr?,\n)\n{\n\tlet er\n\ttry\n\t{\n\t\t// 同步關閉檔案描述符 / Close file descriptor synchronously\n\t\t// @ts-ignore\n\t\tcloseSync(stream.fd)\n\t}\n\tcatch (e)\n\t{\n\t\ter = e || err;\n\t}\n\n\tcb(er)\n\t// 標記流為已關閉 / Mark stream as closed\n\t// @ts-ignore\n\tstream.closed = true;\n\tif (!er)\n\t{\n\t\t// 無錯誤時發送關閉事件 / Emit close event on success\n\t\tstream.emit('close');\n\t}\n}\n\n/**\n * 銷毀流\n * Destroy stream\n *\n * 處理流的銷毀邏輯,包括關閉檔案描述符\n * Handles stream destruction logic including closing file descriptor\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n * @param {Error | null} error - 錯誤物件或 null / Error object or null\n * @param {(error: Error | null) => void} callback - 完成回調 / Completion callback\n */\nexport function _destroy(thisArgv: IThisFsStream, error: Error | null, callback: (error: Error | null) => void): void\n{\n\t// 檢查檔案是否已開啟 / Check if file is open\n\t// @ts-ignore\n\tconst isOpen = typeof thisArgv.fd !== 'number';\n\n\tif (isOpen)\n\t{\n\t\t// 等待開啟事件後再關閉 / Wait for open event before closing\n\t\t// @ts-ignore\n\t\tthisArgv.once('open', closeFsStreamSync.bind(null, thisArgv, callback, error));\n\t\treturn;\n\t}\n\n\tcloseFsStreamSync(thisArgv as any, callback)\n\t// 清除檔案描述符 / Clear file descriptor\n\t// @ts-ignore\n\tthisArgv.fd = null;\n}\n\n/**\n * 發射錯誤和關閉事件(下一個 tick)\n * Emit error and close events (next tick)\n */\nfunction emitErrorAndCloseNT(self, err)\n{\n\temitErrorNT(self, err);\n\temitCloseNT(self);\n}\n\n/**\n * 發射關閉事件(下一個 tick)\n * Emit close event (next tick)\n */\nfunction emitCloseNT(self)\n{\n\tif (self._writableState && !self._writableState.emitClose)\n\t{\n\t\treturn;\n\t}\n\tif (self._readableState && !self._readableState.emitClose)\n\t{\n\t\treturn;\n\t}\n\tself.emit('close');\n}\n\n/**\n * 發射錯誤事件(下一個 tick)\n * Emit error event (next tick)\n */\nfunction emitErrorNT(self, err)\n{\n\tself.emit('error', err);\n}\n\n/**\n * 取得流資料\n * Get stream data\n *\n * 取得或初始化流的內部資料物件\n * Gets or initializes stream's internal data object\n *\n * @param {IThisFsStream} thisArgv - 流實例 / Stream instance\n * @returns {IFsStreamData} 流資料物件 / Stream data object\n */\nexport function getFsStreamData(thisArgv: IThisFsStream): IFsStreamData\n{\n\treturn thisArgv[SYM_FS_STREAM_DATA] = thisArgv[SYM_FS_STREAM_DATA] || {}\n}\n\n/**\n * 預設導出 - 內部模組\n * Default export - internal module\n */\nexport default exports as typeof import('./internal');\n"]}
|
package/lib/util.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["util.ts"],"names":[],"mappings":"","sourcesContent":[""]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fs-stream-sync",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.22",
|
|
4
4
|
"description": "檔案系統同步讀寫流實作,相容於 Node.js Core fs 模組 (File System synchronous read/write stream implementation, compatible with Node.js Core fs module)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"File System",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"@types/node": "*",
|
|
51
51
|
"tslib": "^2"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "6c690c4123ff9db0f807fbc9a05f509a832aee69"
|
|
54
54
|
}
|
package/read-sync.d.ts
CHANGED
|
@@ -1,13 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 同步讀取流實作
|
|
3
|
+
* Synchronous Read Stream Implementation
|
|
4
|
+
*
|
|
5
|
+
* 提供同步檔案讀取流功能
|
|
6
|
+
* Provides synchronous file reading stream functionality
|
|
7
|
+
*
|
|
8
|
+
* @module fs-stream-sync/read-sync
|
|
9
|
+
*/
|
|
1
10
|
import { PathLike } from "fs";
|
|
2
11
|
import { IFsReadStreamOptions } from './lib/interface';
|
|
3
12
|
import { ReadStream } from './read';
|
|
13
|
+
/**
|
|
14
|
+
* 最小緩衝池空間(位元組)
|
|
15
|
+
* Minimum pool space in bytes
|
|
16
|
+
*/
|
|
4
17
|
export declare const kMinPoolSpace = 128;
|
|
18
|
+
/**
|
|
19
|
+
* 同步讀取流類別
|
|
20
|
+
* Synchronous Read Stream Class
|
|
21
|
+
*
|
|
22
|
+
* 提供同步檔案讀取功能,繼承自 ReadStream
|
|
23
|
+
* Provides synchronous file reading functionality, extends ReadStream
|
|
24
|
+
*/
|
|
5
25
|
export declare class SyncReadStream extends ReadStream {
|
|
26
|
+
/**
|
|
27
|
+
* 構造函數
|
|
28
|
+
* Constructor
|
|
29
|
+
*
|
|
30
|
+
* @param {PathLike} path - 檔案路徑 / File path
|
|
31
|
+
* @param {string | IFsReadStreamOptions} [options] - 選項 / Options
|
|
32
|
+
*/
|
|
6
33
|
constructor(path: PathLike, options?: string | IFsReadStreamOptions);
|
|
34
|
+
/**
|
|
35
|
+
* 建立函數別名
|
|
36
|
+
* Factory method alias
|
|
37
|
+
*/
|
|
7
38
|
static get create(): typeof createSyncReadStream;
|
|
39
|
+
/**
|
|
40
|
+
* 開啟檔案流
|
|
41
|
+
* Open file stream
|
|
42
|
+
*
|
|
43
|
+
* 同步開啟檔案並發送 open 和 ready 事件
|
|
44
|
+
* Opens file synchronously and emits open and ready events
|
|
45
|
+
*/
|
|
8
46
|
open(): void;
|
|
47
|
+
/**
|
|
48
|
+
* 內部讀取方法
|
|
49
|
+
* Internal read method
|
|
50
|
+
*
|
|
51
|
+
* 從檔案同步讀取資料到緩衝池
|
|
52
|
+
* Reads data from file synchronously into buffer pool
|
|
53
|
+
*
|
|
54
|
+
* @param {number} n - 要讀取的位元組數 / Number of bytes to read
|
|
55
|
+
* @returns {boolean | this} 讀取結果 / Read result
|
|
56
|
+
*/
|
|
9
57
|
_read(n: number): boolean | this;
|
|
58
|
+
/**
|
|
59
|
+
* 銷毀流
|
|
60
|
+
* Destroy stream
|
|
61
|
+
*
|
|
62
|
+
* 清理資源並關閉檔案描述符
|
|
63
|
+
* Cleans up resources and closes file descriptor
|
|
64
|
+
*
|
|
65
|
+
* @param {Error | null} error - 錯誤物件或 null / Error object or null
|
|
66
|
+
* @param {(error: Error | null) => void} callback - 完成回調 / Completion callback
|
|
67
|
+
*/
|
|
10
68
|
_destroy(error: Error | null, callback: (error: Error | null) => void): void;
|
|
11
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* 建立同步讀取流
|
|
72
|
+
* Create synchronous read stream
|
|
73
|
+
*
|
|
74
|
+
* 工廠函數,建立 SyncReadStream 實例
|
|
75
|
+
* Factory function that creates a SyncReadStream instance
|
|
76
|
+
*
|
|
77
|
+
* @param {PathLike} path - 檔案路徑 / File path
|
|
78
|
+
* @param {string | IFsReadStreamOptions} [options] - 選項 / Options
|
|
79
|
+
* @returns {SyncReadStream} 同步讀取流實例 / Synchronous read stream instance
|
|
80
|
+
*/
|
|
12
81
|
export declare function createSyncReadStream(path: PathLike, options?: string | IFsReadStreamOptions): SyncReadStream;
|
|
82
|
+
/**
|
|
83
|
+
* 預設導出 - SyncReadStream 類別
|
|
84
|
+
* Default export - SyncReadStream class
|
|
85
|
+
*/
|
|
13
86
|
export default SyncReadStream;
|
package/read-sync.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 同步讀取流實作
|
|
4
|
+
* Synchronous Read Stream Implementation
|
|
5
|
+
*
|
|
6
|
+
* 提供同步檔案讀取流功能
|
|
7
|
+
* Provides synchronous file reading stream functionality
|
|
8
|
+
*
|
|
9
|
+
* @module fs-stream-sync/read-sync
|
|
10
|
+
*/
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.SyncReadStream = exports.kMinPoolSpace = void 0;
|
|
4
13
|
exports.createSyncReadStream = createSyncReadStream;
|
|
@@ -7,26 +16,74 @@ const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
|
7
16
|
const internal_1 = require("./lib/internal");
|
|
8
17
|
const internal_2 = tslib_1.__importDefault(require("./lib/internal"));
|
|
9
18
|
const read_1 = require("./read");
|
|
19
|
+
/**
|
|
20
|
+
* 最小緩衝池空間(位元組)
|
|
21
|
+
* Minimum pool space in bytes
|
|
22
|
+
*/
|
|
10
23
|
exports.kMinPoolSpace = 128;
|
|
24
|
+
/**
|
|
25
|
+
* 共享緩衝池 - 用於減少記憶體分配
|
|
26
|
+
* Shared buffer pool - used to reduce memory allocations
|
|
27
|
+
*/
|
|
11
28
|
let pool;
|
|
29
|
+
/**
|
|
30
|
+
* 緩衝池碎片陣列 - 儲存可回收的緩衝區
|
|
31
|
+
* Pool fragments array - stores recyclable buffers
|
|
32
|
+
*/
|
|
12
33
|
const poolFragments = [];
|
|
34
|
+
/**
|
|
35
|
+
* 分配新的緩衝池
|
|
36
|
+
* Allocate new buffer pool
|
|
37
|
+
*
|
|
38
|
+
* 嘗試從碎片陣列重用緩衝區,否則建立新緩衝區
|
|
39
|
+
* Tries to reuse buffer from fragments array, otherwise creates new buffer
|
|
40
|
+
*
|
|
41
|
+
* @param {number} poolSize - 緩衝池大小 / Pool size in bytes
|
|
42
|
+
*/
|
|
13
43
|
function allocNewPool(poolSize) {
|
|
14
44
|
if (poolFragments.length > 0) {
|
|
45
|
+
// 重用現有的緩衝區碎片 / Reuse existing buffer fragment
|
|
15
46
|
pool = poolFragments.pop();
|
|
16
47
|
}
|
|
17
48
|
else {
|
|
49
|
+
// 建立新的不安全緩衝區 / Create new unsafe buffer
|
|
18
50
|
pool = Buffer.allocUnsafe(poolSize);
|
|
19
51
|
}
|
|
20
52
|
pool.used = 0;
|
|
21
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* 同步讀取流類別
|
|
56
|
+
* Synchronous Read Stream Class
|
|
57
|
+
*
|
|
58
|
+
* 提供同步檔案讀取功能,繼承自 ReadStream
|
|
59
|
+
* Provides synchronous file reading functionality, extends ReadStream
|
|
60
|
+
*/
|
|
22
61
|
class SyncReadStream extends read_1.ReadStream {
|
|
62
|
+
/**
|
|
63
|
+
* 構造函數
|
|
64
|
+
* Constructor
|
|
65
|
+
*
|
|
66
|
+
* @param {PathLike} path - 檔案路徑 / File path
|
|
67
|
+
* @param {string | IFsReadStreamOptions} [options] - 選項 / Options
|
|
68
|
+
*/
|
|
23
69
|
constructor(path, options) {
|
|
24
70
|
// @ts-ignore
|
|
25
71
|
super(path, options);
|
|
26
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* 建立函數別名
|
|
75
|
+
* Factory method alias
|
|
76
|
+
*/
|
|
27
77
|
static get create() {
|
|
28
78
|
return createSyncReadStream;
|
|
29
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* 開啟檔案流
|
|
82
|
+
* Open file stream
|
|
83
|
+
*
|
|
84
|
+
* 同步開啟檔案並發送 open 和 ready 事件
|
|
85
|
+
* Opens file synchronously and emits open and ready events
|
|
86
|
+
*/
|
|
30
87
|
open() {
|
|
31
88
|
if (typeof (0, internal_1.getFsStreamData)(this) !== 'boolean') {
|
|
32
89
|
this[internal_1.SYM_FS_STREAM_DATA].opened = true;
|
|
@@ -39,47 +96,60 @@ class SyncReadStream extends read_1.ReadStream {
|
|
|
39
96
|
this.emit('ready');
|
|
40
97
|
}
|
|
41
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* 內部讀取方法
|
|
101
|
+
* Internal read method
|
|
102
|
+
*
|
|
103
|
+
* 從檔案同步讀取資料到緩衝池
|
|
104
|
+
* Reads data from file synchronously into buffer pool
|
|
105
|
+
*
|
|
106
|
+
* @param {number} n - 要讀取的位元組數 / Number of bytes to read
|
|
107
|
+
* @returns {boolean | this} 讀取結果 / Read result
|
|
108
|
+
*/
|
|
42
109
|
_read(n) {
|
|
110
|
+
// 等待檔案開啟 / Wait for file to open
|
|
43
111
|
if (typeof this.fd !== 'number') {
|
|
44
112
|
return this.once('open', function () {
|
|
45
113
|
// @ts-ignore
|
|
46
114
|
this._read(n);
|
|
47
115
|
});
|
|
48
116
|
}
|
|
117
|
+
// 檢查流是否已銷毀 / Check if stream is destroyed
|
|
49
118
|
if (this.destroyed) {
|
|
50
119
|
return;
|
|
51
120
|
}
|
|
121
|
+
// 檢查緩衝池空間是否足夠 / Check if pool has enough space
|
|
52
122
|
if (!pool || pool.length - pool.used < exports.kMinPoolSpace) {
|
|
53
|
-
//
|
|
123
|
+
// 丟棄舊緩衝池並建立新的 / Discard old pool and allocate new one
|
|
54
124
|
allocNewPool(this.readableHighWaterMark);
|
|
55
125
|
}
|
|
56
126
|
const thisPool = pool;
|
|
57
127
|
let toRead = Math.min(pool.length - pool.used, n);
|
|
58
128
|
const start = pool.used;
|
|
129
|
+
// 計算實際可讀取位元組數 / Calculate actual readable bytes
|
|
59
130
|
if (this.pos !== undefined) {
|
|
60
131
|
toRead = Math.min(this.end - this.pos + 1, toRead);
|
|
61
132
|
}
|
|
62
133
|
else {
|
|
63
134
|
toRead = Math.min(this.end - this.bytesRead + 1, toRead);
|
|
64
135
|
}
|
|
65
|
-
//
|
|
66
|
-
// treat as EOF.
|
|
136
|
+
// 已讀取完所有資料,視為 EOF / Already read everything, treat as EOF
|
|
67
137
|
if (toRead <= 0) {
|
|
68
138
|
return this.push(null);
|
|
69
139
|
}
|
|
70
140
|
try {
|
|
71
|
-
//
|
|
141
|
+
// 實際讀取操作 / The actual read operation
|
|
72
142
|
let bytesRead = fs_1.default.readSync(this.fd, pool, pool.used, toRead, this.pos);
|
|
73
143
|
let b = null;
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
// reservation to be used as a new pool later.
|
|
144
|
+
// 調整緩衝池已使用標記或回收剩餘空間
|
|
145
|
+
// Adjust pool used marker or recycle remaining space
|
|
77
146
|
if (start + toRead === thisPool.used && thisPool === pool) {
|
|
78
147
|
thisPool.used += bytesRead - toRead;
|
|
79
148
|
}
|
|
80
149
|
else if (toRead - bytesRead > exports.kMinPoolSpace) {
|
|
81
150
|
poolFragments.push(thisPool.slice(start + bytesRead, start + toRead));
|
|
82
151
|
}
|
|
152
|
+
// 建立結果緩衝區 / Create result buffer
|
|
83
153
|
if (bytesRead > 0) {
|
|
84
154
|
this.bytesRead += bytesRead;
|
|
85
155
|
b = thisPool.slice(start, start + bytesRead);
|
|
@@ -87,24 +157,50 @@ class SyncReadStream extends read_1.ReadStream {
|
|
|
87
157
|
this.push(b);
|
|
88
158
|
}
|
|
89
159
|
catch (er) {
|
|
160
|
+
// 發生錯誤時自動關閉流 / Auto-close stream on error
|
|
90
161
|
if (this.autoClose) {
|
|
91
162
|
this.destroy();
|
|
92
163
|
}
|
|
93
164
|
this.emit('error', er);
|
|
94
165
|
}
|
|
95
|
-
//
|
|
166
|
+
// 更新位置和緩衝池標記 / Update position and pool markers
|
|
96
167
|
if (this.pos !== undefined) {
|
|
97
168
|
this.pos += toRead;
|
|
98
169
|
}
|
|
99
170
|
pool.used += toRead;
|
|
100
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* 銷毀流
|
|
174
|
+
* Destroy stream
|
|
175
|
+
*
|
|
176
|
+
* 清理資源並關閉檔案描述符
|
|
177
|
+
* Cleans up resources and closes file descriptor
|
|
178
|
+
*
|
|
179
|
+
* @param {Error | null} error - 錯誤物件或 null / Error object or null
|
|
180
|
+
* @param {(error: Error | null) => void} callback - 完成回調 / Completion callback
|
|
181
|
+
*/
|
|
101
182
|
_destroy(error, callback) {
|
|
102
183
|
internal_2.default._destroy(this, error, callback);
|
|
103
184
|
}
|
|
104
185
|
}
|
|
105
186
|
exports.SyncReadStream = SyncReadStream;
|
|
187
|
+
/**
|
|
188
|
+
* 建立同步讀取流
|
|
189
|
+
* Create synchronous read stream
|
|
190
|
+
*
|
|
191
|
+
* 工廠函數,建立 SyncReadStream 實例
|
|
192
|
+
* Factory function that creates a SyncReadStream instance
|
|
193
|
+
*
|
|
194
|
+
* @param {PathLike} path - 檔案路徑 / File path
|
|
195
|
+
* @param {string | IFsReadStreamOptions} [options] - 選項 / Options
|
|
196
|
+
* @returns {SyncReadStream} 同步讀取流實例 / Synchronous read stream instance
|
|
197
|
+
*/
|
|
106
198
|
function createSyncReadStream(path, options) {
|
|
107
199
|
return new SyncReadStream(path, options);
|
|
108
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* 預設導出 - SyncReadStream 類別
|
|
203
|
+
* Default export - SyncReadStream class
|
|
204
|
+
*/
|
|
109
205
|
exports.default = SyncReadStream;
|
|
110
206
|
//# sourceMappingURL=read-sync.js.map
|
package/read-sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-sync.js","sourceRoot":"","sources":["read-sync.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAuOH,oDAGC;;AAxOD,oDAAoB;AAGpB,6CAAqE;AACrE,sEAAsC;AACtC,iCAAmC;AAEnC;;;GAGG;AACU,QAAA,aAAa,GAAG,GAAG,CAAC;AAEjC;;;GAGG;AACH,IAAI,IAAI,CAAC;AAET;;;GAGG;AACH,MAAM,aAAa,GAAG,EAAE,CAAC;AAEzB;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,QAAgB;IAErC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAC5B,CAAC;QACA,8CAA8C;QAC9C,IAAI,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC;SAED,CAAC;QACA,wCAAwC;QACxC,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAa,cAAe,SAAQ,iBAAU;IAE7C;;;;;;OAMG;IACH,YAAY,IAAc,EAAE,OAAuC;QAElE,aAAa;QACb,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACrB,CAAC;IAED;;;OAGG;IACH,MAAM,KAAc,MAAM;QAEzB,OAAO,oBAAoB,CAAA;IAC5B,CAAC;IAED;;;;;;OAMG;IACM,IAAI;QAEZ,IAAI,OAAO,IAAA,0BAAe,EAAC,IAAI,CAAC,KAAK,SAAS,EAC9C,CAAC;YACA,IAAI,CAAC,6BAAkB,CAAC,CAAC,MAAM,GAAG,IAAI,CAAA;YACtC,kBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACnB,IAAI,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;aACI,IAAI,IAAI,CAAC,6BAAkB,CAAC,CAAC,MAAM,KAAK,IAAI,EACjD,CAAC;YACA,IAAI,CAAC,6BAAkB,CAAC,CAAC,MAAM,GAAG,KAAK,CAAA;YACvC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IACM,KAAK,CAAC,CAAS;QAEvB,iCAAiC;QACjC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAC/B,CAAC;YACA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;gBAExB,aAAa;gBACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;QACJ,CAAC;QAED,0CAA0C;QAC1C,IAAI,IAAI,CAAC,SAAS,EAClB,CAAC;YACA,OAAO;QACR,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,GAAG,qBAAa,EACpD,CAAC;YACA,sDAAsD;YACtD,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC;QACtB,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAExB,gDAAgD;QAChD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAC1B,CAAC;YACA,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;aAED,CAAC;YACA,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;QAED,0DAA0D;QAC1D,IAAI,MAAM,IAAI,CAAC,EACf,CAAC;YACA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAED,IACA,CAAC;YACA,qCAAqC;YACrC,IAAI,SAAS,GAAG,YAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAExE,IAAI,CAAC,GAAG,IAAI,CAAC;YACb,oBAAoB;YACpB,qDAAqD;YACrD,IAAI,KAAK,GAAG,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,QAAQ,KAAK,IAAI,EACzD,CAAC;gBACA,QAAQ,CAAC,IAAI,IAAI,SAAS,GAAG,MAAM,CAAC;YACrC,CAAC;iBACI,IAAI,MAAM,GAAG,SAAS,GAAG,qBAAa,EAC3C,CAAC;gBACA,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;YACvE,CAAC;YAED,iCAAiC;YACjC,IAAI,SAAS,GAAG,CAAC,EACjB,CAAC;gBACA,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC;gBAC5B,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;QACD,OAAO,EAAE,EACT,CAAC;YACA,0CAA0C;YAC1C,IAAI,IAAI,CAAC,SAAS,EAClB,CAAC;gBACA,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACxB,CAAC;QAED,gDAAgD;QAChD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAC1B,CAAC;YACA,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;IACrB,CAAC;IAED;;;;;;;;;OASG;IACM,QAAQ,CAAC,KAAmB,EAAE,QAAuC;QAE7E,kBAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;IACzC,CAAC;CACD;AAhKD,wCAgKC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAAC,IAAc,EAAE,OAAuC;IAE3F,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC;AAED;;;GAGG;AACH,kBAAe,cAAc,CAAA","sourcesContent":["/**\n * 同步讀取流實作\n * Synchronous Read Stream Implementation\n *\n * 提供同步檔案讀取流功能\n * Provides synchronous file reading stream functionality\n *\n * @module fs-stream-sync/read-sync\n */\n\nimport fs from 'fs';\nimport { PathLike } from \"fs\";\nimport { IFsReadStreamOptions } from './lib/interface';\nimport { getFsStreamData, SYM_FS_STREAM_DATA } from './lib/internal';\nimport internal from \"./lib/internal\";\nimport { ReadStream } from './read'\n\n/**\n * 最小緩衝池空間(位元組)\n * Minimum pool space in bytes\n */\nexport const kMinPoolSpace = 128;\n\n/**\n * 共享緩衝池 - 用於減少記憶體分配\n * Shared buffer pool - used to reduce memory allocations\n */\nlet pool;\n\n/**\n * 緩衝池碎片陣列 - 儲存可回收的緩衝區\n * Pool fragments array - stores recyclable buffers\n */\nconst poolFragments = [];\n\n/**\n * 分配新的緩衝池\n * Allocate new buffer pool\n *\n * 嘗試從碎片陣列重用緩衝區,否則建立新緩衝區\n * Tries to reuse buffer from fragments array, otherwise creates new buffer\n *\n * @param {number} poolSize - 緩衝池大小 / Pool size in bytes\n */\nfunction allocNewPool(poolSize: number)\n{\n\tif (poolFragments.length > 0)\n\t{\n\t\t// 重用現有的緩衝區碎片 / Reuse existing buffer fragment\n\t\tpool = poolFragments.pop();\n\t}\n\telse\n\t{\n\t\t// 建立新的不安全緩衝區 / Create new unsafe buffer\n\t\tpool = Buffer.allocUnsafe(poolSize);\n\t}\n\tpool.used = 0;\n}\n\n/**\n * 同步讀取流類別\n * Synchronous Read Stream Class\n *\n * 提供同步檔案讀取功能,繼承自 ReadStream\n * Provides synchronous file reading functionality, extends ReadStream\n */\nexport class SyncReadStream extends ReadStream\n{\n\t/**\n\t * 構造函數\n\t * Constructor\n\t *\n\t * @param {PathLike} path - 檔案路徑 / File path\n\t * @param {string | IFsReadStreamOptions} [options] - 選項 / Options\n\t */\n\tconstructor(path: PathLike, options?: string | IFsReadStreamOptions)\n\t{\n\t\t// @ts-ignore\n\t\tsuper(path, options)\n\t}\n\n\t/**\n\t * 建立函數別名\n\t * Factory method alias\n\t */\n\tstatic override get create()\n\t{\n\t\treturn createSyncReadStream\n\t}\n\n\t/**\n\t * 開啟檔案流\n\t * Open file stream\n\t *\n\t * 同步開啟檔案並發送 open 和 ready 事件\n\t * Opens file synchronously and emits open and ready events\n\t */\n\toverride open(): void\n\t{\n\t\tif (typeof getFsStreamData(this) !== 'boolean')\n\t\t{\n\t\t\tthis[SYM_FS_STREAM_DATA].opened = true\n\t\t\tinternal.open(this)\n\t\t\tthis.read();\n\t\t}\n\t\telse if (this[SYM_FS_STREAM_DATA].opened === true)\n\t\t{\n\t\t\tthis[SYM_FS_STREAM_DATA].opened = false\n\t\t\tthis.emit('open', this.fd);\n\t\t\tthis.emit('ready');\n\t\t}\n\t}\n\n\t/**\n\t * 內部讀取方法\n\t * Internal read method\n\t *\n\t * 從檔案同步讀取資料到緩衝池\n\t * Reads data from file synchronously into buffer pool\n\t *\n\t * @param {number} n - 要讀取的位元組數 / Number of bytes to read\n\t * @returns {boolean | this} 讀取結果 / Read result\n\t */\n\toverride _read(n: number)\n\t{\n\t\t// 等待檔案開啟 / Wait for file to open\n\t\tif (typeof this.fd !== 'number')\n\t\t{\n\t\t\treturn this.once('open', function ()\n\t\t\t{\n\t\t\t\t// @ts-ignore\n\t\t\t\tthis._read(n);\n\t\t\t});\n\t\t}\n\n\t\t// 檢查流是否已銷毀 / Check if stream is destroyed\n\t\tif (this.destroyed)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\t// 檢查緩衝池空間是否足夠 / Check if pool has enough space\n\t\tif (!pool || pool.length - pool.used < kMinPoolSpace)\n\t\t{\n\t\t\t// 丟棄舊緩衝池並建立新的 / Discard old pool and allocate new one\n\t\t\tallocNewPool(this.readableHighWaterMark);\n\t\t}\n\n\t\tconst thisPool = pool;\n\t\tlet toRead = Math.min(pool.length - pool.used, n);\n\t\tconst start = pool.used;\n\n\t\t// 計算實際可讀取位元組數 / Calculate actual readable bytes\n\t\tif (this.pos !== undefined)\n\t\t{\n\t\t\ttoRead = Math.min(this.end - this.pos + 1, toRead);\n\t\t}\n\t\telse\n\t\t{\n\t\t\ttoRead = Math.min(this.end - this.bytesRead + 1, toRead);\n\t\t}\n\n\t\t// 已讀取完所有資料,視為 EOF / Already read everything, treat as EOF\n\t\tif (toRead <= 0)\n\t\t{\n\t\t\treturn this.push(null);\n\t\t}\n\n\t\ttry\n\t\t{\n\t\t\t// 實際讀取操作 / The actual read operation\n\t\t\tlet bytesRead = fs.readSync(this.fd, pool, pool.used, toRead, this.pos);\n\n\t\t\tlet b = null;\n\t\t\t// 調整緩衝池已使用標記或回收剩餘空間\n\t\t\t// Adjust pool used marker or recycle remaining space\n\t\t\tif (start + toRead === thisPool.used && thisPool === pool)\n\t\t\t{\n\t\t\t\tthisPool.used += bytesRead - toRead;\n\t\t\t}\n\t\t\telse if (toRead - bytesRead > kMinPoolSpace)\n\t\t\t{\n\t\t\t\tpoolFragments.push(thisPool.slice(start + bytesRead, start + toRead));\n\t\t\t}\n\n\t\t\t// 建立結果緩衝區 / Create result buffer\n\t\t\tif (bytesRead > 0)\n\t\t\t{\n\t\t\t\tthis.bytesRead += bytesRead;\n\t\t\t\tb = thisPool.slice(start, start + bytesRead);\n\t\t\t}\n\n\t\t\tthis.push(b);\n\t\t}\n\t\tcatch (er)\n\t\t{\n\t\t\t// 發生錯誤時自動關閉流 / Auto-close stream on error\n\t\t\tif (this.autoClose)\n\t\t\t{\n\t\t\t\tthis.destroy();\n\t\t\t}\n\t\t\tthis.emit('error', er);\n\t\t}\n\n\t\t// 更新位置和緩衝池標記 / Update position and pool markers\n\t\tif (this.pos !== undefined)\n\t\t{\n\t\t\tthis.pos += toRead;\n\t\t}\n\t\tpool.used += toRead;\n\t}\n\n\t/**\n\t * 銷毀流\n\t * Destroy stream\n\t *\n\t * 清理資源並關閉檔案描述符\n\t * Cleans up resources and closes file descriptor\n\t *\n\t * @param {Error | null} error - 錯誤物件或 null / Error object or null\n\t * @param {(error: Error | null) => void} callback - 完成回調 / Completion callback\n\t */\n\toverride _destroy(error: Error | null, callback: (error: Error | null) => void): void\n\t{\n\t\tinternal._destroy(this, error, callback)\n\t}\n}\n\n/**\n * 建立同步讀取流\n * Create synchronous read stream\n *\n * 工廠函數,建立 SyncReadStream 實例\n * Factory function that creates a SyncReadStream instance\n *\n * @param {PathLike} path - 檔案路徑 / File path\n * @param {string | IFsReadStreamOptions} [options] - 選項 / Options\n * @returns {SyncReadStream} 同步讀取流實例 / Synchronous read stream instance\n */\nexport function createSyncReadStream(path: PathLike, options?: string | IFsReadStreamOptions)\n{\n\treturn new SyncReadStream(path, options)\n}\n\n/**\n * 預設導出 - SyncReadStream 類別\n * Default export - SyncReadStream class\n */\nexport default SyncReadStream\n"]}
|
package/read.d.ts
CHANGED
|
@@ -1,22 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fs-stream-sync - 檔案系統流處理工具
|
|
3
|
+
*
|
|
4
|
+
* 這個模組提供了檔案系統的同步和異步流處理功能,包括讀取和寫入流。
|
|
5
|
+
*
|
|
6
|
+
* @module fs-stream-sync
|
|
7
|
+
* @author bluelovers
|
|
8
|
+
*/
|
|
1
9
|
import { PathLike } from "fs";
|
|
2
10
|
import fs from 'fs';
|
|
3
11
|
import { IFsReadStreamOptions, IFsStreamData, IFsStreamState, IFsWriteStreamOptions } from './lib/interface';
|
|
4
12
|
import { SYM_FS_STREAM_DATA } from './lib/internal';
|
|
13
|
+
/**
|
|
14
|
+
* 讀取流類 - 擴展 Node.js 的 ReadStream
|
|
15
|
+
*
|
|
16
|
+
* 這個類提供了檔案讀取流的功能,支援同步和異步操作。
|
|
17
|
+
*
|
|
18
|
+
* @class ReadStream
|
|
19
|
+
* @extends fs.ReadStream
|
|
20
|
+
*/
|
|
5
21
|
export declare class ReadStream extends fs.ReadStream {
|
|
22
|
+
/** 是否自動關閉 */
|
|
6
23
|
protected autoClose: boolean;
|
|
24
|
+
/** 檔案標誌 */
|
|
7
25
|
protected flags: string;
|
|
26
|
+
/** 檔案描述符 */
|
|
8
27
|
fd: number;
|
|
28
|
+
/** 檔案模式 */
|
|
9
29
|
protected mode: number;
|
|
30
|
+
/** 當前位置 */
|
|
10
31
|
protected pos: number;
|
|
32
|
+
/** 是否已關閉 */
|
|
11
33
|
protected closed: boolean;
|
|
34
|
+
/** 是否已銷毀 */
|
|
12
35
|
protected destroyed: boolean;
|
|
36
|
+
/** 可寫狀態 */
|
|
13
37
|
protected _writableState: IFsStreamState;
|
|
38
|
+
/** 可讀狀態 */
|
|
14
39
|
protected _readableState: IFsStreamState;
|
|
40
|
+
/** 流資料 */
|
|
15
41
|
protected [SYM_FS_STREAM_DATA]: IFsStreamData;
|
|
42
|
+
/** 結束位置 */
|
|
16
43
|
protected end: number;
|
|
44
|
+
/**
|
|
45
|
+
* 構造函數
|
|
46
|
+
*
|
|
47
|
+
* @param {PathLike} path 檔案路徑
|
|
48
|
+
* @param {string | IFsWriteStreamOptions} [options] 選項
|
|
49
|
+
*/
|
|
17
50
|
constructor(path: PathLike, options?: string | IFsWriteStreamOptions);
|
|
51
|
+
/** 創建函數別名 */
|
|
18
52
|
static get create(): typeof createReadStream;
|
|
53
|
+
/**
|
|
54
|
+
* 打開流
|
|
55
|
+
*
|
|
56
|
+
* 這個函數會打開檔案流,並設置相關狀態。
|
|
57
|
+
*/
|
|
19
58
|
open(): void;
|
|
20
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* 創建讀取流
|
|
62
|
+
*
|
|
63
|
+
* 這個函數會創建一個 ReadStream 實例。
|
|
64
|
+
*
|
|
65
|
+
* @param {PathLike} path 檔案路徑
|
|
66
|
+
* @param {string | IFsReadStreamOptions} [options] 選項
|
|
67
|
+
* @returns {ReadStream} 讀取流實例
|
|
68
|
+
*/
|
|
21
69
|
export declare function createReadStream(path: PathLike, options?: string | IFsReadStreamOptions): ReadStream;
|
|
70
|
+
/** 預設導出 - ReadStream 類 */
|
|
22
71
|
export default ReadStream;
|