readSync 或 createReadStream(Symbol.asyncIterator)哪个更好?
What's better readSync or createReadStream (with Symbol.asyncIterator)?
- createReadStream(使用 Symbol.asyncIterator)
async function* readChunkIter(chunksAsync) {
for await (const chunk of chunksAsync) {
// magic
yield chunk;
}
}
const fileStream = fs.createReadStream(filePath, { highWaterMark: 1024 * 64 });
const readChunk = readChunkIter(fileStream);
- 读取同步
function* readChunkIter(fd) {
// loop
// magic
fs.readSync(fd, buffer, 0, chunkSize, bytesRead);
yield buffer;
}
const fd = fs.openSync(filePath, 'r');
const readChunk = readChunkIter(fd);
什么与生成器函数一起使用更好,为什么?
upd:我不是在寻找更好的方法,我想知道使用这些功能的区别
首先,您将同步文件操作 fs.readSync()
与流中的异步文件操作(内部使用 fs.read()
)进行比较。所以,这有点像服务器使用的苹果和橘子。
如果这是在服务器上,则永远不要使用同步文件 I/O 除了在服务器启动时,因为在处理请求或任何其他服务器事件时,同步文件 I/O 会阻塞整个事件循环文件读取操作大大降低了服务器的可扩展性。仅使用异步文件 I/O,在您的两种情况之间将是流。
否则,如果这不是在服务器上或任何关心在同步文件操作期间阻止 node.js 事件循环的进程,那么完全取决于您喜欢哪个界面。
其他评论:
还不清楚为什么要将 for await()
包装在生成器中。调用者可以自己使用 for await()
并避免在生成器中包装。
读取文件的流通常以事件驱动的方式使用,通过向 data
事件添加事件侦听器并在数据到达时响应数据。如果您只是要从文件中异步读取数据块,那么流实际上没有任何好处。您也可以只使用 fs.read()
或 fs.promises.read()
.
如果不了解您尝试编码的整体问题,我们无法真正评论 best/better 解决问题的方法。您刚刚展示了一小段阅读数据。结构化的最佳方式取决于更高级别的代码如何最方便地 use/consume 数据(您不显示)。
I really didn't ask the right question. I'm not looking for a better way, I want to know the difference between using these features.
嗯,主要区别在于 fs.readSync()
是阻塞和同步的,因此会阻塞事件循环,破坏服务器的可伸缩性,永远不应在服务器环境中使用(启动代码期间除外)。 node.js 中的流是异步的,不会阻塞事件循环。
除此之外,流是一种比直接读取文件更高级别的构造,应该在您实际使用流的功能时使用,而在您只是从中读取块时可能不应该使用直接文件并且不使用流的任何功能。
特别是,对于流,错误处理并不总是那么清晰,尤其是在尝试使用 await
和 promises 时。这可能是因为 readstreams 最初被设计为事件驱动对象,这意味着在 error
事件上间接传达错误,这使得直接读取操作的错误处理变得复杂。如果您不使用读取流的事件驱动特性或某些转换功能或流的其他一些主要功能,我不会使用它们 - 我会使用更传统的 fs.promises.readFile()
来读取数据。
- createReadStream(使用 Symbol.asyncIterator)
async function* readChunkIter(chunksAsync) {
for await (const chunk of chunksAsync) {
// magic
yield chunk;
}
}
const fileStream = fs.createReadStream(filePath, { highWaterMark: 1024 * 64 });
const readChunk = readChunkIter(fileStream);
- 读取同步
function* readChunkIter(fd) {
// loop
// magic
fs.readSync(fd, buffer, 0, chunkSize, bytesRead);
yield buffer;
}
const fd = fs.openSync(filePath, 'r');
const readChunk = readChunkIter(fd);
什么与生成器函数一起使用更好,为什么?
upd:我不是在寻找更好的方法,我想知道使用这些功能的区别
首先,您将同步文件操作 fs.readSync()
与流中的异步文件操作(内部使用 fs.read()
)进行比较。所以,这有点像服务器使用的苹果和橘子。
如果这是在服务器上,则永远不要使用同步文件 I/O 除了在服务器启动时,因为在处理请求或任何其他服务器事件时,同步文件 I/O 会阻塞整个事件循环文件读取操作大大降低了服务器的可扩展性。仅使用异步文件 I/O,在您的两种情况之间将是流。
否则,如果这不是在服务器上或任何关心在同步文件操作期间阻止 node.js 事件循环的进程,那么完全取决于您喜欢哪个界面。
其他评论:
还不清楚为什么要将
for await()
包装在生成器中。调用者可以自己使用for await()
并避免在生成器中包装。读取文件的流通常以事件驱动的方式使用,通过向
data
事件添加事件侦听器并在数据到达时响应数据。如果您只是要从文件中异步读取数据块,那么流实际上没有任何好处。您也可以只使用fs.read()
或fs.promises.read()
.如果不了解您尝试编码的整体问题,我们无法真正评论 best/better 解决问题的方法。您刚刚展示了一小段阅读数据。结构化的最佳方式取决于更高级别的代码如何最方便地 use/consume 数据(您不显示)。
I really didn't ask the right question. I'm not looking for a better way, I want to know the difference between using these features.
嗯,主要区别在于 fs.readSync()
是阻塞和同步的,因此会阻塞事件循环,破坏服务器的可伸缩性,永远不应在服务器环境中使用(启动代码期间除外)。 node.js 中的流是异步的,不会阻塞事件循环。
除此之外,流是一种比直接读取文件更高级别的构造,应该在您实际使用流的功能时使用,而在您只是从中读取块时可能不应该使用直接文件并且不使用流的任何功能。
特别是,对于流,错误处理并不总是那么清晰,尤其是在尝试使用 await
和 promises 时。这可能是因为 readstreams 最初被设计为事件驱动对象,这意味着在 error
事件上间接传达错误,这使得直接读取操作的错误处理变得复杂。如果您不使用读取流的事件驱动特性或某些转换功能或流的其他一些主要功能,我不会使用它们 - 我会使用更传统的 fs.promises.readFile()
来读取数据。