2012-02-01 2 views
3

크기가 더 큰 파일이 있으면 처리 할 메모리가 있다고 가정 해보십시오. 당신은 회전 에있는 파일을 n 바이트를 읽고 싶습니다 및거대한 파일을 차단하지 않고 청크로 읽는 방법?

  • 가 다른 블록을
  • 패스를 읽을 스레드에
  • 패스를 블록을 읽는 과정에서 차단되지 스레드

다양한 성공을 거둔 다른 시도를했지만 항상 차단이 문제가 될 것 같습니다.

것은 비 차단 말에 액세스하는 방법을 A가 byte[]

답변

6

당신은 할 수의 예를 제공하십시오.

디스크가 데이터를 제공하기를 기다리는 동안 항상 블록이됩니다. 각 데이터 덩어리에 대한 작업이 많으면 두 번째 스레드를 사용하면 다음 스레드가 완료 될 때까지 대기하는 동안 첫 번째 스레드가 차단되는 동안 해당 스레드가 CPU 중심의 작업을 수행 할 수 있습니다.

하지만 상황과 같이 들리지는 않습니다.

가장 좋은 방법은 데이터를 가능한 한 큰 블록 (예 : 1MB 이상)으로 읽는 것입니다. 이렇게하면 커널에서 차단되는 시간을 최소화 할 수 있으며 디스크를 기다리는 시간을 단축 할 수 있습니다 (블록을 ​​연속적으로 읽는 경우). 당신이 I/O 및 CPU 계산을 수행하는 프로그램이있는 경우


여기에 평균 CPU 시간의 양이 걸리는 경우, 블로킹이 (어딘가에 프로그램에서) 불가피 TEH codez

ExecutorService exec = Executors.newFixedThreadPool(1); 

// use RandomAccessFile because it supports readFully() 
RandomAccessFile in = new RandomAccessFile("myfile.dat", "r"); 
in.seek(0L); 

while (in.getFilePointer() < in.length()) 
{ 
    int readSize = (int)Math.min(1000000, in.length() - in.getFilePointer()); 
    final byte[] data = new byte[readSize]; 
    in.readFully(data); 
    exec.execute(new Runnable() 
    { 
     public void run() 
     { 
      // do something with data 
     } 
    }); 
} 
+0

오른쪽. 한 번에 1M을 읽으라고 말합니다. 내가 그것을 읽은 후에 (그리고 바이트 []라고 말하면서) 다른 스레드로 넘겨주고 싶습니다 ** ** 전에 또 다른 1M을 읽습니다. – JAM

+0

그리고이 문제는 무엇입니까? – parsifal

+1

'while (뭐든간에) {byte [] chunk = 새 바이트 [1 << 10]; myInputStream.read (청크); executorService.submit (theTaskUsing (청크)); }' –

0

입니다 바이트를 처리하는 것은 바이트를 읽는 시간보다 적습니다.

파일을 읽으려고하는데 디스크 탐색이 필요한 경우 데이터가 10ms 동안 도착하지 않을 수 있습니다. 2GHz CPU는 그 시간에 20M 클럭주기의 작업을 수행 할 수있었습니다.

1

스트림, 버퍼링 또는 두 가지 조합 (BufferedInputStream anyone?)을 찾는 것처럼 들립니다.

확인이 아웃 : http://docs.oracle.com/javase/tutorial/essential/io/buffers.html

이 매우 큰 파일을 처리 할 수있는 표준 방법입니다. 나는 이것이 당신이 찾고 있던 것이 아니라면 사과드립니다. 그러나 어쨌든 주스가 흐르도록 도와 주길 바랍니다.

행운을 빈다.

관련 문제