3
我想將多個文件一個接一個地串流到瀏覽器。爲了說明,請考慮將多個CSS文件連接爲一個。使用Node.js管道多個文件流
我使用的代碼是:
var directory = path.join(__dirname, 'css');
fs.readdir(directory, function (err, files) {
async.eachSeries(files, function (file, callback) {
if (!endsWith(file, '.css')) { return callback(); } // (1)
var currentFile = path.join(directory, file);
fs.stat(currentFile, function (err, stats) {
if (stats.isDirectory()) { return callback(); } // (2)
var stream = fs.createReadStream(currentFile).on('end', function() {
callback(); // (3)
});
stream.pipe(res, { end: false }); // (4)
});
}, function() {
res.end(); // (5)
});
});
的想法是,我
- 過濾掉不具有文件擴展名
.css
的所有文件。 - 過濾掉所有目錄。
- 一旦文件被完全讀取後繼續下一個文件。
- 將每個文件傳送到響應流而不關閉它。
- 一旦所有文件都被傳送完畢,結束響應流。
問題是隻有第一個.css
文件獲取管道,並且所有剩餘的文件都丟失。就好像(3)會在第一個(4)之後直接跳到(5)。
有趣的是,如果我有
stream.on('data', function (data) {
console.log(data.toString('utf8'));
});
一切替換線(4)按預期工作:我看到多個文件。如果我然後更改此代碼爲
stream.on('data', function (data) {
res.write(data.toString('utf8'));
});
所有文件希望第一個丟失了再次。
我在做什麼錯?
PS:錯誤發生在使用Node.js 0.8.7以及使用0.8.22。
var directory = path.join(__dirname, 'css');
fs.readdir(directory, function (err, files) {
var concatenated = '';
async.eachSeries(files, function (file, callback) {
if (!endsWith(file, '.css')) { return callback(); }
var currentFile = path.join(directory, file);
fs.stat(currentFile, function (err, stats) {
if (stats.isDirectory()) { return callback(); }
var stream = fs.createReadStream(currentFile).on('end', function() {
callback();
}).on('data', function (data) { concatenated += data.toString('utf8'); });
});
}, function() {
res.write(concatenated);
res.end();
});
});
但是:爲什麼
UPDATE
好了,它如果你改變了代碼如下工作?爲什麼我不能多次撥打res.write
而不是先總結所有的組塊,然後一次寫完所有的組塊?
什麼你拿出不是你因爲你實際上沒有管道,而是你正在緩衝,然後將緩衝區寫入輸出流。這也是你的另一個問題的答案:如果你真的將數據傳輸到輸出流,你不必擔心write(),只能調用一次。 您應該通過查看這些Streams 2示例找到一個管道解決方案:https://github.com/Floby。 特別是這一個: https://github.com/Floby/node-catstream – vanthome 2013-03-27 14:45:36
我知道我沒有管道,我已經寫了,但我找到了一個使用管道的解決方案。正如你從下面的答案中看到的那樣,問題不在代碼中,而是在單元測試中。 – 2013-03-27 19:04:15