2013-06-20 2 views
2

Chrome을 사용하여 로컬 디스크에서 큰 (> 4GB) 이진 파일을 읽고 처리하려고합니다. FileReader API는 전체 파일을 읽는 것처럼 보이지만 파일을 점진적으로 스트림으로 읽을 수 있어야합니다.자바 스크립트에서 점진적으로 이진 파일 읽기

이 파일에는 1 바이트 유형 식별자, 2 바이트 프레임 길이, 8 바이트 시간 소인 및 형식을 기반으로하는 형식의 일부 이진 데이터가 들어있는 일련의 프레임이 들어 있습니다. 이 프레임의 콘텐츠가 누적 될 것이며 HTML5 + JavaScript를 사용하여 그래프를 생성하고이 파일의 내용을 기반으로 실시간 재생으로 다른 메트릭을 표시하려고합니다.

아무도 아이디어가 있습니까?

답변

4

실제로 파일은 Blob이며 BLOB에는 슬라이스 메서드가 있습니다.이 메서드를 사용하여 작은 파일의 큰 파일을 잡을 수 있습니다.

나는 지난 주 큰 로그 파일을 필터링하기 위해 snip을 작성했지만 큰 파일을 통해 sub-section-by-section을 반복 할 때 사용할 수있는 패턴을 보여줍니다.

  1. 파일 fnLineFilter 파일의 하나 개의 라인을 수용하고
  2. fnComplete 수집 된 라인 어레이로 전달되는 콜백이다 그것을 유지 true를 반환하는 함수이다
  3. 파일 오브젝트를이다
당신은 라인 findi 제거 할 수 분명히

function fileFilter(file, fnLineFilter, fnComplete) { 
    var bPos = 0, 
     mx = file.size, 
     BUFF_SIZE = 262144, 
     i = 0, 
     collection = [], 
     lineCount = 0; 
    var d1 = +new Date; 
    var remainder = ""; 

    function grabNextChunk() { 

     var myBlob = file.slice(BUFF_SIZE * i, (BUFF_SIZE * i) + BUFF_SIZE, file.type); 
     i++; 

     var fr = new FileReader(); 

     fr.onload = function(e) { 

      //run line filter: 
      var str = remainder + e.target.result, 
       o = str, 
       r = str.split(/\r?\n/); 
      remainder = r.slice(-1)[0]; 
      r.pop(); 
      lineCount += r.length; 

      var rez = r.map(fnLineFilter).filter(Boolean); 
      if (rez.length) { 
       [].push.apply(collection, rez); 
      } /* end if */ 

      if ((BUFF_SIZE * i) > mx) { 
       fnComplete(collection); 
       console.log("filtered " + file.name + " in " + (+new Date() - d1) + "ms "); 
      } /* end if((BUFF_SIZE * i) > mx) */ 
      else { 
       setTimeout(grabNextChunk, 0); 
      } 

     }; 
     fr.readAsText(myBlob, myBlob.type); 
    } /* end grabNextChunk() */ 

    grabNextChunk(); 
} /* end fileFilter() */ 

: 여기

내가 사용하는 코드입니다 아니, 그냥 대신 순수한 범위를 잡아라. 어떤 유형의 데이터를 파헤쳐야하는지 잘 모르겠다. 중요한 것은 슬라이스 매커니즘이다. 위의 텍스트 중심 코드에서 잘 설명되어있다.

+0

챔피언처럼 작동합니다. 감사!! – Krum