在 java 中,程序通常會(huì)和其他外部設(shè)備進(jìn)行數(shù)據(jù)交互,比如寫入磁盤,網(wǎng)絡(luò)發(fā)送數(shù)據(jù)等等,今天我們來學(xué)學(xué) java 中 基礎(chǔ)的 IO 流。
IO 流
與其他外部設(shè)備進(jìn)行數(shù)據(jù)交互,比如將數(shù)據(jù)從內(nèi)存中保存到磁盤文件中或者從網(wǎng)絡(luò)上下載數(shù)據(jù)并加載到內(nèi)存中,這個(gè)過程都是一種單向且有順序的數(shù)據(jù)傳輸,被稱之為流。
IO 就是 Input 輸入和 Output 輸出。輸入輸出以內(nèi)存為中心的流向劃分的。傳輸數(shù)據(jù)到內(nèi)存就是輸入流,從內(nèi)存中輸出數(shù)據(jù)就是輸出流。
InputStream
InputStream 是所有輸入流的父類,是一個(gè)抽象類,讀取的數(shù)據(jù)單位是字節(jié)(byte)。
主要的抽象方法是 read(),這個(gè)方法就是讀取數(shù)據(jù)內(nèi)容并返回 -1~255 的 int 值。read() 方法是一個(gè)阻塞的方法,只有將內(nèi)容全部讀取完成之后才能運(yùn)行下一行代碼。
public abstract int read() throws IOException;
以 FileInputStream 實(shí)現(xiàn)類作為示例:
public static void main(String[] args) throws Exception {
// input.txt 內(nèi)容為 hello, inputStream
InputStream input = new FileInputStream("input.txt");
int n = 0;
while((n = input.read()) != -1){
System.out.print((char) n);
}
input.close();
}
示例中的 read() 方法只能一個(gè)字節(jié)的一個(gè)字節(jié)讀取數(shù)據(jù),效率不高,當(dāng)文件中存在多個(gè)字節(jié)為一個(gè)漢字的中文時(shí),上面的示例將打印出亂碼。
InputStream 支持將一次性讀取多個(gè)字節(jié)到緩沖區(qū),利用緩沖區(qū)提高效率。返回值的數(shù)據(jù)不再是讀取的數(shù)據(jù)字節(jié),而是讀取的字節(jié)數(shù)。并且可以正常的打印出中文字符。
// 將讀取的內(nèi)容填充到 byte 數(shù)組
public int read(byte b[]) throws IOException
// 將讀取的內(nèi)容填充 byte 數(shù)組中 off 開始,len 長度的區(qū)域
public int read(byte b[], int off, int len) throws IOException
將緩沖區(qū)大小設(shè)置為 1024 個(gè)字節(jié)示例:
public static void main(String[] args) throws Exception {
//input.txt 文件內(nèi)容為 你好, inputStream
InputStream input = new FileInputStream("input.txt");
byte[] result = new byte[1024];
while(input.read(result) != -1){
System.out.print(new String(result, "utf-8"));
}
input.close();
}
OutputStream
OutputStream 是所有輸出流的父類。和 InputStream 一樣是一個(gè)抽象類。
主要的抽象方法是 write(),也是一個(gè)阻塞的方法,只有將內(nèi)容全部寫完成之后才能運(yùn)行下一行代碼。write() 方法和 read() 方法一樣都是一個(gè)字節(jié)一個(gè)字節(jié)的操作的。
public abstract void write(int b) throws IOException;
以 FileInputStream 實(shí)現(xiàn)類作為示例:
public static void main(String[] args) throws Exception {
OutputStream out = new FileOutputStream("out.txt");
try {
out.write("h".getBytes());
out.write("e".getBytes());
out.write("l".getBytes());
out.write("l".getBytes());
out.write("0".getBytes());
} finally {
if(out != null) {
out.close();
}
}
}
write() 按單個(gè)字節(jié)寫入磁盤的效率比較低下,OutputStream 提供了 write(byte[]) 一次性大批量的將字節(jié)輸出到磁盤。對(duì)于 IO 設(shè)備來說,一次性寫入 1 個(gè)字節(jié)和寫入 1000 個(gè)字節(jié)的時(shí)間都是差不多的。
public static void main(String[] args) throws Exception {
OutputStream out = new FileOutputStream("out.txt");
try {
out.write("哈嘍,outputStream".getBytes());
} finally {
if(out != null) {
out.close();
}
}
}
關(guān)閉資源
不管是 InputStream 還是 OutputStream 在使用資源之后都需要調(diào)用 close()方法。在示例中如果在 close() 方法調(diào)用之前拋出異常則不會(huì)自動(dòng)關(guān)閉資源。以下兩種方式都可以關(guān)閉資源:
- try..finally 方式
public static void main(String[] args) throws Exception {
InputStream input = new FileInputStream("input.txt");
try {
byte[] result = new byte[1024];
while(input.read(result) != -1){
System.out.print(new String(result, "utf-8"));
}
} finally {
if(input != null) {
input.close();
}
}
}
- try(resource)
實(shí)現(xiàn)了 Closeable 接口的 InputStream 和 OutputStream 使用 try(resource) 時(shí),編譯器會(huì)自動(dòng)增加 finally。
public static void main(String[] args) throws Exception {
try (OutputStream out = new FileOutputStream("out.txt")){
out.write("編譯器會(huì)添加 finally".getBytes());
}
}
總結(jié)
今天就是簡單地給大家介紹 Java 的 IO 流,為接下來學(xué)其他 IO 類打個(gè)基礎(chǔ)。
-
IO
+關(guān)注
關(guān)注
0文章
436瀏覽量
39084 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6909瀏覽量
88849 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3004瀏覽量
73900 -
JAVA
+關(guān)注
關(guān)注
19文章
2960瀏覽量
104565 -
磁盤
+關(guān)注
關(guān)注
1文章
367瀏覽量
25180
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論