web-dev-qa-db-fra.com

Remplacement de fs.readFile par fs.createReadStream dans Node.js

J'ai un code pour lire une image d'un répertoire et l'envoyer à index.html.

J'essaie de remplacer fs.readFile par fs.createReadStream mais je n'ai aucune idée de la façon de la mettre en œuvre car je ne trouve pas un bon exemple.

Voici ce que j'ai obtenu (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 >
14
AESTHETICS

L'approche ci-dessous utilise uniquement les modules de base et lit les fragments de l'instance stream.Readable Renvoyée par fs.createReadStream(), puis les renvoie sous la forme d'un Buffer. Ce n’est pas une très bonne approche si vous ne voulez pas rediffuser les morceaux. Vous allez placer le fichier dans un Buffer qui réside dans la mémoire, ce n'est donc qu'une bonne solution pour les fichiers de taille raisonnable.

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

Exemple de flux de réponse HTTP

C’est presque toujours une meilleure idée d’utiliser HTTP pour la transmission en continu des données car elle est intégrée au protocole et vous n’aurez jamais besoin de charger toutes les données en mémoire en même temps puisque vous pouvez pipe() le fichier. diffuser directement à la réponse.

Ceci est un exemple très basique sans les cloches et les sifflets et est juste pour montrer comment pipe() un stream.Readable À un http.ServerResponse. L'exemple utilise Express, mais il fonctionne exactement de la même manière en utilisant http ou https à partir de l'API Node.js Core.

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