在Node.js的通过HTTP发送大量的图像数据(Sending large image data

2019-07-20 07:46发布

在我的开发环境我有两台服务器。 一个在发送和图像到另一POST HTTP请求。

客户端服务器执行此操作:

    fs.readFile(rawFile.path,'binary',function (err, file){
        restler.post("http://0.0.0.0:5000",{
            data: file,
            headers:{
                "Content-Type": rawFile.type,
            }
        }).on('complete',function(data,response){                               
            console.log(data);
            res.send("file went through")
        })

是临危请求服务器执行此操作:

    server.post('/',function(req,res,next){
        fs.writeFileSync("test.png",req.body,"binary",function(err){
            if(err) throw err;
            res.send("OK")
        })
    })

如果我送一个小图像,它工作正常。 然而,如果我发送大量图像虽然该文件被正确保存仅显示图像的第一上部。 其余部分为黑色。 图像尺寸是正确的。

我想这只是就是BEING上的文件写入的图像的第一块。 我试图创建一个readStreamwriteStream但它似乎不工作:

req.body.pipe(fs.createWriteStream('test.png'))

我可以直接从二进制数据和流pipe成什么文件? 对于我所看到的, readStream经常被用来从文件而不是原始的二进制数据流式传输。

我读了几岗位秒,但它似乎并没有为我工作。

我使用restler模块中的客户端服务器和restify在其他。

谢谢!

Answer 1:

对不起,是生硬的,但有很多错在这里。

readFile调用回调,指向你开始上传文件,在这之前读取文件的全部内容复制到内存中。

这是不好的,尤其是对于大型文件处理类似图像时,因为实在没有理由文件读入到内存中。 这是浪费; 和负载下,你会发现,你的服务器将运行内存不足和崩溃。

相反,你希望得到一个 ,因为他们从磁盘读取发射的数据块。 所有你需要做的就是通过这些块一起上传流( pipe ),再从内存中删除这些数据。 通过这种方式,您仅仅使用缓冲存储器少量多。

(A可读流的默认行为是处理原始的二进制数据,如果你传递一个它的唯一encoding ,它在文本中的交易。)

该请求模块使得该特别容易:

fs.createReadStream('test.png').pipe(request.post('http://0.0.0.0:5000/'));

在服务器上,你有一个更大的问题。 切勿使用* Sync的方法。 它会阻止从做任何事情 (如响应其他请求),直到整个文件服务器刷新到磁盘,这可能需要秒钟。

因此,相反,我们要采取的输入数据流和管道到一个文件系统的数据流。 你原本是在正确的轨道上; 其原因req.body.pipe(fs.createWriteStream('test.png'))没有工作是因为body是不是甲流。

body通过所产生的bodyParser中间件。 在的RESTify,中间件的作用很像readFile在于它在存储器缓冲器整个传入请求的实体。 在这种情况下,我们不希望出现这种情况。 禁用身体解析器的中间件。

那么,是输入数据流? 它是req对象本身。 的RESTify的Request继承节点的http.IncomingMessage ,这是一个可读流。 所以:

fs.createWriteStream('test.png').pipe(req);

我还要提到的是这一切工作原理非常简单,因为没有形式解析开销参与。 请求简单地发送不带该文件multipart/form-data包装:

POST / HTTP/1.1
host: localhost:5000
content-type: application/octet-stream
Connection: keep-alive
Transfer-Encoding: chunked

<image data>...

这意味着浏览器无法发布一个文件,这个URL。 如果这是一种需要,在看向强大的 ,它不流媒体请求的实体的解析。



Answer 2:

我不知道很多关于restler。 但张贴的图像是一个多请求。

restler.post("http://0.0.0.0:5000",{
    data: restler.file(path, filename, fileSize, encoding, contentType),
    multipart: true
})


Answer 3:

我试过上述解决方案,如果你刚刚移动上传的文件或东西以下的效果要好得多:

fs.rename(path, newPath, callback(err) {});

我上传超过200MB的文件,并会遇到使用流,同步或异步错误。



文章来源: Sending large image data over HTTP in Node.js