2013-03-05 1 views
3

NGinx 로그를 구문 분석하는 모듈을 만들었습니다. 이제는이를 사용하는 명령 도구를 작성하고 있습니다. 내 문제는 전체 디렉토리를 구문 분석 할 수 있도록 허용한다는 것입니다. 그 다음에 읽기 및 구문 분석 측면에서 문제가되지 않습니다. 왜냐하면 명령 줄 도구에서 qeueus가 읽기 및 구문 분석을 수행하는 풀을 가지고 있기 때문에 허용하고 있습니다. JSON 지금은 다른 형식으로 로그를 다시 작성 - 좋아, 내가 추격으로 잘라 버릴거야, 나는 모든 WriteStreams (wstreams [readFilePath] (내가 readFilePath를 사용하여 알고있는 참조를 유지 합니다이 작가 개체를 작성했습니다,이 찾아 볼 수있는 단지 키), 하고 모듈 노출 된 개체를 통해 모든 읽기 스트림의 글로벌 참조도있다 Parser.rstreams [readFilePath]Node.js WriteStream Unknown 인코딩 오류

는 A writeStream 데이터를 작성하려고
// creating a writer to handle the data buffering from the parser's readstreams 
writer = { 
wstreams: {}, 
append: function(data, wfile, rfile){ 
    console.log(JSON.stringify(this.wstreams[rfile])); 
    if(this.wstreams[rfile] 
     && (this.wstreams[rfile].write(data, wfile) == false) // <-- crashing here 
     && parser.rstreams[rfile] 
     && parser.rstreams[rfile].pause){ 
      console.log('Pausing: ' + rfile); 
      parser.rstreams[rfile].pause(); 
    } 
}, 
addStream: function(wfile, rfile){ 
    var wstream = fs.createWriteStream(wfile, {'flags': 'w', 'encoding':'utf8', 'mode': '0666'}); 
    console.log("stream added: " + wfile + " r: " + rfile); 
    this.wstreams[rfile] = wstream; 
    this.wstreams[rfile].on('drain', function(){ 
     if(parser.rstreams[rfile] 
      && parser.rstreams[rfile].readable 
      && parser.rstreams[rfile].resume){ 
       console.log('Drained: ' + rfile); 
       parser.rstreams[rfile].resume(); 
     } 
    }); 
    } 
} 

, 알 수없는 인코딩 예외를 던지고 있습니다. utf8을 기본값으로 사용하기 때문에 아무런 의미가 없습니다. 차 내가 옵션 인코딩을 통과하더라도,이 같은 일을 할 것입니다, 나는 UTF-8 및 ASCII

{"path":"/Users/akhoury/code/rk/ginx/bin/here.json","fd":8,"writable":true,"flags":"w","encoding":"utf8","mode":"0666","bytesWritten":0,"busy":false,"_queue":[],"_events":{}} 
[GINX][ERROR][uncaughtException] Error: Unknown encoding 
[GINX-DEBUG] Exiting - 0 {file:cursor} record(s) stored in /Users/akhoury/code/rk/ginx/tmp/stored.cursors 

/Users/akhoury/code/rk/ginx/lib/ginx.js:453 
throw err; 
    ^
Error: Unknown encoding 
at Buffer.write (buffer.js:382:13) 
at new Buffer (buffer.js:261:26) 
at WriteStream.write (fs.js:1548:12) 
at Object.writer.append (/Users/akhoury/code/rk/ginx/bin/ginx.js:95:38) 
at /Users/akhoury/code/rk/ginx/bin/ginx.js:152:16 
at Ginx.eval [as hardParseLine] (eval at generateParseLine (/Users/akhoury/code/rk/ginx/lib/ginx.js:59:21)) 
at streamData (/Users/akhoury/code/rk/ginx/lib/ginx.js:179:13) 
at Ginx.parseFile.fs.stat.stream.on.streamEnd.cursor (/Users/akhoury/code/rk/ginx/lib/ginx.js:346:28) 
at EventEmitter.emit (events.js:93:17) 
at ReadStream._emitData (fs.js:1365:10) 

I도 JSON.stringify 스트림이 그 안에 뭐가 있는지보고, ut8을 시도하고, 그것을 잘 보인다 .

나는 buffer.js의 소스를 쳐다 보면서 그것은 인코딩이 허용 목록 아무도 없을 때이 오류가 발생한다, 이해가되지 않습니다 https://github.com/joyent/node/blob/master/lib/buffer.js : 50의 다음

나는 읽을 루프가 디렉토리, 다음 write.addStream (OUTPUTFILE, inputfile을)에는 processFile 및 processDirectory에서 다음

if (stats.isDirectory()) { 
fs.mkdir(output, function() { 
    fs.readdir(input, function (err, files) { 
     if (err) error(err); 
     files.forEach(function (wfile) { 
      wfile = path.join(output, file); 
      rfile = path.join(input, file); 
      console.log("W:"+ wfile + " R: " + rfile); 
      //prepend the JSON openings for each new file before we go on. 
      if (isNewFile(rfile)) { 
       fs.writeFileSync(wfile, "{[", 'utf8'); 
      } 
      writer.addStream(wfile, rfile); // <-- adding the stream to writer here 
     }); 
     processDirectory(input, output); 
    }); 
}); 
} else if (stats.isFile()) { 
if (isNewFile(input)) { 
    fs.writeFile(output, "{[", 'utf8', function() { 
     writer.addStream(output, input); 
     processFile(input, output); 
    }); 
} else { 
    writer.addStream(output, input); 
    processFile(input, output); 
    } 
} 

은 매번 내가 라인이 구문 분석 된 의미 rowCallback을받을 경우 디렉토리, 나는 writer.append

를 사용 ,896,913,

}

// process directory parsing to JSON outputs 
function processDirectory(input, output) { 
parser.parseDir(input, 

function (err, row) { 
    if (err) error(err); 
    var fname = row.__fname; 
    writer.append(ifLastRow(row), path.join(output, fname), row.__file); 
}, 

function (err, rfile) { 
    if (err) error(err); 
    var wfile = path.join(output, rfile.substring(rfile.lastIndexOf(path.sep) + 1)); 
    //close the JSON array 
    writer.append("]}", wfile, rfile); 
}, 

function (err, filesCount) { 
    if (err) error(err); 
}); 
} 

사람이 내가 잘못 여기서 뭐하는 거지 볼 수 있을까요? 스트림을 잘못 만드는 중입니까?

나는 그것이 많이 읽는 것을 알고 있지만 나는 너무 일반적이되고 싶지 않았다. 감사합니다.

+2

이 읽을 수있는 코드를 많이입니다. 문제를 재현하는 코드 줄을 최소로 경화 할 수 있다면 좋을 것입니다. – Floby

+0

아, 죄송합니다. 모호한 부분을 원하지 않았습니다. 충돌하는 부분이 첫 번째 코드 블록에 있습니다. 이 행을 찾으십시오.'&& (this.wstreams [rfile].write (data, wfile) == false) // <- 여기에 충돌 함 ' – bentael

+0

실제로 여기서 무엇을하려고합니까? 기본적으로'rfile.pipe (wfile)'을 구현하는 것은 복잡한 기계처럼 보입니다. – isaacs

답변

5

두 번째 매개 변수로 파일 이름을 stream.write()으로 전달하지만 두 번째 매개 변수는 .write()으로 인코딩하는 것이 선택 인코딩입니다 (이전 링크 참조).

오류는 파일 이름을 인코딩으로 사용하려고 시도한 것이므로 Unknown encoding입니다. data이 버퍼 인 경우 버퍼를 기반으로 인코딩을 결정합니다.

쓰기 스트림은 파일에 연결되어 있으므로 각 쓰기시 파일 이름을 전달할 필요가 없습니다. 변경 시도 :

&& (this.wstreams[rfile].write(data, wfile) == false) 

에 :

&& (this.wstreams[rfile].write(data) == false)