我正在尝试使用NodeJS和Express通过HTTP传输二进制文件。该文件不是很大,但足够大,足以让我遇到麻烦(〜1.8 Mo)。
我正在使用fs.readFile(..)读取文件,然后使用内置的res.sendFile(..)函数发送文件。如果我执行curl命令并将其结果重定向到一个新文件,则原始文件的内容将完美地复制到服务器上,并且可以使用它。
但是,如果我使用NodeJs通过使用http模块和缓冲区来执行此操作,则仅写入文件的65.5 Ko。 我尝试使用curl-request模块,并将主体写入文件。它的工作效果略好一些,但仍然只将1.7 Mo复制到了新文件中,仍然不完整。
这是我用来发送文件的代码:
app.get('/global_model', (req, res, next) => {
res.sendFile(__dirname+'/global-model/weights.bin');
});
以及接收它的代码(使用http模块):
const options = {
hostname: host,
port: port,
path: '/global_model',
method: 'GET',
};
return new Promise((resolve, reject) => {
const req = http.request(options, (res) => {
res.on('data', (d) => {
let buffer = new Buffer(d, 'binary');
fs.writeFile(__dirname+'/loc-model/weights.bin', buffer, (err) => {
if(!err) {
resolve();
}
});
});
});
req.on('error', (error) => {
reject(error);
});
req.end();
});
并使用curl-request模块:
let curl = new (require('curl-request'))();
return new Promise(resolve => {
curl.get('http://localhost:33333/global_model')
.then(({statusCode, body, headers}) => {
fs.writeFile(__dirname+'/loc-model/weights.bin', body, {encoding:'binary'} , (err) => {
if(!err) {
resolve();
}
});
});
});
Wireshark显示在处理请求时没有损失。我对这个相对简单的任务有点迷茫。 我做错什么了吗?
编辑:我尝试在缓冲区上使用ReadStream,但仍然无法完全保存文件。
答案 0 :(得分:0)
您的代码会在每个新的数据块上重写文件,并在收到新数据后立即解析。
您需要将HTTP读取流通过管道传输到文件中-像这样(未经测试,YMMV)。
const options = {
hostname: host,
port: port,
path: "/global_model",
method: "GET",
};
return new Promise((resolve, reject) => {
const req = http.request(options, res => {
const outStream = fs.createWriteStream(__dirname + "/loc-model/weights.bin");
outStream.on("error", reject);
res.pipe(outStream);
res.on("end", () => {
outStream.close();
resolve();
});
});
req.on("error", reject);
});