<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Java 內存映射文件 – Java `MappedByteBuffer` > 原文: [https://howtodoinjava.com/java7/nio/memory-mapped-files-mappedbytebuffer/](https://howtodoinjava.com/java7/nio/memory-mapped-files-mappedbytebuffer/) 了解 **Java 內存映射文件**,并借助`RandomAccessFile`和`MemoryMappedBuffer`從內存映射文件中讀取和寫入內容。 ## 1\. 內存映射的 IO 如果您知道 [**Java IO 在較低級別**](//howtodoinjava.com/java/io/how-java-io-works-internally-at-lower-level/ "How Java I/O Works Internally at Lower Level?")的工作方式,那么您將了解緩沖區處理,內存分頁和其他此類概念。 對于傳統的文件 I/O,用戶進程在其中發出`read()`和`write()`系統調用來傳輸數據,幾乎總是存在一個或多個復制操作,以在內核空間中的這些文件系統頁面和內存中的內存區域之間移動數據。 用戶空間。 這是因為文件系統頁面和用戶緩沖區之間通常沒有一對一的對齊方式。 但是,大多數操作系統都支持一種特殊類型的 I/O 操作,它允許用戶進程最大程度地利用系統 I/O 的面向頁面的特性,并完全避免緩沖區復制。 這稱為**內存映射的 I/O** ,我們將在此處學習有關內存映射文件的一些知識。 ## 2\. Java 內存映射文件 內存映射的 I/O 使用文件系統來建立從用戶空間直接到適用文件系統頁面的虛擬內存映射。 使用內存映射文件,我們可以假裝整個文件都在內存中,并且可以通過簡單地將其視為非常大的數組來訪問它。 這種方法極大地簡化了我們為修改文件而編寫的代碼。 > **閱讀更多信息:[使用緩沖區](//howtodoinjava.com/java-7/nio/java-nio-2-0-working-with-buffers/ "Java NIO 2.0 : Working With Buffers")** 為了在內存映射文件中進行寫入和讀取,我們從`RandomAccessFile`開始,獲取該文件的通道。 存儲器映射的字節緩沖區是通過`FileChannel.map()`方法創建的。 此類通過特定于內存映射文件區域的操作擴展了[`ByteBuffer`](//howtodoinjava.com/java-7/nio/java-nio-2-0-working-with-buffers/ "Java NIO 2.0 : Working With Buffers")類。 映射的字節緩沖區及其表示的文件映射將保持有效,直到緩沖區本身被垃圾回收為止。 請注意,必須指定文件中要映射的區域的起點和長度。 這意味著您可以選擇映射大文件的較小區域。 ```java import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class MemoryMappedFileExample { static int length = 0x8FFFFFF; public static void main(String[] args) throws Exception { try(RandomAccessFile file = new RandomAccessFile("howtodoinjava.dat", "rw")) { MappedByteBuffer out = file.getChannel() .map(FileChannel.MapMode.READ_WRITE, 0, length); for (int i = 0; i < length; i++) { out.put((byte) 'x'); } System.out.println("Finished writing"); } } } ``` 使用上述程序創建的文件的長度為 128 MB,可能大于操作系統允許的空間。 該文件似乎可以一次訪問,因為只有部分文件被帶入內存,而其他部分被換出。 這樣,可以輕松地修改非常大的文件(最大 2 GB)。 #### 文件模式 像常規文件句柄一樣,文件映射可以是可寫的或只讀的。 * 前兩個映射模式`MapMode.READ_ONLY** 和 **MapMode.READ_WRITE`相當明顯。 它們指示您是要映射為只讀映射還是允許修改映射文件。 * 第三種模式`MapMode.PRIVATE`表示您需要寫時復制映射。 這意味著您通過`put()`進行的任何修改都將導致只有`MappedByteBuffer`實例可以看到的數據的私有副本。 不會對基礎文件進行任何更改,并且對緩沖區進行垃圾回收時所做的任何更改都將丟失。 即使寫時復制映射阻止了對基礎文件的任何更改,您也必須已打開文件以進行讀/寫以設置`MapMode.PRIVATE`映射。 這對于返回的`MappedByteBuffer`對象允許`put()`是必需的。 您會注意到,沒有`unmap()`方法。 建立后,映射將一直有效,直到`MappedByteBuffer`對象被垃圾回收為止。 同樣,映射緩沖區不綁定到創建它們的通道。 關閉關聯的`FileChannel`不會破壞映射。 僅處理緩沖區對象本身會破壞映射。 `MemoryMappedBuffer`具有固定大小,但映射到的文件是彈性的。 具體來說,如果在映射生效時文件大小發生變化,則部分或全部緩沖區可能變得不可訪問,可能會返回未定義的數據,或者會引發未經檢查的異常。 內存映射文件時,請注意其他線程或外部進程如何處理文件。 ## 3\. 內存映射文件的好處 與常規 I/O 相比,內存映射 IO 具有以下優點: 1. 用戶進程將文件數據視為內存,因此無需發出`read()`或`write()`系統調用。 2. 當用戶進程觸摸映射的內存空間時,將自動生成頁面錯誤,以從磁盤引入文件數據。 如果用戶修改了映射的內存空間,則受影響的頁面會自動標記為臟頁面,隨后將刷新到磁盤以更新文件。 3. 操作系統的虛擬內存子系統將執行頁面的智能緩存,并根據系統負載自動管理內存。 4. 數據總是頁面對齊的,不需要緩沖區復制。 5. 可以映射非常大的文件,而無需消耗大量內存來復制數據。 ## 4\. 如何讀取內存映射文件 要使用內存映射的 IO 讀取文件,請使用以下代碼模板: ```java import java.io.File; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class MemoryMappedFileReadExample { private static String bigExcelFile = "bigFile.xls"; public static void main(String[] args) throws Exception { try (RandomAccessFile file = new RandomAccessFile(new File(bigExcelFile), "r")) { //Get file channel in read-only mode FileChannel fileChannel = file.getChannel(); //Get direct byte buffer access using channel.map() operation MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); // the buffer now reads the file as if it were loaded in memory. System.out.println(buffer.isLoaded()); //prints false System.out.println(buffer.capacity()); //Get the size based on content size of file //You can read the file from this buffer the way you like. for (int i = 0; i < buffer.limit(); i++) { System.out.print((char) buffer.get()); //Print the content of file } } } } ``` ## 5\. 如何寫入內存映射文件 要使用內存映射的 IO 將數據寫入文件,請使用以下代碼模板: ```java import java.io.File; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class MemoryMappedFileWriteExample { private static String bigTextFile = "test.txt"; public static void main(String[] args) throws Exception { // Create file object File file = new File(bigTextFile); //Delete the file; we will create a new file file.delete(); try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw")) { // Get file channel in read-write mode FileChannel fileChannel = randomAccessFile.getChannel(); // Get direct byte buffer access using channel.map() operation MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 4096 * 8 * 8); //Write the content using put methods buffer.put("howtodoinjava.com".getBytes()); } } } ``` 在評論部分中將您的評論和想法留給我。 學習愉快!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看