대용량 파일을 처리할 때 일반적인 FileInputStream이나 FileOutputStream 또는 RandomAccessFile을 사용하여 빈번한 읽기 및 쓰기 작업을 수행하면 외부 메모리를 자주 읽고 쓰기 때문에 프로세스 속도가 느려지는 현상이 발생합니다.
다음과 같이 코드 코드를 복사합니다.
패키지 테스트;
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;
공개 클래스 테스트 {
공개 정적 무효 메인(String[] args) {
노력하다 {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
노력하다 {
while((n=fis.read())>=0){
합+=n;
}
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
노력하다 {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
노력하다 {
while((n=bis.read())>=0){
합+=n;
}
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
MappedByteBuffer 버퍼=null;
노력하다 {
buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
for(int i=0;i<1253244;i++){
n=0x000000ff&buffer.get(i);
합+=n;
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
}
}
테스트 파일은 1253244바이트 크기의 파일이다. 테스트 결과:
다음과 같이 코드 코드를 복사합니다.
합계:220152087 시간:1464
합계:220152087 시간:72
합계:220152087 시간:25
읽은 데이터가 정확하다는 것을 나타냅니다. 데이터 처리 부분을 삭제합니다.
다음과 같이 코드 코드를 복사합니다.
패키지 테스트;
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;
공개 클래스 테스트 {
공개 정적 무효 메인(String[] args) {
노력하다 {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
노력하다 {
while((n=fis.read())>=0){
//합계+=n;
}
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
노력하다 {
FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
노력하다 {
while((n=bis.read())>=0){
//합계+=n;
}
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
MappedByteBuffer 버퍼=null;
노력하다 {
buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 1253244);
정수 합=0;
int n;
긴 t1=System.currentTimeMillis();
for(int i=0;i<1253244;i++){
//n=0x000000ff&buffer.get(i);
//합계+=n;
}
긴 t=System.currentTimeMillis()-t1;
System.out.println("sum:"+sum+" 시간:"+t);
} 잡기(FileNotFoundException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
} 잡기(IOException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
}
}
테스트 결과:
다음과 같이 코드 코드를 복사합니다.
합계:0 시간:1458
합계:0 시간:67
합계:0 시간:8
파일의 일부 또는 전체를 읽고 쓰기 위해 메모리에 매핑하면 속도가 크게 향상되는 것을 볼 수 있습니다.
이는 메모리 매핑 파일이 먼저 외부 메모리의 파일을 메모리의 연속 영역에 매핑하고, 이는 바이트 배열로 처리되므로 읽기 및 쓰기 작업이 메모리에서 직접 작동한 다음 메모리 영역을 다시 매핑하기 때문입니다. 외부 저장소 파일을 사용하면 외부 저장소를 자주 읽고 쓰는 시간을 절약하고 읽고 쓰는 시간을 크게 줄일 수 있습니다.