文件读取和流式传输有什么区别?

what is difference between file reading and streaming?

我在 node.js 的一些书中读到使用流式传输比一次读取整个文件更好,我理解这个想法..但我想知道是不是不要使用流读取文件,我从 Java 和 C++ 就习惯了这个,当我想读取文件时我使用流 .. 那么这里有什么区别? fs.createReadStream(<somefile>);fs.readFile(<somefile>); 之间有什么区别 两者都是异步的,对吧!!

So what's the difference here ?? also what is the difference between fs.createReadStream(<somefile>); and fs.readFile(<somefile>); both are asynchronous, right !!

除了 fs.createReadStream() 直接 returns 一个 stream 对象,而 fs.readFile() 期望在第二个参数中有一个回调函数,还有另一个巨大的区别.

是的,它们都是异步的,但这不会改变 fs.readFile() 在整个文件缓冲到内存中之前不会给您任何数据的事实。当通过服务器响应中继回数据时,这会降低内存效率并且速度变慢。使用 fs.createReadStream(),您可以 pipe() stream 对象直接到服务器的 response 对象,这意味着您的客户端可以立即开始接收数据,即使文件是 500MB。

不仅如此,您还可以通过一次处理一个块而不是一次处理所有文件来提高内存效率。这意味着您的内存一次只需要缓冲几千字节的 file 内容,而不是一次缓冲所有内容。

这里有两个片段可以证明我在说什么:

const fs = require('fs');
const http = require('http');

// using readFile()
http.createServer(function (req, res) {
    // let's pretend this is a huge 500MB zip file
    fs.readFile('some/file/path.zip', function (err, data) {
        // entire file must be buffered in memory to data, which could be very slow
        // entire chunk is sent at once, no streaming here
        res.write(data);
        res.end();
    });
});

// using createReadStream()
http.createServer(function (req, res) {
    // processes the large file in chunks
    // sending them to client as soon as they're ready
    fs.createReadStream('some/file/path.zip').pipe(res);
    // this is more memory-efficient and responsive
});

首先,fileread 是完全缓冲的方法。流式传输是部分缓冲方法。

现在这是什么意思?

完全缓冲的函数调用,如 readFileSync() 和 readFile() 公开 数据作为一个大斑点。也就是说,先执行读取,然后以同步或异步方式 return 编辑完整的数据集。 使用这些完全缓冲的方法,我们必须等到所有数据都被读取,并且 Node 内部将需要分配足够的内存来将所有数据存储在内存中。这可能会有问题 - 想象一个从磁盘读取 1 GB 文件的应用程序。只有完全缓冲的访问,我们需要使用 1 GB 的内存来存储文件的全部内容以供读取 - 因为 readFile 和 readFileSync return 一个包含所有数据的字符串。

部分缓冲访问方式不同。它们不将数据输入视为离散事件,而是将其视为在读取或写入数据时发生的一系列事件。它们允许我们访问从 disk/network/other I/O.

读取的数据

流 return 较小的数据部分(使用缓冲区),并在有新数据可供处理时触发回调。

流是事件发射器。例如,如果我们的 1 GB 文件需要以某种方式处理一次,我们可以使用流并在读取数据后立即处理数据。这很有用,因为我们不需要将内存中的所有数据保存在某个缓冲区中:处理后,对于此类应用程序,我们不再需要将数据保存在内存中。

Node流接口由两部分组成:Readable streams和Writable streams。一些流是可读可写的。