Java NIO 之 FileChannel

從 JDK1.4 開始(2002 年發佈的),Java 提供了 NIO ,主要包含在 java.nio 軟件包及其子包中,並被命名爲 New I/O(NIO)距今已經十幾年了,其實已經算不得新了。

Java NIO 網上有很多詳細的文檔和書籍。

NIO 中的 Channel 可以分成 2 類,

  • 一類是阻塞的,只有 FileChannel
  • 一類是非阻塞的(除了 FileChannel),此類一般與 Selector 一起使用,通常是和網絡相關的操作。

FileChannel

FileChannel 雖然是阻塞的,但是通常他在性能上有更好的表現。它可以通過 map 方法實現內存映射,直接提升了效率。

操作系統中,把系統的空間分成用戶空間和內核空間。所謂內核空間,指的是操作系統所在的區域,裏面的操作和操作系統密切相關,屬於底層調用,包括和硬件的I/O交互,設置指令,線程調度等操作。而用戶空間,就是常規進程所在的區域,JVM就屬於常規進程,運行在用戶空間。用戶空間的操作不能干擾內核空間的操作,所以用戶空間不能直接和硬件通信,必須通過內核空間作爲中間人。正式由於這種機制,傳統的文件I/O不得不在內核空間內核空間拷貝數據。 但是,還有一種操作系統支持的特殊類型的I/O操作,它直接將用戶空間中的內存映射到內核空間中的高速緩存頁,這種方式省去了內核空間和用戶空間之間的數據複製損耗。

12

操作系統中,把系統的空間分成用戶空間和內核空間。所謂內核空間,指的是操作系統所在的區域,裏面的操作和操作系統密切相關,屬於底層調用,包括和硬件的I/O交互,設置指令,線程調度等操作。而用戶空間,就是常規進程所在的區域,JVM就屬於常規進程,運行在用戶空間。用戶空間的操作不能干擾內核空間的操作,所以用戶空間不能直接和硬件通信,必須通過內核空間作爲中間人。正式由於這種機制,傳統的文件I/O不得不在內核空間內核空間拷貝數據。但是,還有一種操作系統支持的特殊類型的I/O操作,它直接將用戶空間中的內存映射到內核空間中的高速緩存頁,這種方式省去了內核空間和用戶空間之間的數據複製損耗。

下面的代碼演示了通過 FileChannel 的 map 方法讀取內容。

Java

public static void demo() throws Exception { RandomAccessFile aFile = new RandomAccessFile("c:\\source.txt", "r"); FileChannel inChannel = aFile.getChannel(); // map方法映射 MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); buffer.load(); for (int i = 0; i < buffer.limit(); i++) { System.out.print((char) buffer.get()); } buffer.clear(); // 關閉channel inChannel.close(); aFile.close(); }

1234567891011121314

public static void demo() throws Exception { RandomAccessFile aFile = new RandomAccessFile("c:\\source.txt", "r"); FileChannel inChannel = aFile.getChannel(); // map方法映射 MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); buffer.load(); for (int i = 0; i < buffer.limit(); i++) { System.out.print((char) buffer.get()); } buffer.clear(); // 關閉channel inChannel.close(); aFile.close(); }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章