Nodejs 求个http合并文件服务的栗子

Nodejs 求个http合并文件服务的栗子

var http = require(‘http’);
var fs = require(‘fs’);
http.createServer(function (req, res) {
var mergefile = ‘’;
fs.readFile(‘a.txt’,function(err, data){
mergefile += data;
});
fs.readFile(‘b.txt’,function(err, data){
mergefile += data;
});
res.writeHead(200, {‘Content-Type’: ‘text/plain’});
res.end(mergefile);
}).listen(1337, ‘127.0.0.1’);
console.log(‘Server running at http://127.0.0.1:1337/’);

如上错误代码所示,我希望http服务器接受请求的时候读取合并a.txt和b.txt两个文件内容返回。

但是这个代码不对,我初学nodejs,希望各位能给个好示例。


8 回复

当然可以!你提供的代码有几个问题。首先,fs.readFile 是异步操作,这意味着在调用 res.end(mergefile) 之前,文件可能还没有被读取完毕。其次,你需要确保两个文件都读取完成后才发送响应。

下面是修正后的代码示例:

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
    // 使用 Promise 来处理异步操作
    Promise.all([
        new Promise((resolve, reject) => {
            fs.readFile('a.txt', function (err, data) {
                if (err) return reject(err);
                resolve(data);
            });
        }),
        new Promise((resolve, reject) => {
            fs.readFile('b.txt', function (err, data) {
                if (err) return reject(err);
                resolve(data);
            });
        })
    ]).then(([dataA, dataB]) => {
        // 合并文件内容
        const mergefile = Buffer.concat([dataA, dataB]);
        
        // 发送响应
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end(mergefile);
    }).catch(err => {
        // 错误处理
        console.error(err);
        res.writeHead(500, {'Content-Type': 'text/plain'});
        res.end('Internal Server Error');
    });
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

解释

  1. Promise.all: 这个方法用于处理多个异步操作。它接收一个 Promise 数组,并在所有 Promise 都成功完成时返回一个包含所有结果的数组。

  2. fs.readFile: 我们使用 fs.readFile 读取文件内容。为了确保它们在发送响应之前都被读取完毕,我们将每个 fs.readFile 包装在一个 Promise 中。

  3. Buffer.concat: 当两个文件都读取完毕后,我们使用 Buffer.concat 将它们的内容合并成一个新的 Buffer 对象。

  4. 错误处理: 如果任何文件读取失败,Promise.all 会捕获到错误并进入 .catch 回调函数,然后发送一个 500 错误响应。

这样,当客户端请求这个 HTTP 服务时,它将接收到 a.txtb.txt 的合并内容。希望这对你有所帮助!


其实我想说 LZ看看API就知道了啊。不要寄望别人直接写给你。

同意楼上的,node是基于事件循环的异步,你这个还没读到文件,就直接res.end了,结果会是空。修改下代码就OK了: var http = require(‘http’); var fs = require(‘fs’); http.createServer(function(req, res) { var mergefile = ‘’; fs.readFile(‘a.txt’, function(err, data) { mergefile += data; fs.readFile(‘b.txt’, function(err, data) { mergefile += data; res.writeHead(200, { ‘Content-Type’: ‘text/plain’ }); res.end(mergefile); }); }); }).listen(1337, ‘127.0.0.1’); console.log(‘Server running at http://127.0.0.1:1337/’);

异步,异步,回调,回调,我就这么坑过来的…………

这种事情,用echo命令才是王道

用async。。。

var http = require('http');
var fs = require('fs');

http.createServer(function(req, res) {
  var src1 = fs.createReadStream('./a.txt');
  var src2 = fs.createReadStream('./b.txt');
  src1.pipe(res);
  src2.pipe(res);
}).listen(5000);

你当前的代码存在一些问题,主要在于文件读取是异步操作,而你的代码没有等待这些操作完成就直接结束了请求处理。你可以使用Promise或者async/await来解决这个问题。下面是一个改进后的示例代码:

const http = require('http');
const fs = require('fs').promises; // 使用 fs.promises 来支持 async/await

http.createServer(async function (req, res) {
    try {
        const [dataA, dataB] = await Promise.all([
            fs.readFile('a.txt', 'utf-8'), // 读取文件并指定编码为 utf-8
            fs.readFile('b.txt', 'utf-8')
        ]);
        
        const mergedData = dataA + dataB; // 合并文件内容
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(mergedData);
    } catch (err) {
        console.error(err);
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('Internal Server Error');
    }
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

解释:

  1. fs.promises:使用fs.promises模块来支持async/await语法。
  2. Promise.all:同时读取两个文件,并使用Promise.all确保所有文件读取完成后才继续执行。
  3. 异步处理:使用async/await语法处理异步操作,确保文件读取完成后再合并内容并返回响应。

这样可以确保在发送响应之前,文件读取操作已经完成,避免了数据丢失或未完全加载的问题。

回到顶部