我认为这里的问题是当你调用 savefile 时,它在数据被读取并保存到磁盘之前返回。
这意味着当您调用 fs.readFileSync 时,文件数据尚不存在。在文件出现之前可能需要几百毫秒。请记住 https.get 函数是不阻塞的(就像 Node.js 中的大多数 I/O 函数一样)。
因此,最好的方法是使用回调函数来指示我们何时完成,或者使用 Promise。我通常更喜欢后者,因为代码语法更清晰。
例如(带有承诺):
function savefileWithPromise(filename, url) {
return new Promise((resolve, reject) => {
// Create file and setup close handler.
const file = fs.createWriteStream(filename)
.on('close', () => resolve("File end"));
// Read data from url..the file.close handler will fire when the response has been piped to the file stream.
https.get(url, function(response) {
response.pipe(file);
});
});
}
app.post('/addfile', async function(req, res) {
var filename = req.body.filename;
var url = req.body.url;
console.log(`/addfile: Reading from url: ${url}, writing to file ${filename}...`);
await savefileWithPromise(filename, url);
// readFileSync returns a buffer.
let testFile = fs.readFileSync(filename);
console.log("File length: " + testFile.length + " byte(s).")
res.status(200).send("ok");
});
我们也可以用回调做同样的事情:
function savefileWithCallback(filename, url, callback) {
// Create file and setup close handler.
const file = fs.createWriteStream(filename)
.on('close', () => callback("File end"));
// Read data from url..
https.get(url, function(response) {
response.pipe(file);
});
}
app.post('/addfile', function(req, res) {
var filename = req.body.filename;
var url = req.body.url;
console.log(`/addfile: Reading from url: ${url}, writing to file ${filename}...`);
savefileWithCallback(filename, url, function() {
// readFileSync returns a buffer.
let testFile = fs.readFileSync(filename);
console.log("File length: " + testFile.length + " byte(s).")
res.status(200).send("ok");
});
});
然后将 url 数据简单地读取到缓冲区:
function readUrlDataToBuffer(url) {
return new Promise((resolve, reject) => {
https.get(url, function(response) {
const data = [];
response.on('data', function(chunk) {
data.push(chunk);
}).on('end', function() {
resolve(Buffer.concat(data));
})
}).on('error', function(err) {
reject(err);
});
});
}
app.post('/addfile', async function(req, res) {
try {
var url = req.body.url;
console.log(`/addfile: Reading from url: ${url}..`);
let buffer = await readUrlDataToBuffer(url);
console.log("Buffer length: " + buffer.length + " byte(s).");
res.send('ok');
} catch (error) {
res.status(500).send('An error occurred');
}
});