자바 메모리 맵 큰 파일 쉽게 처리
메모리 맵 파일(Memory-mapped File)은 가상 메모 리 를 한 파일 에 매 핑 하여 프로그램 처리 파일 을 주 메모리 에 접근 하 는 것 과 같 게 하 는 것 을 말한다.
가상 메모리(물리 적 메모리 가 아 닌 것 이 분명 합 니 다)는 컴퓨터 시스템 메모리 관리 기술 입 니 다.요술 을 부 린 것 처럼 프로그램 은 연속 적 으로 사용 가능 한 메모 리 를 가지 고 있다 고 생각 합 니 다.실제로 여러 개의 물리 적 메모리 로 구 분 된 조각 이 고 일 부 는 외부 디스크 메모리 에 잠시 저장 되 어 필요 할 때 데이터 교환 을 합 니 다.
메모리 맵 파일 의 주요 용 도 는 I/O 성능 을 증가 시 키 는 것 입 니 다.특히 큰 파일 을 대상 으로 합 니 다.작은 파일 에 대해 서 는 메모리 맵 파일 이 오히려 조각 공간의 낭 비 를 초래 할 수 있 습 니 다.메모리 맵 은 항상 페이지 경 계 를 맞 춰 야 하기 때 문 입 니 다.최소 단 위 는 4 KiB 이 고 5 KiB 의 파일 은 8 KiB 메모 리 를 차지 하 며 3 KiB 메모 리 를 낭비 합 니 다.
java.nio 패 키 지 는 메모리 매 핑 을 매우 간단하게 만 들 었 습 니 다.그 중의 핵심 클래스 는 MappedByteBuffer 라 고 하 는데,글자 의 뜻 은 매 핑 된 바이트 버퍼 입 니 다.
01、MappedByteBuffer 로 파일 읽 기
현재 cmower.txt 라 는 파일 이 있다 고 가정 하면 그 내용 은:
침묵 왕 2,재 미 있 는 프로그래머
PS:아,왕 할머니 가 참 외 를 팔 아 자화자찬 하 는 버릇 을 고 칠 수가 없어 요.글 이 도 둑 맞 아서 무서워 요.
이 파일 은/resource 디 렉 터 리 에 놓 여 있 습 니 다.아래 방법 으로 가 져 올 수 있 습 니 다.
ClassLoader classLoader = Cmower.class.getClassLoader();
Path path = Paths.get(classLoader.getResource("cmower.txt").getPath());
Path 는 디 렉 터 리 를 표시 할 수도 있 고 파일 을 표시 할 수도 있 습 니 다.File 처럼-물론 Path 는 File 을 대체 하 는 데 사 용 됩 니 다.그리고 파일 에서 채널(채널,디스크 파일 에 대한 추상)을 가 져 옵 니 다.
FileChannel fileChannel = FileChannel.open(path);
이 어 FileChannel 류 의 map 방법 을 사용 하여 channel 에서 MappedByteBuffer 를 가 져 왔 습 니 다.이러한 확장 은 ByteBuffer―메모리 맵 파일 의 기본 적 인 조작 방법 을 제공 합 니 다.
MappedByteBuffer mappedByteBuffer = fileChannel.map(mode, position, size);
맵 방법의 세 가지 인 자 를 살짝 설명해 주세요.1)mode 는 파일 맵 모드 로 세 가지 로 나 뉜 다.
3)size 는 매 핑 할 영역의 크기 이 며,반드시 마이너스 여야 하 며,Integer.MAX 보다 크 면 안 됩 니 다.VALUE。
메모리 버퍼 에 파일 을 비 추 면 CharBuffer 에 데 이 터 를 읽 고 인쇄 할 수 있 습 니 다.구체 적 인 코드 예 는 다음 과 같다.
CharBuffer charBuffer = null;
ClassLoader classLoader = Cmower.class.getClassLoader();
Path path = Paths.get(classLoader.getResource("cmower.txt").getPath());
try (FileChannel fileChannel = FileChannel.open(path)) {
MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, 0, fileChannel.size());
if (mappedByteBuffer != null) {
charBuffer = Charset.forName("UTF-8").decode(mappedByteBuffer);
}
System.out.println(charBuffer.toString());
} catch (IOException e) {
e.printStackTrace();
}
decode()방법의 매개 변 수 는 Mapped Byte Buffer 이기 때문에 디스크 가 아 닌 메모리 에서 읽 은 파일 내용 이기 때문에 속도 가 매우 빠 를 것 입 니 다.02、MappedByteBuffer 로 파일 쓰기
지금 아래 내용 을 파일 에 쓰 려 면 cmower 1.txt 라 고 가정 합 니 다.
침묵 왕 2,저자
이 파일 은 아직 만 들 지 않 았 습 니 다.프로젝트 의 classpath 디 렉 터 리 에 놓 을 계획 입 니 다.
Path path = Paths.get("cmower1.txt");
구체 적 인 위 치 는 다음 그림 과 같다.그리고 파일 을 만 드 는 채널 입 니 다.
FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING)
여전히 사용 하 는 open 방법 은 3 개의 인 자 를 추 가 했 습 니 다.앞의 2 개 는 이해 하기 쉽 고 파일 읽 기(READ),쓰기(WRITE)를 표시 합 니 다.세 번 째 매개 변수 TRUNCATEEXISTING 은 파일 이 이미 존재 하고 파일 이 열 려 있 으 면 WRITE 작업 을 하려 면 길이 가 0 으로 잘 린 다 는 뜻 이다.이 어 FileChannel 류 의 map 방법 을 사용 하여 channel 에서 MappedByteBuffer 를 가 져 옵 니 다.
MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_WRITE, 0, 1024);
이번에 우 리 는 모드 를 MapMode.READ 로 조정 했다.WRITE,파일 크기 를 1024,즉 1KB 크기 로 지정 합 니 다.그리고 MappedByteBuffer 의 put()방법 으로 CharBuffer 의 내용 을 파일 에 저장 합 니 다.구체 적 인 코드 예 는 다음 과 같다.
CharBuffer charBuffer = CharBuffer.wrap(" ,《Web 》 ");
Path path = Paths.get("cmower1.txt");
try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING)) {
MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_WRITE, 0, 1024);
if (mappedByteBuffer != null) {
mappedByteBuffer.put(Charset.forName("UTF-8").encode(charBuffer));
}
} catch (IOException e) {
e.printStackTrace();
}
cmower 1.txt 를 열 어 내용 을 확인 하고 예상 한 내용 이 기록 되 었 는 지 확인 할 수 있 습 니 다.03.Mappedbytebuffer 의 아 쉬 움
자바 에서 Mapped Byte Buffer 를 사용 하 는 것 은 매우 번 거 롭 고 고통스러운 일이 라 고 합 니 다.주로 다음 과 같은 표현 이 있 습 니 다.
1)1 회 맵 의 크기 는 1.5G 정도 로 제한 하 는 것 이 좋 으 며,중복 맵 은 가상 메모리 회수 와 재배 치 압력 을 증가 시 킵 니 다.파일 크기 가 확실 하지 않 으 면 그다지 우호 적 이지 않다 는 것 이다.
2)가상 메모 리 는 운영 체제 에서 디스크 를 언제 새로 고 칠 지 결정 합 니 다.이 시간 은 프로그램 에 의 해 제어 되 기 쉽 지 않 습 니 다.
3)Mapped Byte Buffer 의 회수 방식 은 비교적 기괴 하 다.
다시 한 번 강조 하지만 이 세 가지 설 은 모두 내 가 일시 적 으로 능력 에 한계 가 있 고 이런 설의 정확성 을 확정 할 수 없다 는 것 이 라 고 하 는데 매우 유감스럽다.
04.파일 작업 의 처리 시간 비교
어이,친구 야,이상 의 내용 을 다 읽 은 후에 나 는 네가 메모리 맵 파일 에 대해 대충 알 게 되 었 을 것 이 라 고 생각한다.하지만 책임 있 는 프로그래머 라면 메모리 맵 파일 의 읽 기 속도 가 얼마나 빠 른 지 알 고 싶 을 것 이 라 고 믿 습 니 다.
결론 을 내리 기 위해 저 는 다른 세 명의 경기 선 수 를 불 렀 습 니 다.InputStream(일반 입력 흐름),Buffered InputStream(버퍼 가 있 는 입력 흐름),RandomAccessFile(랜 덤 액세스 파일).
읽 는 대상 은 카 리 브 해적 4 의 파도.mkv 로 크기 는 1.71G 이다.
1)일반 입력 흐름
public static void inputStream(Path filename) {
try (InputStream is = Files.newInputStream(filename)) {
int c;
while((c = is.read()) != -1) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
2)버퍼 가 있 는 입력 흐름
public static void bufferedInputStream(Path filename) {
try (InputStream is = new BufferedInputStream(Files.newInputStream(filename))) {
int c;
while((c = is.read()) != -1) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
3)무 작위 접근 파일
public static void randomAccessFile(Path filename) {
try (RandomAccessFile randomAccessFile = new RandomAccessFile(filename.toFile(), "r")) {
for (long i = 0; i < randomAccessFile.length(); i++) {
randomAccessFile.seek(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
4)메모리 맵 파일
public static void mappedFile(Path filename) {
try (FileChannel fileChannel = FileChannel.open(filename)) {
long size = fileChannel.size();
MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, 0, size);
for (int i = 0; i < size; i++) {
mappedByteBuffer.get(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
테스트 프로그램 도 간단 합 니 다.대체적으로 다음 과 같 습 니 다.
long start = System.currentTimeMillis();
bufferedInputStream(Paths.get("jialebi.mkv"));
long end = System.currentTimeMillis();
System.out.println(end-start);
네 선수 의 결 과 는 다음 과 같다.방법.
시간.
일반 입력 흐름
거북 속,인내심 없 이 결 과 를 기다리다.
무 작위 접근 파일
거북 속,인내심 없 이 기 다 려 라.
버퍼 가 있 는 입력 흐름
29966
메모리 맵 파일
914
보통 입력 흐름 과 무 작위 접근 파일 이 느 려 서 정말 거북이 속도 입 니 다.저 는 인내심 을 가지 고 결 과 를 기다 리 지 않 았 습 니 다.버퍼 가 있 는 입력 흐름 은 괜 찮 지만 메모리 맵 파일 보다 훨씬 손 색 이 있 습 니 다.이 를 통 해 얻 은 결론 은 메모리 맵 파일,G 큰 파일 을 쉽게 처리 한 다 는 것 이다.
05 마지막
이 글 은 자바 의 메모리 맵 파일 을 소개 하 는데 Mapped ByteBuffer 는 영혼 으로 로켓 처럼 읽 는 속도 가 빠르다.또한 모든 예제 와 코드 세 션GitHub 에서 찾기-Maven 프로젝트 이기 때문에 가 져 오고 실행 하기 쉽다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.