简体   繁体   English

Node.js-仅出于获取文件长度的目的将文件流保存到磁盘是否可以接受?

[英]Node.js - Is it acceptable to save a file stream to disk, solely for the purpose of getting the file length?

I have multiple Node.js servers running on my backend. 我在后端运行着多个Node.js服务器。 One is an API server, which can accept image files from a 3rd party. 一个是API服务器,它可以接受来自第三方的图像文件。 The image files are streamed to the stdin of an ImageMagick process, and then the stdout of the ImageMagick process is streamed to a Node.js TCP server where the file is ultimately saved locally. 图像文件将流式传输到ImageMagick进程的标准输入,然后将ImageMagick进程的标准输出流式传输到Node.js TCP服务器,最终将文件保存在本地。 The TCP server then needs to send a response to the API server after the file is successfully saved, so I need some way for the TCP server to know when it has the entire file (ie I can't simply close the socket on the API server after the file is sent). 文件成功保存后,TCP服务器随后需要向API服务器发送响应,因此我需要某种方式让TCP服务器知道何时具有整个文件(即,我不能简单地关闭API上的套接字文件发送后的服务器)。

One solution I could use is to save the stdout of the ImageMagick process to a temporary file on the API server, so I can get the length of the full file before I send it, and embed it in the beginning of the stream. 我可以使用的一种解决方案是将ImageMagick进程的标准输出保存到API服务器上的临时文件中,以便在发送前可以获取完整文件的长度,并将其嵌入流的开头。 Writing to disk throws a bit of a knot in the system though. 但是,写入磁盘会给系统带来一些麻烦。

Is it acceptable to write a temp file to disk for the purpose of getting the length of the file, or is there a better / more efficient way to solve this problem? 将临时文件写入磁盘以获取文件的长度是否可以接受,还是有更好/更有效的方法来解决此问题?

Thanks 谢谢

I do not know if this is relevant. 我不知道这是否相关。 But ImageMagick miff: format is a streaming format. 但是ImageMagick的miff:格式是流式格式。 So you can write the dimensions of the image to a text file while streaming it out again via miff:. 因此,您可以将图像的尺寸写入文本文件,同时通过miff:再次将其输出。

convert rose: miff:- | convert - -format "%wx%h" -write info:tmp.txt miff:-

Here I use convert rose: miff:- to simulate your input stream. 在这里,我使用convert rose: miff:-模拟您的输入流。

Then I pipe it to the next convert, which reads the input stream, writes the WxH information to a tmp.txt text file, which you could access subsequently. 然后,我将其传送到下一个转换,该转换将读取输入流,并将WxH信息写入tmp.txt文本文件,您可以随后访问该文件。 The second convert also creates a miff:- output stream. 第二个转换还创建一个miff:-输出流。

You could use NetPBM format in place of miff, since it also is a streaming format. 您可以使用NetPBM格式代替miff,因为它也是一种流格式。

In case anybody else with a similar problem stumbles upon this, I found an alternative solution, which avoids the need to specify the file size altogether. 万一遇到其他类似问题,我发现了另一种解决方案,避免了完全指定文件大小。

Create the TCP server using the {allowHalfOpen: true} option. 使用{allowHalfOpen:true}选项创建TCP服务器。 The client can send the file to the TCP server, and then simply call the "end" method on the socket to signify that no more data will be written by the client (the socket is still readable by the client). 客户端可以将文件发送到TCP服务器,然后只需在套接字上调用“ end”方法即可表示该客户端将不再写入任何数据(该套接字仍可供客户端读取)。 With the "allowHalfOpen" option set on the server, the server can simply listen for the "end" event (which signifies that all of the data has been received), with the writable side of the server still open (allowing the server to send a response back to the client). 通过在服务器上设置“ allowHalfOpen”选项,服务器可以简单地侦听“ end”事件(这表示已接收到所有数据),而服务器的可写侧仍处于打开状态(允许服务器发送)回复给客户)。

Note that the "allowHalfOpen" option defaults to false. 请注意,“ allowHalfOpen”选项默认为false。 If this option isn't set, the server automatically closes the socket when the writable side of the client is closed. 如果未设置此选项,则关闭客户端的可写端后,服务器会自动关闭套接字。

eg 例如

SERVER 服务器

const fs = require('fs');
const net = require('net');
const server = net.createServer({allowHalfOpen: true});

server.on('connection', (socket) => {
    const writeStream = fs.createWriteStream('myFile.png');

    socket.on('data', (chunk) => {
        writeStream.write(chunk);
    });

    socket.on('end', () => {
        writeStream.end();
        socket.end('File Written To Disk'); // send response and close socket
    });
});

server.listen(8000);

CLIENT 客户

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

const socket = net.connect(8000);

fs.createReadStream('myFile.png').pipe(socket);

socket.on('data', (chunk) => {
    // response from TCP server
    console.log(chunk.toString()); // File Written To Disk
});

socket.on('end', () => {
    // server closed socket
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM