2012-02-03 6 views
2

나는 메모리 매핑 된 파일을 만드는 방법을 이해하지만, 내 질문의 다음 줄에 그런 말을 할 수 있습니다 :메모리 매핑 된 파일의 자바 NIO

내가 예를 들어 2메가바이트로 크기를 설정
FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); 
ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, SIZE); 

,이 방법을 수행 그것은 단지 2MB의 파일을로드 할 것인가, 아니면 그 파일을 더 읽고 바이트를 소비하면서 버퍼를 업데이트 할 것인가?

+5

매핑 된 부분 만 해당 버퍼를 통해 액세스 할 수 있습니다. 전체 파일에 대해 창으로 상상해보십시오. 가시 영역 만 읽을 수 있습니다. (서면) – bestsss

+0

@bestsss :이 질문에 답을 추가해야합니다. – Jonas

+0

@Jonas, ... 한 문장으로 답변을 좋아하지 않습니다. 대답은 아주 분명합니다. 묻는 사람은 항상 스스로 대답하고 그것을 선택할 수 있습니다. – bestsss

답변

2

버퍼의 크기는 전달하는 크기이며 늘리거나 줄이지 않습니다.

javadoc

는 말한다 : 직접 메모리에이 채널의 파일의

지도 지역.

...

크기 - 매핑 할 영역의 크기. 음이 아닌 Integer.MAX_VALUE의

EDIT 이하 커야합니다 : 당신이 무슨 뜻인지에 따라

"새로운 데이터로 업데이트", 대답은 '예'입니다.

이 클래스의 인스턴스가 제공하는 파일의 뷰는 동일한 프로그램의 다른 인스턴스에 의해 제공 같은 파일의 뷰와 일치되도록 보장된다. 그러나이 클래스의 인스턴스가 제공하는 뷰는 기본 운영 체제에서 수행 한 캐싱과 네트워크 파일 시스템 프로토콜에 의해 유발되는 지연으로 인해 동시에 실행되는 다른 프로그램에서 볼 수있는 뷰와 일치 할 수도 있고 그렇지 않을 수도 있습니다. 이는 다른 프로그램이 작성된 언어와 동일한 기계 또는 다른 기계에서 실행 중인지 여부와 상관없이 사실입니다. 이러한 불일치의 정확한 특성은 시스템에 따라 다르므로 지정되지 않습니다.

따라서 다른 시스템에서는 캐싱을 수행 할 수 있지만 이러한 캐쉬를 플러시하거나 최신 상태로 유지하면 FileChannel에 의해 제공되는보기와 일치합니다.

position 메서드에 대한 명시 적 호출과 다른 방법을 사용하여보기에서 표시 할 내용을 변경할 수도 있습니다.

명시 적으로 또는 바이트 읽기 또는 쓰기로 채널의 위치를 ​​변경하면 원래 개체의 파일 위치가 변경되고 반대의 경우도 마찬가지입니다. 파일 채널을 통해 파일의 길이를 변경하면 원본 객체를 통해 보이는 길이가 변경되고 그 반대의 경우도 마찬가지입니다. 바이트를 쓰는 것으로 파일의 내용을 변경하면 원래의 객체가 보는 내용이 변경되고 그 반대의 경우도 마찬가지입니다. 내가 예 2메가바이트되도록 크기 설정

+0

나는 버퍼가 커지지 않을 것이라는 점을 이해한다. 나의 질문은 내가 소비하는 새로운 데이터로 업데이트 될 것인지 아닌지, javadoc은이 점에서 분명하지 않다. – raygozag

+0

@raygozag, 제 편집을 참조하십시오. –

4

이 그것만로드 파일 2메가바이트 또는이 파일에 추가 판독 내가 바이트를 소모로 버퍼를 업데이트 할 것을 의미 하는가?

버퍼 초기화시 지정된 파일의 부분 만로드합니다. 더 많이 읽고 싶다면 일종의 읽기 루프가 필요할 것입니다. 이것은 까다 롭다는 말은하지 않지만, 관련 API 인 java.io와 java.nio에 대해 100 % 익숙하지 않은 사용자라면 100 % 이해가되지 않을 가능성이 높습니다. (예 :: 버퍼를 뒤집지 않음; 버퍼/파일 엣지 케이스 실수).

ByteBuffer에서이 파일에 쉽게 액세스 할 방법을 찾고 있다면 MappedByteBuffer을 사용해보십시오. 이러한 맥락에서 MBB를 사용하여 약

RandomAccessFile raf = new RandomAccessFile(file, "r"); 
FileChannel fc = raf.getChannel(); 
MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 

좋은 점은 반드시 실제로 메모리에 전체 버퍼를로드,하지만 당신은 액세스가 아니라 부분 만없는 것입니다.