国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

JavaNIO入門

2019-11-14 15:16:46
字體:
來源:轉載
供稿:網友

NIO入門

前段時間在公司里處理一些大的數據,并對其進行分詞、提取關鍵字等。雖說任務基本完成了(效果也不是特別好),對于java還沒入門的我來說前前后后花了2周的時間,我自己也是醉了。當然也有涉及到機器學習的知識,我想陸陸續續的記錄下我的這一次任務的過程,也算做一個總結。

首先,手上有這么個達G級別的文件,按照Java普通I/O的方式肯定是不行的了,劃分文件的話,也不知何年何月才能讀完。所以后來上網查找了相關資料,才知道有這么個神奇的NIO

Java編程中,I/O是用流的方式讀取文件,所有I/O都被視為單個的字節的移動,通過一個稱為Stream的對象一次移動一個字節。Java中新的輸入/輸出(NIO)庫是在JDK1.4中引入的。NIO彌補了原來I/O的不足,它在標準Java代碼中提供了高速、面向塊的I/O。通過定義包含數據的塊,以及通過以塊的形式來處理這些數據,NIO不用使用本機代碼就可以利用低級優化,這是原來的I/O包所無法做到的。

流與塊的比較

原來的I/O庫和NIO最重要的區別就是數據打包和傳輸的方式,原來的I/O以流的方式處理數據,而NIO以塊的方式處理數據。

面向流的I/O系統一次一個字節的處理數據,一個輸入流產生一個字節的數據,一個輸出流產生一個字節的數據。

一個面向塊的I/O系統以塊的形式處理數據。每一個操作都在一步中產生或者消費一個數據塊。按塊處理數據比按字節處理數據要快得多,即便它沒有面向流的I/O那樣的簡單性。

通道和緩沖區

通道和緩沖區是NIO中的核心對象,幾乎在每一個I/O操作中都要使用它們。

通道是對原I/O包中的流的模擬。到任何目的地或來自任何地方的所有數據都必須通過一個Channel對象。一個Buffer實質上是一個容器對象。發送給一個通道的所有對象都必須首先存放到緩沖區中;同樣的,從通道中讀取任何的數據都必須首先讀取到緩沖區里。

什么是緩沖區?

Buffer是一個對象,它包含一些要寫入或者剛讀出的數據。 在 NIO 中加入Buffer對象,體現了新庫與原 I/O 的一個重要區別。在面向流的  I/O 中,您將數據直接寫入或者將數據直接讀到Stream對象中。在 NIO 庫中,所有數據都是用緩沖區處理的。在讀取數據時,它是直接讀到緩沖區中的。在寫入數據時,它是寫入到緩沖區中的。任何時候訪問 NIO 中的數據,您都是將它放到緩沖區中。緩沖區實質上是一個數組。通常它是一個字節數組,但是也可以使用其他種類的數組。但是一個緩沖區不僅僅是一個數組。緩沖區提供了對數據的結構化訪問,而且還可以跟蹤系統的讀/寫進程。

緩沖區類型

最常用的緩沖區類型是ByteBuffer。一個ByteBuffer可以在其底層字節數組上進行 get/set 操作(即字節的獲取和設置)。ByteBuffer不是 NIO  中唯一的緩沖區類型。事實上,對于每一種基本 Java 類型都有一種緩沖區類型:

ByteBuffer

CharBuffer

ShortBuffer

IntBuffer

LongBuffer

FloatBuffer

DoubleBuffer

每一個Buffer類都是Buffer接口的一個實例。 除了ByteBuffer,每一個 Buffer 類都有完全一樣的操作,只是它們所處理的數據類型不一樣。因為大多數標準 I/O 操作都使用ByteBuffer,所以它具有所有共享的緩沖區操作以及一些特有的操作。

下面看一下FloatBuffer的簡單例子:

 1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.nio.ByteBuffer; 5 import java.nio.FloatBuffer; 6 import java.nio.channels.FileChannel; 7  8 // UseFloatBuffer 9 10 public class UseFloatBuffer {11     12     public static void main(String[] args) throws Exception {13         14         FloatBuffer fb=FloatBuffer.allocate(10);15         for (int i=0; i<fb.capacity(); i++) {16             float f=(float)((float)i/10*(2*Math.PI));17             fb.put(f);18         }19         fb.flip();20         while (fb.hasRemaining()){21             float f=fb.get();22             System.out.PRintln(f);23         }24     }25 }

什么是通道?

Channel是一個對象,可以通過它讀取和寫入數據。拿 NIO 與原來的 I/O 做個比較,通道就像是流。正如前面提到的,所有數據都通過 Buffer 對象來處理。您永遠不會將字節直接寫入通道中,相反,您是將數據寫入包含一個或者多個字節的緩沖區。同樣,您不會直接從通道中讀取字節,而是將數據從通道讀入緩沖區,再從緩沖區獲取這個字節。簡而言之,就是NIO的大致流程為:輸入文件->緩沖區->通道->緩沖區->程序處理數據->緩沖區->通道->緩沖區->輸出文件;I/O的大致流程為:輸入文件->流->程序處理數據->流->輸出文件。

通道類型

通道與流的不同之處在于通道是雙向的。而流只是在一個方向上移動(一個流必須是InputStream或者OutputStream的子類),而通道可以用于讀、寫或者同時用于讀寫。

實踐起來:NIO 中的讀和寫

讀和寫是 I/O 的基本過程。從一個通道中讀取很簡單:只需創建一個緩沖區,然后讓通道將數據讀到這個緩沖區中;寫入也相當簡單:創建一個緩沖區,用數據填充它,然后讓通道用這些數據來執行寫入操作。

從文件中讀取

如果使用原來的 I/O,那么我們只需創建一個FileInputStream并從它那里讀取。而在 NIO 中,情況稍有不同:我們首先從FileInputStream獲取一個Channel對象,然后使用這個通道來讀取數據。

在 NIO 系統中,任何時候執行一個讀操作,您都是從通道中讀取,但是您不是直接從通道讀取。因為所有數據最終都駐留在緩沖區中,所以您是通過通道讀到緩沖區中的數據。

因此讀取文件涉及三個步驟:

(1) 從FileInputStream獲取Channel

(2) 創建Buffer

(3) 將數據從Channel讀到Buffer中。

1 FileInputStream fin=new FileInputStream("read.txt");2 FileChannel fc=fin.getChannel();3 ByteBuffer buffer=ByteBuffer.allocate(1024);4 fc.read(buffer);

寫入文件

在 NIO 中寫入文件類似于從文件中讀取。首先從FileOutputStream獲取一個通道;下一步是創建一個緩沖區并在其中放入一些數據 - 在這里,數據將從一個名為data的數組中取出,最后一步是寫入緩沖區中。

1 FileOutputStream fout=new FileOutputStream("write.txt");2 FileChannel fc=fout.getChannel();3 ByteBuffer buffer=ByteBuffer.allocate(1024);4 for (int i=0; i<data.length; i++) {5       buffer.put(data[i]);6 }7 buffer.flip();8 fc.write(buffer);    

實戰練習

我們以一個名為 CopyFile.java 的簡單程序作為這個練習的基礎,它將一個文件的所有內容拷貝到另一個文件中。CopyFile.java 執行三個基本操作:首先創建一個Buffer,然后從源文件中將數據讀到這個緩沖區中,然后將緩沖區寫入目標文件。這個程序不斷重復 ― 讀、寫、讀、寫 ― 直到源文件結束。

 1 // CopyFile 2  3 import java.io.*; 4 import java.nio.*; 5 import java.nio.channels.*; 6  7 public class CopyFile { 8      9     static public void main( String args[] ) throws Exception {10         String infile="E://北京歡迎你.txt";11         String outfile="E://out.txt";12 13         FileInputStream fin=new FileInputStream(infile);14         FileOutputStream fout=new FileOutputStream(outfile);15         FileChannel fcin = fin.getChannel();16         FileChannel fcout = fout.getChannel();17 18         ByteBuffer buffer = ByteBuffer.allocate(1024);19 20         while (true) {21             buffer.clear();22             int r=fcin.read(buffer);23             if (r == -1) {24                 break;25             }26             buffer.flip();27             fcout.write(buffer);28         }29     }30 }

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 神木县| 札达县| 龙海市| 景德镇市| 兴城市| 葵青区| 图们市| 巫山县| 马鞍山市| 隆德县| 秦安县| 安吉县| 嘉黎县| 肇源县| 东源县| 固原市| 海晏县| 榆树市| 丹凤县| 绵阳市| 秭归县| 保定市| 攀枝花市| 汤阴县| 富裕县| 托里县| 马山县| 黎城县| 焦作市| 大关县| 观塘区| 香港 | 林口县| 阿巴嘎旗| 灌南县| 博白县| 宿松县| 改则县| 蛟河市| 义乌市| 咸丰县|