如何在nodejs中读取和打开两个不同的文件?
How to read and open two different files in nodejs?
我在这段代码中观察到我们在读取文件后无法打开文件。
电脑报错Error [ERR_STREAM_WRITE_AFTER_END]: write after end
当然,如果我删除 readFile
函数,那么这个错误就会消失,但我想了解为什么会出现这个错误,即使我使用两个不同的文件来读取和打开。
读取和打开两个不同文件的方法是什么?
var objHttp = require('http');
var objFS = require('fs');
objHttp.createServer(function(argClientRequest, argResult) {
objFS.readFile('z.html',
function(argError, argData) {
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
argResult.end();
}
);
objFS.open('mynewfile1.txt', 'r', (argErr, argFD) => {
if (argErr) throw argErr;
objFS.readFile('mynewfile1.txt',
function(argError, argData) {
if (argError) throw argError;
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
return argResult.end();
}
);
objFS.close(argFD, (argErr) => {
if (argErr) throw argErr;
});
});
}).listen(8080);
问题是 argResult.end();
这在读取 z.html
后立即返回,当读取 mynewfile1.txt
时,headers 已经发送给客户端。您正在尝试再次发送,这在技术上是不可能的。您只需发送一次回复。
argResult
是一个流。在第一个 objFS.readFile
调用中,您正在结束 argResult
流,然后您再次尝试在第二个 objFS.readFile
调用中写入 argResult
流。这就是您收到错误的原因。
问题不在于文件访问。如果您删除 http 侦听器和 运行 代码,那么您将不会在控制台中看到任何错误。
您正在使用 argResult.end();两次。您不能发送两次响应。
对于此问题,您需要使用承诺读取文件并在回调后解决它们。您可以使用
Promise.All([promise1,promise2]).then((data)=>{
argResult.end();
})
此处 promise1 是第一个文件 reader,promise2 是第二个文件 reader
然后在两个承诺都解决后发回响应
var objHttp = require('http');
var objFS = require('fs');
function firstReader(argResult){
return new Promise(function(resolve,reject){
objFS.readFile("z.html",
function(argError, argData) {
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
}
);
})
}
function secondReader(argResult){
return new Promise(function(resolve,reject){
objFS.open('mynewfile1.txt', 'r', (argErr, argFD) => {
if (argErr) throw argErr;
objFS.readFile('mynewfile1.txt',
function(argError, argData) {
if (argError) reject();
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
}
);
objFS.close(argFD, (argErr) => {
if (argErr) reject();
});
});
})
}
objHttp.createServer(function(argClientRequest, argResult) {
Promise.all([firstReader(argResult),secondReader(argResult)]).then(function(){
argResult.end();
}).catch(function(){
argResult.end();
})
}).listen(8080);
我在这段代码中观察到我们在读取文件后无法打开文件。
电脑报错Error [ERR_STREAM_WRITE_AFTER_END]: write after end
当然,如果我删除 readFile
函数,那么这个错误就会消失,但我想了解为什么会出现这个错误,即使我使用两个不同的文件来读取和打开。
读取和打开两个不同文件的方法是什么?
var objHttp = require('http');
var objFS = require('fs');
objHttp.createServer(function(argClientRequest, argResult) {
objFS.readFile('z.html',
function(argError, argData) {
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
argResult.end();
}
);
objFS.open('mynewfile1.txt', 'r', (argErr, argFD) => {
if (argErr) throw argErr;
objFS.readFile('mynewfile1.txt',
function(argError, argData) {
if (argError) throw argError;
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
return argResult.end();
}
);
objFS.close(argFD, (argErr) => {
if (argErr) throw argErr;
});
});
}).listen(8080);
问题是 argResult.end();
这在读取 z.html
后立即返回,当读取 mynewfile1.txt
时,headers 已经发送给客户端。您正在尝试再次发送,这在技术上是不可能的。您只需发送一次回复。
argResult
是一个流。在第一个 objFS.readFile
调用中,您正在结束 argResult
流,然后您再次尝试在第二个 objFS.readFile
调用中写入 argResult
流。这就是您收到错误的原因。
问题不在于文件访问。如果您删除 http 侦听器和 运行 代码,那么您将不会在控制台中看到任何错误。
您正在使用 argResult.end();两次。您不能发送两次响应。 对于此问题,您需要使用承诺读取文件并在回调后解决它们。您可以使用
Promise.All([promise1,promise2]).then((data)=>{
argResult.end();
})
此处 promise1 是第一个文件 reader,promise2 是第二个文件 reader
然后在两个承诺都解决后发回响应
var objHttp = require('http');
var objFS = require('fs');
function firstReader(argResult){
return new Promise(function(resolve,reject){
objFS.readFile("z.html",
function(argError, argData) {
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
}
);
})
}
function secondReader(argResult){
return new Promise(function(resolve,reject){
objFS.open('mynewfile1.txt', 'r', (argErr, argFD) => {
if (argErr) throw argErr;
objFS.readFile('mynewfile1.txt',
function(argError, argData) {
if (argError) reject();
argResult.writeHead(200, {
'Content-Type': 'text/html'
});
argResult.write(argData);
}
);
objFS.close(argFD, (argErr) => {
if (argErr) reject();
});
});
})
}
objHttp.createServer(function(argClientRequest, argResult) {
Promise.all([firstReader(argResult),secondReader(argResult)]).then(function(){
argResult.end();
}).catch(function(){
argResult.end();
})
}).listen(8080);