概述
IO流是數據的流從源頭流到目的地。流(Stream)是一組有順序,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。即數據在倆設備之間的傳輸稱爲流,流的本質是數據傳輸。
分類
- 按照操作數據類型的不同分爲兩種:字節流和字符流。
字節流:字節流主要是操作byte類型數據。
字符流:因爲數據編碼的不同,而有了對字符進行高效操作的流對象,其本質就是基於字節流讀取時,去查了指定的碼錶。
區別:
(1) 讀寫單位不同:字節流以字節(8bit)爲單位,字符流以字符爲單位,根據碼錶映射字符,一次可能讀多個字節。
(2)處理對象不同:字節流能處理所有類型的數據,字符流只能處理字符類型的數據。
(3)字節流操作的時候不會用到緩衝區,是對文件本身直接操作。而字符流在操作的時候會用到緩衝區,通過緩衝區操作文件。
- 流按照數據流向的不同分爲:輸出流和輸入流。
輸入流:從文件中讀到程序中。
輸入流:從程序中寫到文件中。
這裏輸出流和輸入流的參照物是程序
字節流
字節流基類
-
InputStream:是所有字節輸入流的父類。首先看InputStream的定義:
public abstract class InputStream extends Object implements Closeable
可以看出它是一個抽象類,如果想要使用此類,首先必須通過子類實例化對象,如果要操作一個文件的話,則可以使用:FileInputStream類,通過向上轉型之後,可以爲InputStream實例化。
InputStream的常用方法:
//從輸入流中讀取數據的下一個字節
abstract int read()
// 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b中
int read(byte[] b)
// 將輸入流中最多 len 個數據字節讀入 byte 數組
int read(byte[] b, int off, int len)
// 關閉此輸入流並釋放與該流關聯的所有系統資源
void close()
-
OutputStream:字節輸出流的最大父類,OutputStream的定義:
public abstract class InputStream extends Object implements Closeable
它與InputStream一樣,是個抽象類,必須依靠其子類來實例化。
OutputStream的常用方法:
//將b.length個字節從指定的byte數組寫入此輸出流
void write(byte[] e)
// 將指定的字節寫入此輸出流
abstract void write(int b)
// 關閉此輸入流並釋放與該流關聯的所有系統資源
void close()
// 刷新此輸出流並強制寫出所有緩衝的輸出字節
void flush()
字節文件操作流
- FileInputStream:字節文件輸入流,從系統中的某個文件中獲得輸入字節,用於讀取諸如圖像數據之類的原始字節。
構造方法:
//通過打開到一個實際文件的連接來創造FileInputStream,該文件通過文件系統File對象file指定
FileInputStream(File file)
//通過打開到一個實際文件的連接來創造FileInputStream,該文件通過文件系統中路徑name指定
FileInputStream(String name)
常用方法:覆蓋和重寫了父類的方法。
例子:
在f盤的hello文件下新建一個文本,內容爲ABCD。
// 讀取f盤下該文件f://hello/test.txt
//構造方法1
File file = new ("f://hello//test.txt");
InputStream inputStream = new FileInputStream(file);
int i = 0;
//一次讀取一個字節
while((i=inputStream.read()) != -1){
//System.out.print(i +" ");//輸出65 66 67 68
//爲什麼會輸出65 66 67 68?因爲字符在底層存儲的時候就是存儲的數值。即字符對應的ASCII碼
System.out.print((char)i + " "); //輸出A B C D
//關閉IO流
inputStream.close();
}
// 讀取f盤下該文件f://hell/test.txt
//構造方法2
InputStream inputStream2 = new FileInputStream("f://hello/test.txt");
// 字節數組
byte[] b = new byte[2];
int i2 = 0;
// 一次讀取一個字節數組
while ((i2 = inputStream2.read(b)) != -1) {
System.out.print(new String(b, 0, i2) + " ");// AB CD
}
//關閉IO流
inputStream2.close();
- FileOutputStream:字節文件輸出流,用於將數據寫入到File,從程序中寫入到其他位置。
構造方法:
//創建一個向指定File對象表示的文件中寫入數據的文件輸出流
FileOutputStream(File file)
//創建一個向指定File對象表示的文件中寫入數據的文件輸出流
FileOutputStream(File file, boolean append)
//創建一個向具有指定名稱的文件中寫入數據的文件輸出流
FileOutputStream(String name)
//創建一個向具體有指定name的文件寫入數據的文件輸出流
FileOutputStream(String name, boolean append)
有兩個構造方法各多了一個boolean參數append。append參數爲true時,數據從文件尾部寫入;append參數爲false時,數據覆蓋原文件。
常用方法:覆蓋和重寫了父類的方法。
例子:
OutputStream outputStream = new FileOutputStream("d://test.txt");
//寫出數據
outputStream.write("ABCD".getBytes());
//關閉IO流
outputStream.close();
//內容追加寫入
OutputStream outputStream2 = new FileOutputStream("d://test.txt", true);
//輸出換行符
outputStream2.write("\r\n".getBytes());
//輸出追加內容
outputStream2.write("hello".getBytes());
//關閉IO流
ouputStream2.close();
注意:輸出的目的地文件不存在,則會自動創建,不指定盤符的話,默認創建在項目目錄下;輸出換行符時一定要寫\r\n不能只寫\n,因爲不同文本編輯器對換行符的識別存在差異性。
字節緩衝流
- BufferInputStream:字節緩衝輸入流,提高了讀寫效率。
構造方法:
//創建一個BufferInputStream並保存參數,即輸入流in,以便將來使用。
BufferInputStream(InputStream in)
// // 創建具有指定緩衝區大小的 BufferedInputStream並保存其參數,即輸入流in以便將來使用
BufferInputStream(InputStream in, int size)
從構造方法中我們可以知道BufferedInputStream沒有無參構造方法,它必須傳入一個InputStream(一般是FileInputStream),來一起使用,以提高讀寫效率。
例子:
InputStream in = new FileInputStream("test.txt");
// 字節緩存流
BufferedInputStream bis = new BufferedInputStream(in);
byte[] bs = new byte[20];
int len = 0;
while ((len = bis.read(bs)) != -1) {
System.out.print(new String(bs, 0, len));
// ABCD
// hello
}
// 關閉流
bis.close();
- BufferOutputStream:字節緩衝輸出流,提高了寫出效率。
構造方法:
//創建一個新的緩衝輸出流,將數據寫入指定的底層輸出流
BufferOutputStream(OutputStream out)
//創建一個新的緩衝輸出流,將具有指定緩衝區大小的數據寫入底層輸出流
BufferOutputStream(OutputStream out, int size)
常用方法:
// 將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此緩衝的輸出流
void write(byte[] b, int off, int len)
// 將指定的字節寫入此緩衝的輸出流
void write(int b)
// 刷新此緩衝的輸出流
void flush()
例子:
OutputStream outputStream = new FileOutputStream("test.txt",true);
BufferOutputStream bos = new BufferOutputStream(outputStream);
bos.write("\r\n".getBytes());
//輸出內容
bos.write("hello word!".getBytes());
//刷新此緩衝的輸出流
bos.flush();
//關閉流
bos.close();
字符流
字符流基類
- Reader:讀取字符流的抽象類
常用方法:
//讀取單個字符
int read()
//將字符讀入數組
int read(char[] cbuf)
//將字符讀入數組的某個部分
abstract int read(char[] cbuf, int off, int len)
//關閉該流並釋放與之關聯的所有資源
abstract void close()
- write:寫入字符流的抽象類
常用方法:
// 寫入字符數組
void write(char[] cbuf)
// 寫入字符數組的某一部分
abstract void write(char[] cbuf, int off, int len)
// 寫入單個字符
void write(int c)
// 寫入字符串
void write(String str)
// 寫入字符串的某一部分
void write(String str, int off, int len)
// 將指定字符添加到此 writer
Writer append(char c)
// 將指定字符序列添加到此 writer
Writer append(CharSequence csq)
// 將指定字符序列的子序列添加到此 writer.Appendable
Writer append(CharSequence csq, int start, int end)
// 關閉此流,但要先刷新它
abstract void close()
// 刷新該流的緩衝
abstract void flush()
字符轉換流
- InputStreamReader:字節流轉字符流,它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺默認的字符集。
- OutputStreamWrite:字節流轉字符流。
字符緩衝流(高效流)
- BufferReader:字符緩衝流,從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。
- BufferWrite:字符緩衝流,將文本寫入字符輸出流,緩衝各個字符,從而提供單個字符、數組和字符串的高效寫入