2012-11-02 6 views
3

파일이 들어있는 디렉토리를 열어야합니다. 각각에 대해 readstream을 열고 모든 파일의 데이터를 단일 파일에 씁니다. 하지만 난 계속 오류 : EMFILE, 열 '청크/piece96.data'Nodejs 오류 : EMFILE

내 ulimit는 256이고 나는 그것을 1024로 증가 시켰습니다. 나는 하나의 파일을 열고, 읽고 쓸 수있는 127 개의 파일을 가지고 있습니다.

내 코드는 내가 EMI 파일 오류를 방지 할 수 있습니까



    var DIR='chunks/'; 
    var files=fs.readdirSync(DIR); 
    var filename='bach.mp3'; 

    files.forEach(function(singlebit){ 
     //console.log(files); 
     var bit=fs.createReadStream(DIR+singlebit); 
     var resultfile=fs.createWriteStream(filename,{ 
      flags:'r+', 
      encoding:null, 
      mode:0666 
     }); 
     bit.on('data',function(bitdata){ 
       resultfile.write(bitdata); 
       console.log(bitdata); 
      }).on('end',function(){ 
       resultfile.end(); 
      }); 
     }); 
    console.log('file complete'); 

이하입니다. readdirSync를 사용하고 한 번에 모든 파일을 열지 않기 때문에 많은 파일을 한 번에 열지 않습니다. 모든 파일을 읽고 단일 파일에 쓰는 방법이 필요합니다.

+1

귀하의 .forEach 각 파일에 대한 함수를 만듭니다 귀하의 디렉토리에. 각 파일에 대해 최소한 2 개의 파일 핸들을 사용하고 그 아래에 사용중인 노드를 사용합니다. 어쨌든, 그 많은 파일들과 함께, 당신은'async'와 같은 것을 사용하여 동시 행동을 제한하고 싶을지도 모릅니다. – Joe

+1

write stream을 sync로 변경했습니다. 그것으로 해결되었습니다. –

+0

@GokulKav 당신은 나의 하루를 저장합니다. 고맙습니다! – shaosh

답변

3

난 그냥, 내가 스트림을 사용하지 않는이 문제를 스스로 해결하기 위해 코드의 작은 조각을 작성 완료 그러나 이것은 여러분의 필요에 적응해야한다 :

// Queuing reads and writes, so your nodejs script doesn't overwhelm system limits catastrophically 
global.maxFilesInFlight = 100; // Set this value to some number safeish for your system 
var origRead = fs.readFile; 
var origWrite = fs.writeFile; 

var activeCount = 0; 
var pending = []; 

var wrapCallback = function(cb){ 
    return function(){ 
     activeCount--; 
     cb.apply(this,Array.prototype.slice.call(arguments)); 
     if (activeCount < global.maxFilesInFlight && pending.length){ 
      console.log("Processing Pending read/write"); 
      pending.shift()(); 
     } 
    }; 
}; 
fs.readFile = function(){ 
    var args = Array.prototype.slice.call(arguments); 
    if (activeCount < global.maxFilesInFlight){ 
     if (args[1] instanceof Function){ 
      args[1] = wrapCallback(args[1]); 
     } else if (args[2] instanceof Function) { 
      args[2] = wrapCallback(args[2]); 
     } 
     activeCount++; 
     origRead.apply(fs,args); 
    } else { 
     console.log("Delaying read:",args[0]); 
     pending.push(function(){ 
      fs.readFile.apply(fs,args); 
     }); 
    } 
}; 

fs.writeFile = function(){ 
    var args = Array.prototype.slice.call(arguments); 
    if (activeCount < global.maxFilesInFlight){ 
     if (args[1] instanceof Function){ 
      args[1] = wrapCallback(args[1]); 
     } else if (args[2] instanceof Function) { 
      args[2] = wrapCallback(args[2]); 
     } 
     activeCount++; 
     origWrite.apply(fs,args); 
    } else { 
     console.log("Delaying write:",args[0]); 
     pending.push(function(){ 
      fs.writeFile.apply(fs,args); 
     }); 
    } 
}; 
+0

왜이 오류가 발생합니까? 이 문제를 해결하는 더 쉬운 방법은 없을까요? – yas4891

+2

모든 운영 체제는 임의의 프로세스에서 동시에 열 수있는 파일 핸들 수를 제한합니다. OSX는 기본 한계를 조금 떨어 뜨 렸지만 실제 상황은 nodejs가 많은 병렬 작업을 쉽게 쌓을 수있게 만든다. 디렉토리 트리를 탐색하고 모든 파일을 간단하게 처리하는 단순한 로직을 사용하면 실제로 디스크 I/O 시간보다 훨씬 짧은 시간이 걸리는 코드를 실제로 그 한계까지 실행합니다. 효과적으로 음악 라이브러리를 처리하면 잠시 후에 운영 체제에 수천 개의 파일을 열어 모든 것을 녹일 수 있습니다. – fbartho