12

大きなファイル (utf8) があります。fs.createReadStream大きなファイルを読み取るためにストリームを作成できることはわかっていますが、同期されていません。だから私は使用しようとしますfs.readSyncが、読み取りテキストはのように壊れています"迈�"

var fs = require('fs');
var util = require('util');
var textPath = __dirname + '/people-daily.txt';   
var fd = fs.openSync(textPath, "r");
var text = fs.readSync(fd, 4, 0, "utf8");
console.log(util.inspect(text, true, null));
4

5 に答える 5

12

大きなファイルの場合、readFileSyncファイル全体がメモリに読み込まれるため、不便な場合があります。別の同期アプローチは、 を繰り返し呼び出しreadSync、一度に小さなデータを読み取り、行が来るたびに処理することです。次のコードは、このアプローチを実装し、ファイル 'test.txt' から一度に 1 行ずつ同期的に処理します。

var fs = require('fs');
var filename = 'test.txt'

var fd = fs.openSync(filename, 'r');
var bufferSize = 1024;
var buffer = new Buffer(bufferSize);

var leftOver = '';
var read, line, idxStart, idx;
while ((read = fs.readSync(fd, buffer, 0, bufferSize, null)) !== 0) {
  leftOver += buffer.toString('utf8', 0, read);
  idxStart = 0
  while ((idx = leftOver.indexOf("\n", idxStart)) !== -1) {
    line = leftOver.substring(idxStart, idx);
    console.log("one line read: " + line);
    idxStart = idx + 1;
  }
  leftOver = leftOver.substring(idxStart);
}
于 2014-01-19T16:30:30.797 に答える
4

readFileSyncを使用します。

fs.readFileSync(filename, [encoding]) fs.readFile の同期バージョン。ファイル名の内容を返します。

エンコーディングが指定されている場合、この関数は文字列を返します。それ以外の場合は、バッファを返します。

ちなみに、ノードを使用しているので、非同期関数を使用することをお勧めします。

于 2011-09-25T11:17:17.780 に答える
2

バッファで split() を使用する、より単純なバージョンの JB Kohn の回答を作成しました。私が試したより大きなファイルで動作します。

/*
 * Synchronously call fn(text, lineNum) on each line read from file descriptor fd.
 */
function forEachLine (fd, fn) {
    var bufSize = 64 * 1024;
    var buf = new Buffer(bufSize);
    var leftOver = '';
    var lineNum = 0;
    var lines, n;

    while ((n = fs.readSync(fd, buf, 0, bufSize, null)) !== 0) {
        lines = buf.toString('utf8', 0 , n).split('\n');
        lines[0] = leftOver+lines[0];       // add leftover string from previous read
        while (lines.length > 1) {          // process all but the last line
            fn(lines.shift(), lineNum);
            lineNum++;
        }
        leftOver = lines.shift();           // save last line fragment (may be '')
    }
    if (leftOver) {                         // process any remaining line
        fn(leftOver, lineNum);
    }
}
于 2016-09-09T14:06:35.703 に答える
1

2 つの潜在的な問題

  1. スキップしなかった先頭の 3bytes BOM
  2. 最初の 4 バイトを UTF8 の文字に適切にフォーマットすることはできません (utf8 は固定長ではありません)。
于 2011-09-25T13:06:35.363 に答える