Java에서 메모리 매핑으로 큰 파일 구현 코드 처리

큰 파일을 처리할 때 일반적인 File Input Stream이나 File Output Stream 또는 RandomAccess File을 이용하여 빈번한 읽기와 쓰기를 하면 프로세스가 빈번한 읽기와 쓰기로 인해 속도를 떨어뜨릴 수 있습니다.다음은 비교 실험이다.

package test; 
 
import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 
import java.nio.MappedByteBuffer; 
import java.nio.channels.FileChannel; 
 
public class Test { 
 
   
  public static void main(String[] args) { 
    try { 
      FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt"); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      try { 
        while((n=fis.read())>=0){ 
          sum+=n; 
        } 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
     
    try { 
      FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt"); 
      BufferedInputStream bis=new BufferedInputStream(fis); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      try { 
        while((n=bis.read())>=0){ 
          sum+=n; 
        } 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
     
    MappedByteBuffer buffer=null; 
    try { 
      buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      for(int i=0;i<1253244;i++){ 
        n=0x000000ff&buffer.get(i); 
        sum+=n; 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
 
  } 
 
} 
테스트 파일은 1253244바이트 크기의 파일입니다.테스트 결과:
sum:220152087  time:1464
sum:220152087  time:72
sum:220152087  time:25
읽은 데이터가 틀림없음을 설명하다.그 중의 데이터 처리 부분을 삭제하다.

package test; 
 
import java.io.BufferedInputStream; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 
import java.nio.MappedByteBuffer; 
import java.nio.channels.FileChannel; 
 
public class Test { 
 
   
  public static void main(String[] args) { 
    try { 
      FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt"); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      try { 
        while((n=fis.read())>=0){ 
          //sum+=n; 
        } 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
     
    try { 
      FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt"); 
      BufferedInputStream bis=new BufferedInputStream(fis); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      try { 
        while((n=bis.read())>=0){ 
          //sum+=n; 
        } 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
     
    MappedByteBuffer buffer=null; 
    try { 
      buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244); 
      int sum=0; 
      int n; 
      long t1=System.currentTimeMillis(); 
      for(int i=0;i<1253244;i++){ 
        //n=0x000000ff&buffer.get(i); 
        //sum+=n; 
      } 
      long t=System.currentTimeMillis()-t1; 
      System.out.println("sum:"+sum+" time:"+t); 
    } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
 
  } 
 
} 
테스트 결과:
sum:0  time:1458
sum:0  time:67
sum:0  time:8
이를 통해 알 수 있듯이 파일 부분이나 전체를 메모리에 비추어 읽기와 쓰기를 하면 속도가 많이 높아진다.
이것은 메모리 맵 파일이 먼저 메모리에 저장된 파일을 연속 영역에 비추어 하나의 바이트 그룹으로 처리되고 읽기와 쓰기 작업은 메모리를 직접 조작한 다음에 메모리 영역을 메모리 파일에 다시 비추기 때문에 중간에 빈번한 외부 메모리를 읽기와 쓰기하는 시간을 절약하고 읽기와 쓰기 시간을 크게 낮출 수 있다.
이상의 이 자바에서 메모리로 큰 파일을 처리하는 실현 코드는 여러분에게 공유된 모든 내용입니다. 참고해 주시고 저희를 많이 사랑해 주시기 바랍니다.

좋은 웹페이지 즐겨찾기