Java IO(三)——字節流

一、流類

Java的流式輸入/輸出是建立在四個抽象類的基礎上的:InputStream、OutputStream、Reader、Writer。它們用來創建具體的流式子類。儘管程序通過具體子類執行輸入/輸出操作,但頂層類定義了所有流類的基本通用功能。

InputStream和OutputStream爲字節流設計,Reader和Writer爲字符流設計,字節流和字符流形成分離的層次結構。一般來說,處理字符或字符串使用字符流類,處理字節或二進制對象使用字節流。

操作文件流時,不管是字符流還是字節流,都可以按照以下方式進行:

1、使用File類找到一個對象

2、通過File類的對象去實例化字節流或字符流的子類

3、進行字節(字符)的讀、寫操作

4、關閉文件流

二、OutputStream(字節輸出流)

OutputStream是定義了Java流式字節輸入模式的抽象類。該類的所有方法返回一個void值並且在出錯的情況下引發一個IOException,OutputStream提供的抽象方法有:

方 法 作 用
void close() 關閉輸入流,關閉後的寫操作會引發IOException
flush() 刷新此輸入流並強制寫出所有緩衝的輸出字節
write(byte[] b) 向輸入流寫入單個字節,注意參數是一個int型,它允許設計者不必把參數轉換成字節型就可以調用write()方法
write(byte[] b, int off, int len) 以b[off]爲起點,向文件寫入字節數組b中len個字節
write(int b) 向一個輸出流寫一個完整的字節數組

三、FileOutputStream(文件字節輸出流)

FileOutpuStream應該是Java中最常見的字節輸出流了,它創建一個可向文件寫入字節的類OutputStream,它常用的構造方法如下:

1、FileOutputStream(String name)

2、FileOutputStream(File file)

3、FileOutputStream(File file, boolean append)

前兩個構造方法類似,前者輸入文件的絕對路徑,後者輸入File的實例對象,和RandomAccessFile一樣,推薦後者。第三個構造方法有一點不同,append如果設置爲true,文件則以搜索路徑模式打開。FileOutputStream的創建不依賴於文件是否存在,在創建對象時,FileOutputSStream會在打開輸出文件之前就創建它。這種情況下如果試圖打開一個只讀文件,會引發IOException。FileOutputStream,寫一個例子,現在我的D盤下的Files文件夾裏並沒有"stream.txt"這個文件:

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class FileOutputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    OutputStream out = new FileOutputStream(file);
    byte b[] = "Hello World!!!".getBytes(); //操作字節流,要轉換成字節
    out.write(b);
    out.close();
}

}
複製代碼
複製代碼
此時打開"stream.txt":

到D盤下的Files文件夾裏多了"stream.txt",且文件中的內容和我們寫入的一致,同樣這個例子也證明了FileOutputStream並不依賴指定路徑下的文件是否存在。那如果指定路徑下本來就有文件,那麼寫將會覆蓋而不是追加,很好證明:

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class FileOutputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    OutputStream out = new FileOutputStream(file);
    byte b[] = "abcdefghijklmnopqrstuvwxyz".getBytes(); //操作字節流,要轉換成字節
    out.write(b);
    out.close();
}

}
複製代碼
複製代碼
此時再打開"stream.txt":

"stream.txt"中的內容變掉了,證明了結論。

四、InputStream(字節輸入流)

InputStream是定義了Java流式字節輸入模式的抽象類。該類所有方法在出錯的時候都會引發一個IOException,InputStream提供的抽象方法有:

方 法 作 用
int available() 返回當前可讀的字節數
void close() 關閉此輸入流並釋放與該流關聯的所有系統資源,關閉之後再讀取會產生IOException
int mark(int readlimit) 在輸入流中放置一個標記,該流在讀取N個Bytes字節前都保持有效
boolean markSupported() 如果調用的流支持mark()/reset()就返回true
int read() 如果下一個字節可讀取則返回一個×××,遇到文件尾時返回-1
int read(byte b[]) 試圖讀取buffer.length個字節到buffer中,並返回實際成功讀取的字節數,遇到文件尾則返回-1
int read(byte b[], int off, int len) 將輸入流中最多len個數組直接讀入byte數組,off表示數組b中寫入數據的初始偏移量。注意,三個read方法,在輸入數據可用、檢測到流末尾或者拋出異常前,此方法將一直阻塞
void reset() 重新設置輸入指針到先前設置的標記處
long skip(long n) 跳過和丟棄此輸入流中數據的n個字節
五、FileInputStream(文件字節輸入流)

FileInputStream應該是Java中最常見的字節輸入流了,它創建一個能從文件讀取字節的InputStream類,它的兩個常用構造方法如下:

1、FileInputStream(String name)

2、FileInputStream(File file)

和FileOutputStream差不多,推薦後者的用法。FileInputStream,同樣寫一個例子,操作的是上面D盤下的Files文件夾生成的"stream.txt":

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class FileInputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    InputStream in = new FileInputStream(file);
    byte b1[] = new byte[(int)file.length()];
    int i = 0;
    i = in.read(b1);
    System.out.println(i);
    System.out.println(new String(b1, 0, i));

}

}
複製代碼
複製代碼
運行結果爲:

26
abcdefghijklmnopqrstuvwxyz
要區分清楚,OutputStream的作用是將內容由Java內存輸出到文件中、InputStream是將內容由文件輸入到Java內存中。read(byte b[])方法之前講明瞭,表示"試圖讀取buffer.length個字節到buffer中,並返回實際讀取的字節數",返回的是實際字節的大小。Java IO(三)——字節流
一、流類

Java的流式輸入/輸出是建立在四個抽象類的基礎上的:InputStream、OutputStream、Reader、Writer。它們用來創建具體的流式子類。儘管程序通過具體子類執行輸入/輸出操作,但頂層類定義了所有流類的基本通用功能。

InputStream和OutputStream爲字節流設計,Reader和Writer爲字符流設計,字節流和字符流形成分離的層次結構。一般來說,處理字符或字符串使用字符流類,處理字節或二進制對象使用字節流。

操作文件流時,不管是字符流還是字節流,都可以按照以下方式進行:

1、使用File類找到一個對象

2、通過File類的對象去實例化字節流或字符流的子類

3、進行字節(字符)的讀、寫操作

4、關閉文件流

二、OutputStream(字節輸出流)

OutputStream是定義了Java流式字節輸入模式的抽象類。該類的所有方法返回一個void值並且在出錯的情況下引發一個IOException,OutputStream提供的抽象方法有:

方 法 作 用
void close() 關閉輸入流,關閉後的寫操作會引發IOException
flush() 刷新此輸入流並強制寫出所有緩衝的輸出字節
write(byte[] b) 向輸入流寫入單個字節,注意參數是一個int型,它允許設計者不必把參數轉換成字節型就可以調用write()方法
write(byte[] b, int off, int len) 以b[off]爲起點,向文件寫入字節數組b中len個字節
write(int b) 向一個輸出流寫一個完整的字節數組

三、FileOutputStream(文件字節輸出流)

FileOutpuStream應該是Java中最常見的字節輸出流了,它創建一個可向文件寫入字節的類OutputStream,它常用的構造方法如下:

1、FileOutputStream(String name)

2、FileOutputStream(File file)

3、FileOutputStream(File file, boolean append)

前兩個構造方法類似,前者輸入文件的絕對路徑,後者輸入File的實例對象,和RandomAccessFile一樣,推薦後者。第三個構造方法有一點不同,append如果設置爲true,文件則以搜索路徑模式打開。FileOutputStream的創建不依賴於文件是否存在,在創建對象時,FileOutputSStream會在打開輸出文件之前就創建它。這種情況下如果試圖打開一個只讀文件,會引發IOException。FileOutputStream,寫一個例子,現在我的D盤下的Files文件夾裏並沒有"stream.txt"這個文件:

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class FileOutputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    OutputStream out = new FileOutputStream(file);
    byte b[] = "Hello World!!!".getBytes(); //操作字節流,要轉換成字節
    out.write(b);
    out.close();
}

}
複製代碼
複製代碼
此時打開"stream.txt":

到D盤下的Files文件夾裏多了"stream.txt",且文件中的內容和我們寫入的一致,同樣這個例子也證明了FileOutputStream並不依賴指定路徑下的文件是否存在。那如果指定路徑下本來就有文件,那麼寫將會覆蓋而不是追加,很好證明:

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

public class FileOutputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    OutputStream out = new FileOutputStream(file);
    byte b[] = "abcdefghijklmnopqrstuvwxyz".getBytes(); //操作字節流,要轉換成字節
    out.write(b);
    out.close();
}

}
複製代碼
複製代碼
此時再打開"stream.txt":

"stream.txt"中的內容變掉了,證明了結論。

四、InputStream(字節輸入流)

InputStream是定義了Java流式字節輸入模式的抽象類。該類所有方法在出錯的時候都會引發一個IOException,InputStream提供的抽象方法有:

方 法 作 用
int available() 返回當前可讀的字節數
void close() 關閉此輸入流並釋放與該流關聯的所有系統資源,關閉之後再讀取會產生IOException
int mark(int readlimit) 在輸入流中放置一個標記,該流在讀取N個Bytes字節前都保持有效
boolean markSupported() 如果調用的流支持mark()/reset()就返回true
int read() 如果下一個字節可讀取則返回一個×××,遇到文件尾時返回-1
int read(byte b[]) 試圖讀取buffer.length個字節到buffer中,並返回實際成功讀取的字節數,遇到文件尾則返回-1
int read(byte b[], int off, int len) 將輸入流中最多len個數組直接讀入byte數組,off表示數組b中寫入數據的初始偏移量。注意,三個read方法,在輸入數據可用、檢測到流末尾或者拋出異常前,此方法將一直阻塞
void reset() 重新設置輸入指針到先前設置的標記處
long skip(long n) 跳過和丟棄此輸入流中數據的n個字節
五、FileInputStream(文件字節輸入流)

FileInputStream應該是Java中最常見的字節輸入流了,它創建一個能從文件讀取字節的InputStream類,它的兩個常用構造方法如下:

1、FileInputStream(String name)

2、FileInputStream(File file)

和FileOutputStream差不多,推薦後者的用法。FileInputStream,同樣寫一個例子,操作的是上面D盤下的Files文件夾生成的"stream.txt":

複製代碼
複製代碼
package com.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class FileInputStreamTest {

public static void main(String[] args) throws Exception{
    File file = new File("D:/Files/stream.txt");
    InputStream in = new FileInputStream(file);
    byte b1[] = new byte[(int)file.length()];
    int i = 0;
    i = in.read(b1);
    System.out.println(i);
    System.out.println(new String(b1, 0, i));

}

}
複製代碼
複製代碼
運行結果爲:

26
abcdefghijklmnopqrstuvwxyz
要區分清楚,OutputStream的作用是將內容由Java內存輸出到文件中、InputStream是將內容由文件輸入到Java內存中。read(byte b[])方法之前講明瞭,表示"試圖讀取buffer.length個字節到buffer中,並返回實際讀取的字節數",返回的是實際字節的大小。

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