【问题标题】:Replacing fs.readFile with fs.createReadStream in Node.js在 Node.js 中用 fs.createReadStream 替换 fs.readFile
【发布时间】:2017-09-01 13:29:43
【问题描述】:

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

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

这是我得到的 (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

<!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 >

【问题讨论】:

标签: javascript node.js image express stream


【解决方案1】:

以下方法仅使用核心模块并从stream.Readable 实例中读取块,该实例从fs.createReadStream() 返回,并将这些块作为Buffer 返回。如果您不打算将块流回,这不是一种很好的方法。您将把文件保存在内存中的Buffer 中,因此它仅适用于大小合理的文件。

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 响应流示例

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

这是一个非常基本的示例,没有花里胡哨,只是为了演示如何将pipe()stream.Readable 转换为http.ServerResponse。该示例使用 Express,但使用来自 Node.js 核心 API 的 httphttps 的工作方式完全相同。

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}`);
});

【讨论】:

  • 感谢您回复我的问题并回答我的问题。
  • @AESTHETICS 用 HTTP 流示例更新了我的答案。
  • fs.createReadStream 在节点 12 中给我以下结果: Promise { _handler: Pending { consumer: undefined, receiver: undefined, handler: undefined, resolved: false } } 请在这里帮助我了解什么是这里错了
猜你喜欢
  • 2016-10-20
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 2015-04-10
  • 1970-01-01
  • 2012-03-15
相关资源
最近更新 更多