使用 NIO.2 操作檔案系統

來源:互聯網
上載者:User

標籤:

Java 一直到 JDK 1.3 為止,都是使用 java.io 下的類別進行 I/O 的處理,對這有興趣的鄉民,可以參考「Java I/O」,那是我 13 年前整理的 ... XD。JDK 1.4 之後提供了 NIO,到了 JDK 1.7 又加上些新的功能,稱為 NIO.2,這些類別都被放在 java.nio 下,一般來說,使用 java.nio 類別操作檔案系統,會比使用 java.io 效率來的高且方便。

在進入主題前,各位不妨先看一下我之前整理的「Working with the Path Class」及「Metadata File Attributes」,這算是進入主題的前菜,這篇開始要說明怎麼開檔、讀檔、寫檔。

  • 開檔

不管是要讀檔或寫檔,第一個步驟總得要開檔,java.nio 提供了以下的開檔方式:

  1. READ: 要讀取檔案的內容
  2. WRITE: 要寫資料到檔案
  3. CREATE: 建立一個新檔,如果檔案已存在,將它刪除,重建立立新檔。
  4. CREATE_NEW: 建立一個新檔,當檔案已存在,拋出 exception。
  5. APPEND: 附加內容到已存在的檔案。
  6. DELETE_ON_CLOSE: 這個選項是用在暫存檔上,當檔案關閉時,將這個檔案刪除。
  7. TRUNCATE_EXISTING: 將檔案內容清除,然後再開始寫入。
  8. SPARSE: 
  9. SYNC: 保持檔案內容和 metadata 不變。
  10. DSYNC: 保持檔案內容不變。

 底下是一個最典型的範例:

 1 package idv.steven.nio2.metadata; 2  3 import java.io.IOException; 4 import java.nio.channels.ReadableByteChannel; 5 import java.nio.file.Files; 6 import java.nio.file.Path; 7 import java.nio.file.Paths; 8 import java.nio.file.StandardOpenOption; 9 10 public class NIO2File {11     public static void main(String[] args) throws IOException {12         Path path = Paths.get("C:/Java/poi-3.11/NOTICE");13         ReadableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);14         //...15     }16 }

在 java.io 中,I/O 都是在串流 (stream) 中操作,到了 java.nio 都改為渠道 (channel),上面的程式是開啟一個讀取的檔案,所有開檔模式都定義在 StandOpenOption 這個自定型別中。如果要開啟一個寫入的檔案,第 13 行可能就改為如下:

WritableByteChannel channel = Files.newByteChannel(path, new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.WRITE});

寫檔時不能只有 WRITE 這個參數,還要再加入如何 CREATE、CREATE_NEW 等參數,所有參數放在一個 OpenOption 陣列裡。

  • 渠道 (Channel)

java.nio 定義了那些 channel ? 如下類別圖所示:

上圖只列出常用的介面及其 method,要瞭解詳細的類別繼承關係,請看 JDK Doc。操作檔案時,最常用的就是 ReadableByteChannel、WritableByteChannel 及 SeekableByteChannel,前兩者顧名思義,是分別用在讀檔及寫檔,第三個是同時可用在讀與寫的渠道,且可以在讀寫過程裡移動檔案指標。至於 NetworkChannel 和 MulticastChannel 是用在網路的 TCP 和 UDP 傳輸上,會另外說明。

在 java.nio 中定義了渠道取代 java.io 中的 stream,同時渠道操作的物件也不是 byte[]、char[]… 改成 java.nio 自行定義的 ByteBuffer、CharBuffer 等類別,最常用的是 ByteBuffer,關於 ByteBuffer 的說明,請看「ByteBuffer 指標說明」,在繼續往下看之前,請務必先瞭解 ByteBuffer。

  • 讀檔
 1 package idv.steven.nio2.metadata; 2  3 import java.io.IOException; 4 import java.nio.ByteBuffer; 5 import java.nio.channels.ReadableByteChannel; 6 import java.nio.file.Files; 7 import java.nio.file.Path; 8 import java.nio.file.Paths; 9 import java.nio.file.StandardOpenOption;10 11 public class NIO2File {12     public static void main(String[] args) throws IOException {13         Path path = Paths.get("C:/Java/poi-3.11/NOTICE");14         ReadableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);15         16         ByteBuffer buffer = ByteBuffer.allocate(1024);17         18         while (channel.read(buffer) > 0) {19             System.out.println(new String(buffer.array()));20             buffer.flip();21         }22         23         channel.close();24     }25 }

上面的程式,於 18 行每次讀取 1024 個 byte,直到檔尾為止,讀取後放入 buffer 中,在 19 行將讀取的內容輸出,讀完後當然要記得關檔 (23行)。

  • 寫檔
 1 package idv.steven.nio2.metadata; 2  3 import java.io.IOException; 4 import java.nio.ByteBuffer; 5 import java.nio.channels.ReadableByteChannel; 6 import java.nio.channels.WritableByteChannel; 7 import java.nio.file.Files; 8 import java.nio.file.OpenOption; 9 import java.nio.file.Path;10 import java.nio.file.Paths;11 import java.nio.file.StandardOpenOption;12 13 public class NIO2File {14     public static void main(String[] args) throws IOException {15         Path path = Paths.get("C:/Java/poi-3.11/NOTICE");16         ReadableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);17         18         Path pathTo = Paths.get("C:/Java/poi-3.11/NOTICE.txt");19         WritableByteChannel channelTo = Files.newByteChannel(pathTo, 20                 new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.WRITE});21         22         ByteBuffer buffer = ByteBuffer.allocate(1024);23         while ((channel.read(buffer)) > 0) {24             buffer.flip();25             channelTo.write(buffer);26             buffer.flip();27         }28         29         channel.close();30         channelTo.close();31     }32 }

這個程式只是將上一個程式擴充,將由 NOTICE 讀出的內容,寫入 NOTICE.txt 檔裡,在 19~20 行開啟一個寫入的檔案,於 24~26 行將讀到的內容寫入指定的檔案。

 

使用 NIO.2 操作檔案系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.