Javascript 在 Node.js 中用 fs.createReadStream 替换 fs.readFile

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43256505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:47:12  来源:igfitidea点击:

Replacing fs.readFile with fs.createReadStream in Node.js

javascriptnode.jsimageexpressstream

提问by AESTHETICS

I have code for reading an image from directory and sending it to index.html.

我有从目录中读取图像并将其发送到 index.html 的代码。

I am trying to replace fs.readFile with fs.createReadStream but i have no idea how to implement this as i can not find a good example.

我正在尝试用 fs.createReadStream 替换 fs.readFile 但我不知道如何实现它,因为我找不到一个好的例子。

Here is what i got (index.js)

这是我得到的(index.js)

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

var fs = require('fs');

http.listen(3000, function () {
     console.log('listening on *:3000');
});
app.get('/', function (req, res) {
     res.sendFile(__dirname + '/public/views/index.html');
});
io.on('connection', function (socket) {
     fs.readFile(__dirname + '/public/images/image.png', function (err, buf){
        socket.emit('image', { image: true, buffer: buf.toString('base64') });
     });
});

index.html

索引.html

<!DOCTYPE html>
<html>
<body>

<canvas id="canvas" width="200" height="100">
    Your browser does not support the HTML5 canvas tag.
</canvas>

<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>

<script>
    var socket = io();
    var ctx = document.getElementById('canvas').getContext('2d');
    socket.on("image", function (info) {
        if (info.image) {
            var img = new Image();
            img.src = 'data:image/jpeg;base64,' + info.buffer;
            ctx.drawImage(img, 0, 0);
        }
    });
</script>
</body >
</html >

回答by peteb

The below approach only uses core modules and reads the chunks from the stream.Readableinstance returned from fs.createReadStream()and returns those chunks back as a Buffer. This isn't that great of an approach if you're not going to stream the chunks back. You're going to hold the file within a Bufferwhich resides in memory, so its only a good solution for reasonably sized files.

下面的方法只使用核心模块并从stream.Readable返回的实例中读取块fs.createReadStream()并将这些块作为Buffer. 如果您不打算将块流回,这不是一种很好的方法。您要将文件保存在Buffer驻留在内存中的a中,因此对于合理大小的文件来说,它只是一个很好的解决方案。

io.on('connection', function (socket) {
  fileToBuffer(__dirname + '/public/images/image.png', (err, imageBuffer) => {
    if (err) { 
      socket.emit('error', err)
    } else {
      socket.emit('image', { image: true, buffer: imageBuffer.toString('base64') }); 
    }
  });
});

const fileToBuffer = (filename, cb) => {
    let readStream = fs.createReadStream(filename);
    let chunks = [];

    // Handle any errors while reading
    readStream.on('error', err => {
        // handle error

        // File could not be read
        return cb(err);
    });

    // Listen for data
    readStream.on('data', chunk => {
        chunks.push(chunk);
    });

    // File is done being read
    readStream.on('close', () => {
        // Create a buffer of the image from the stream
        return cb(null, Buffer.concat(chunks));
    });
}

HTTP Response Stream Example

HTTP 响应流示例

Its almost always a better idea to use HTTPfor streaming data since its built into the protocol and you'd never need to load the data into memory all at once since you can pipe()the file stream directly to the response.

HTTP用于流数据几乎总是一个更好的主意,因为它内置在协议中,并且您永远不需要将数据一次全部加载到内存中,因为您可以pipe()将文件流直接发送到响应。

This is a very basic example without the bells and whistles and just is to demonstrate how to pipe()a stream.Readableto a http.ServerResponse. the example uses Express but it works the exact same way using httpor httpsfrom the Node.js Core API.

这是一个非常基本的例子,没有花里胡哨的东西,只是为了演示如何pipe()astream.Readable到 a http.ServerResponse。该示例使用 Express,但它的工作方式与使用httphttps来自 Node.js Core API 的方式完全相同。

const express = require('express');
const fs = require('fs');
const server = express();

const port = process.env.PORT || 1337;

server.get ('/image', (req, res) => {
    let readStream = fs.createReadStream(__dirname + '/public/images/image.png')

    // When the stream is done being read, end the response
    readStream.on('close', () => {
        res.end()
    })

    // Stream chunks to response
    readStream.pipe(res)
});

server.listen(port, () => {
    console.log(`Listening on ${port}`);
});