Menggunakan Java MappedByteBuffer

1. Ikhtisar

Di artikel singkat ini, kita akan melihat MappedByteBuffer di paket java.nio . Utilitas ini bisa sangat berguna untuk pembacaan file yang efisien.

2. Bagaimana MappedByteBuffer Bekerja

Saat kami memuat wilayah file, kami dapat memuatnya ke wilayah memori tertentu yang dapat diakses nanti.

Saat kita mengetahui bahwa kita perlu membaca konten file beberapa kali, ada baiknya untuk mengoptimalkan proses yang mahal, misalnya dengan menyimpan konten tersebut di memori. Berkat itu, pencarian selanjutnya dari bagian file itu hanya akan masuk ke memori utama tanpa perlu memuat data dari disk, mengurangi latensi secara substansial.

Satu hal yang perlu kita perhatikan saat menggunakan MappedByteBuffer adalah saat kita bekerja dengan file yang sangat besar dari disk - kita perlu memastikan file tersebut akan masuk ke dalam memori .

Jika tidak, kita dapat mengisi seluruh memori dan, sebagai konsekuensinya, menjalankan OutOfMemoryException yang umum . Kita dapat mengatasinya dengan memuat hanya sebagian dari file - misalnya berdasarkan pola penggunaan.

3. Membaca File Menggunakan MappedByteBuffer

Katakanlah kita memiliki file bernama fileToRead.txt dengan konten berikut:

This is a content of the file

File tersebut terletak di direktori / resource sehingga kita dapat memuatnya menggunakan fungsi berikut:

Path getFileURIFromResources(String fileName) throws Exception { ClassLoader classLoader = getClass().getClassLoader(); return Paths.get(classLoader.getResource(fileName).getPath()); }

Untuk membuat MappedByteBuffer dari file, pertama-tama kita perlu membuat FileChannel darinya. Setelah kami telah saluran kami buat, kami dapat memanggil peta () metode di atasnya melintas di MapMode, sebuah posisi dari mana kita ingin membaca, dan ukuran parameter yang menentukan berapa banyak byte yang kita inginkan:

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); } }

Setelah kami memetakan file kami ke buffer yang dipetakan memori, kami dapat membaca data dari itu ke dalam CharBuffer. Penting untuk diperhatikan adalah bahwa meskipun kita membaca konten file ketika kita memanggil metode decode () melewati MappedByteBuffer, kita membaca dari memori, bukan dari disk. Oleh karena itu pembacaan itu akan sangat cepat.

Kami dapat menegaskan bahwa konten yang kami baca dari file kami adalah konten sebenarnya dari file fileToRead.txt :

assertNotNull(charBuffer); assertEquals( charBuffer.toString(), "This is a content of the file");

Setiap pembacaan berikutnya dari mappedByteBuffer akan sangat cepat karena konten file dipetakan di memori dan pembacaan dilakukan tanpa perlu mencari data dari disk.

4. Menulis ke File Menggunakan MappedByteBuffer

Katakanlah kita ingin menulis beberapa konten ke dalam file fileToWriteTo.txt menggunakan API MappedByteBuffer . Untuk mencapai itu kita perlu membuka FileChannel dan memanggil metode map () di atasnya, meneruskan FileChannel.MapMode.READ_WRITE.

Selanjutnya, kita dapat menyimpan konten CharBuffer ke dalam file menggunakan metode put () dari MappedByteBuffer:

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)); } }

Kami dapat menegaskan bahwa konten sebenarnya dari charBuffer telah ditulis ke file dengan membaca isinya:

List fileContent = Files.readAllLines(pathToWrite); assertEquals(fileContent.get(0), "This will be written to the file");

5. Kesimpulan

Dalam tutorial singkat ini, kami melihat konstruksi MappedByteBuffer dari paket java.nio .

Ini adalah cara yang sangat efisien untuk membaca konten file beberapa kali, karena file tersebut dipetakan ke dalam memori dan pembacaan berikutnya tidak perlu setiap kali masuk ke disk.

Semua contoh dan cuplikan kode ini dapat ditemukan di GitHub - ini adalah proyek Maven, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.