在 Node.js 中用 fs.createReadStream 替换 fs.readFile [英] Replacing fs.readFile with fs.createReadStream in Node.js

查看:33
本文介绍了在 Node.js 中用 fs.createReadStream 替换 fs.readFile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

这是我得到的(index.js)

Here is what i got (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 >

推荐答案

下面的方法只使用核心模块并从 fs.createReadStream() 并将这些块作为 Buffer 返回.如果您不打算将块流回,这不是一种很好的方法.您将把文件保存在驻留在内存中的 Buffer 中,因此它是合理大小文件的唯一好解决方案.

The below approach only uses core modules and reads the chunks from the stream.Readable instance 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 Buffer which resides in memory, so its only a good solution for reasonably sized files.

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 流式传输数据几乎总是一个更好的主意,因为它内置于协议中,并且您永远不需要将数据一次全部加载到内存中,因为您可以管道() 直接响应文件流.

HTTP Response Stream Example

Its almost always a better idea to use HTTP for 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.

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

This is a very basic example without the bells and whistles and just is to demonstrate how to pipe() a stream.Readable to a http.ServerResponse. the example uses Express but it works the exact same way using http or https from the 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}`);
});

这篇关于在 Node.js 中用 fs.createReadStream 替换 fs.readFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆