Javascript 从另一台服务器读取Node.js中的大文件
我有两台相互通信的服务器。Server1从Server2请求部分文件,并将收到的数据存储到一个文件中。Server2应该接收这些请求中的每一个,并创建一个通过管道传输数据的流 假设存储在服务器2中的文件(目录)如下Javascript 从另一台服务器读取Node.js中的大文件,javascript,node.js,Javascript,Node.js,我有两台相互通信的服务器。Server1从Server2请求部分文件,并将收到的数据存储到一个文件中。Server2应该接收这些请求中的每一个,并创建一个通过管道传输数据的流 假设存储在服务器2中的文件(目录)如下 bigfile.gz bigfile.gz.part-0 bigfile.gz.part-1 bigfile.gz.part-2 ...... 因此,Server1将向Server2发送一个第0部分的请求,然后是第1部分,依此类推。因此,可以使用循环发出请求
bigfile.gz
bigfile.gz.part-0
bigfile.gz.part-1
bigfile.gz.part-2
......
因此,Server1将向Server2发送一个第0部分的请求,然后是第1部分,依此类推。因此,可以使用循环发出请求
服务器1(代码片段)
for (var i in requestInfo['blockName']) {
var blockName = i;
var IP = requestInfo['blockName'][i][0];
var fileData = JSON.stringify({
blockName: blockName,
fileName: requestInfo['fileName']
});
makeRequest(fileData, IP);
console.log(counter);
}
function makeRequest(fileData, IP) {
var options = {
host: IP,
port: 5000,
path: '/read',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
var req = http.request(options, function(res) {
var data = '';
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
console.log(data.length);
//fs.appendFileSync(fileName, data);
var writeStream = fs.createWriteStream(fileName, { "flags": 'a' });
writeStream.write(data);
writeStream.end();
});
});
req.write(fileData);
req.end();
}
服务器2(代码片段)
当我用一个100MB的txt文件测试它时,上面的一个是有效的。但是当我有1GB.gz文件时,或者甚至当我用一个.zip文件测试它时,它都会失败。在服务器1端生成的最终.zip文件的输出大小不正确
我不确定我在这里做错了什么,或者是替代解决方案
编辑:
另外,my Server1在处理大的1GB.gz文件时崩溃这里的主要问题是,您将
块添加到字符串中,从而将数据视为字符串
通过重写,这应该是
var req=http.request(选项、函数(res){
var数据=[];
res.on('data',函数(块){
数据推送(块);
});
res.on('end',function(){
fs.writeFile(文件名,Buffer.concat(数据),函数(){
console.log(“写入结束”)
});
});
});
这样我们就创建了一个大的二进制块数组,下载完成后,我们将所有块的串联写入一个文件
但是注意单词big
如果您坚持使用此实现,您将面临内存不足的风险,尤其是在处理大(>500mb)文件时
流式救援
var req=https.request(选项、函数(res){
res.pipe(fs.createWriteStream(fileName)).on(“关闭”,函数(){
console.log(“写入端”);
});
});
使用上述实现时,内存占用应保持较低。因为当您从下载中获得特定数量的数据时,您就将其写入文件。这样,您就不会将整个文件保存在程序内存中。您将所有内容视为文本-这就是为什么它适用于文本文件而不是二进制文件的原因!找到可能对你有帮助的。这也可能是您的答案。我遵循了您建议的链接,但我看到了这个错误TypeError:“list”参数必须是缓冲区数组,即使我正在传递array@Jamiec现在可以了,我正在设置res.setencoding(..)不需要这个。但是1GB的文件会使应用程序崩溃。您应该将响应直接流式传输到该文件,这样您就可以将内存消耗保持在原来的水平minimum@alex-rokabilis你能举个例子吗
app.post('/read', function(req, res) {
var dataBody = req.body;
fs.createReadStream(dataBody.fileName + '/' + dataBody.blockName).pipe(res);
});