Javaを使うMappedByteBuffer
1概要
この簡単な記事では、
java.nio
パッケージの
MappedByteBuffer
を見ていきます。このユーティリティは効率的なファイル読み込みに非常に役立ちます。
2どのように
__MappedByteBuffer W
__orks
ファイルの領域を読み込むときは、後でアクセスできる特定のメモリ領域に読み込むことができます。
ファイルの内容を複数回読み取る必要があることがわかった場合は、費用のかかるプロセスを最適化することをお勧めします。その内容をメモリに保存します。そのおかげで、ファイルのその部分のその後の検索は、ディスクからデータをロードする必要なしにメインメモリだけに行き、待ち時間を大幅に減らすことができます。
MappedByteBuffer
を使用するときに注意する必要があることの1つは、ディスクから非常に大きなファイルを扱う場合です –
ファイルがメモリに収まるようにする必要があります
。
そうでなければ、メモリ全体をいっぱいにして、結果として、共通の__OutOfMemoryExceptionに遭遇する可能性があります。
3
MappedByteBuffer
を使用したファイルの読み取り
次の内容を含む
fileToRead.txt
というファイルがあるとします。
This is a content of the file
ファイルは
/resource
ディレクトリにあるので、次の関数を使って読み込むことができます。
Path getFileURIFromResources(String fileName) throws Exception {
ClassLoader classLoader = getClass().getClassLoader();
return Paths.get(classLoader.getResource(fileName).getPath());
}
ファイルから
MappedByteBuffer
を作成するには、まずそのファイルから
FileChannel
を作成する必要があります。チャネルを作成したら、
MapMode、読み込み元の
position
、および必要なバイト数を指定する
size
パラメータを渡して、
map()__メソッドを呼び出すことができます。
CharBuffer charBuffer = null;
Path pathToRead = getFileURIFromResources("fileToRead.txt");
try (FileChannel fileChannel (FileChannel) Files.newByteChannel(
pathToRead, EnumSet.of(StandardOpenOption.READ))) {
MappedByteBuffer mappedByteBuffer = fileChannel
.map(FileChannel.MapMode.READ__ONLY, 0, fileChannel.size());
if (mappedByteBuffer != null) {
charBuffer = Charset.forName("UTF-8").decode(mappedByteBuffer);
}
}
ファイルをメモリマップバッファにマップしたら、そこから
CharBufferにデータを読み込むことができます。
ModepedByteBufferを渡して
decode()
メソッドを呼び出すときにファイルの内容を読み込んでいることに注意してください。ディスクからではなく、メモリから読み取ります。したがって、その読み取りは非常に高速になります。
ファイルから読み込んだコンテンツは、
fileToRead.txt
ファイルの実際のコンテンツであると言えるでしょう。
assertNotNull(charBuffer);
assertEquals(
charBuffer.toString(), "This is a content of the file");
その後の
mappedByteBuffer
からの読み取りは非常に高速になります。これは、ファイルの内容がメモリーにマップされており、読み取りはディスクからデータを検索する必要なしに行われるためです。
4
MappedByteBuffer
を使用してファイルに書き込む
MappedByteBuffer
APIを使用して
fileToWriteTo.txt
ファイルにコンテンツを書き込みたいとしましょう。そのためには、
FileChannel
を開き、その上で
map()
メソッドを呼び出して
FileChannel.MapMode.READ
WRITE.__を渡す必要があります。
次に、
MappedByteBufferの
put()メソッドを使用して、
CharBuffer
の内容をファイルに保存します。
CharBuffer charBuffer = CharBuffer
.wrap("This will be written to the file");
Path pathToWrite = getFileURIFromResources("fileToWriteTo.txt");
try (FileChannel fileChannel = (FileChannel) Files
.newByteChannel(pathToWrite, EnumSet.of(
StandardOpenOption.READ,
StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE__EXISTING))) {
MappedByteBuffer mappedByteBuffer = fileChannel
.map(FileChannel.MapMode.READ__WRITE, 0, charBuffer.length());
if (mappedByteBuffer != null) {
mappedByteBuffer.put(
Charset.forName("utf-8").encode(charBuffer));
}
}
charBuffer
の実際の内容は、その内容を読み取ることでファイルに書き込まれたと主張できます。
List<String> fileContent = Files.readAllLines(pathToWrite);
assertEquals(fileContent.get(0), "This will be written to the file");
5結論
このクイックチュートリアルでは、
java.nio
パッケージの
MappedByteBuffer
構造を見ていました。
ファイルはメモリにマップされ、その後の読み込みで毎回ディスクにアクセスする必要がないため、これはファイルの内容を複数回読み込むための非常に効率的な方法です。
これらすべての例とコードスニペットはhttps://github.com/eugenp/tutorials/tree/master/core-java-io[GitHubに追加]を見つけることができます – これはMavenプロジェクトです。そのまま実行します。