Java 常用IO流操作詳解
1.基本概念
IO:Java對數據的操作是通過流的方式,IO流用來處理設備之間的數據傳輸,上傳文件和下載文件,Java用於操作流的對象都在IO包中。
2.IO流的分類
圖示:(主要IO流)
3.字節流
(1).字節流基類
1).InputStream
InputStream:字節輸入流基類,抽象類是表示字節輸入流的所有類的超類。
常用方法: // 從輸入流中讀取數據的下一個字節 abstract int read() // 從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 b中 int read(byte[] b) // 將輸入流中最多 len 個數據字節讀入 byte 數組 int read(byte[] b, int off, int len) // 跳過和丟棄此輸入流中數據的 n個字節 long skip(long n) // 關閉此輸入流並釋放與該流關聯的所有系統資源 void close()
2).OutputStream
OutputStream:字節輸出流基類,抽象類是表示輸出字節流的所有類的超類。
常用方法: // 將 b.length 個字節從指定的 byte 數組寫入此輸出流 void write(byte[] b) // 將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流 void write(byte[] b, int off, int len) // 將指定的字節寫入此輸出流 abstract void write(int b) // 關閉此輸出流並釋放與此流有關的所有系統資源 void close() // 刷新此輸出流並強制寫出所有緩沖的輸出字節 void flush()
(2).字節文件操作流
1).FileInputStream
FileInputStream:字節文件輸入流,從文件系統中的某個文件中獲得輸入字節,用於讀取諸如圖像數據之類的原始字節流。
構造方法: // 通過打開一個到實際文件的連接來創建一個FileInputStream,該文件通過文件系統中的File對象file指定 FileInputStream(File file) // 通過打開一個到實際文件的連接來創建一個FileInputStream,該文件通過文件系統中的路徑name指定 FileInputStream(String name) 常用方法:覆蓋和重寫了父類的的常用方法。
// 讀取f盤下該文件f://hell/test.txt
//構造方法1
InputStream inputStream = new FileInputStream(new File("f://hello//test.txt"));
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();
註: 一次讀取一個字節數組,提高了操作效率,IO流使用完畢一定要關閉。
2).FileOutputStream
FileOutputStream:字節文件輸出流是用於將數據寫入到File,從程序中寫入到其他位置。
構造方法:
// 創建一個向指定File對象表示的文件中寫入數據的文件輸出流
FileOutputStream(File file)
// 創建一個向指定File對象表示的文件中寫入數據的文件輸出流
FileOutputStream(File file, boolean append)
// 創建一個向具有指定名稱的文件中寫入數據的輸出文件流
FileOutputStream(String name)
// 創建一個向具有指定name的文件中寫入數據的輸出文件流
FileOutputStream(String name, boolean append)
常用方法:覆蓋和重寫了父類的的常用方法。
OutputStream outputStream = new FileOutputStream(new File("test.txt"));
// 寫出數據
outputStream.write("ABCD".getBytes());
// 關閉IO流
outputStream.close();
// 內容追加寫入
OutputStream outputStream2 = new FileOutputStream("test.txt", true);
// 輸出換行符
outputStream2.write("\r\n".getBytes());
// 輸出追加內容
outputStream2.write("hello".getBytes());
// 關閉IO流
outputStream2.close();
註;輸出的目的地文件不存在,則會自動創建,不指定盤符的話,默認創建在項目目錄下;輸出換行符時一定要寫\r\n不能只寫\n,因為不同文本編輯器對換行符的識別存在差異性。
(3).字節緩沖流(高效流)
1).BufferedInputStream
BufferedInputStream:字節緩沖輸入流,提高了讀取效率。
構造方法:
// 創建一個 BufferedInputStream並保存其參數,即輸入流in,以便將來使用。
BufferedInputStream(InputStream in)
// 創建具有指定緩沖區大小的 BufferedInputStream並保存其參數,即輸入流in以便將來使用
BufferedInputStream(InputStream in, int size)
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();
2).BufferedOutputStream
BufferedOutputStream:字節緩沖輸出流,提高了寫出效率。
構造方法:
// 創建一個新的緩沖輸出流,以將數據寫入指定的底層輸出流
BufferedOutputStream(OutputStream out)
// 創建一個新的緩沖輸出流,以將具有指定緩沖區大小的數據寫入指定的底層輸出流
BufferedOutputStream(OutputStream out, int size)
常用方法:
// 將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此緩沖的輸出流
void write(byte[] b, int off, int len)
// 將指定的字節寫入此緩沖的輸出流
void write(int b)
// 刷新此緩沖的輸出流
void flush()
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.txt", true));
// 輸出換行符
bos.write("\r\n".getBytes());
// 輸出內容
bos.write("Hello Android".getBytes());
// 刷新此緩沖的輸出流
bos.flush();
// 關閉流
bos.close();
4.字符流
(1).字符流基類
1).Reader
Reader:讀取字符流的抽象類.
常用方法:
// 讀取單個字符
int read()
// 將字符讀入數組
int read(char[] cbuf)
// 將字符讀入數組的某一部分
abstract int read(char[] cbuf, int off, int len)
// 跳過字符
long skip(long n)
// 關閉該流並釋放與之關聯的所有資源
abstract void close()
2).Writer
Writer:寫入字符流的抽象類.
常用方法:
// 寫入字符數組
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()
(2).字符轉換流
1).InputStreamReader
InputStreamReader:字節流轉字符流,它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺默認的字符集。
構造方法:
// 創建一個使用默認字符集的 InputStreamReader
InputStreamReader(InputStream in)
// 創建使用給定字符集的 InputStreamReader
InputStreamReader(InputStream in, Charset cs)
// 創建使用給定字符集解碼器的 InputStreamReader
InputStreamReader(InputStream in, CharsetDecoder dec)
// 創建使用指定字符集的 InputStreamReader
InputStreamReader(InputStream in, String charsetName)
特有方法:
//返回此流使用的字符編碼的名稱
String getEncoding()
//使用默認編碼
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"));
int len;
while ((len = reader.read()) != -1) {
System.out.print((char) len);//愛生活,愛Android
}
reader.close();
//指定編碼
InputStreamReader reader = new InputStreamReader(new FileInputStream("test.txt"),"utf-8");
int len;
while ((len = reader.read()) != -1) {
System.out.print((char) len);//????????Android
}
reader.close();
註:Eclipse默認使用GBK編碼,test.txt文件所以是GBK編碼,當指定utf-8編碼時所以會亂碼。
2).OutputStreamWriter
OutputStreamWriter:字節流轉字符流。
構造方法:
// 創建使用默認字符編碼的 OutputStreamWriter
OutputStreamWriter(OutputStream out)
// 創建使用給定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)
// 創建使用給定字符集編碼器的 OutputStreamWriter
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
// 創建使用指定字符集的 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)
特有方法:
//返回此流使用的字符編碼的名稱
String getEncoding()
(3).字符緩沖流(高效流)
1).BufferedReader
BufferedReader:字符緩沖流,從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。
構造方法:
// 創建一個使用默認大小輸入緩沖區的緩沖字符輸入流
BufferedReader(Reader in)
// 創建一個使用指定大小輸入緩沖區的緩沖字符輸入流
BufferedReader(Reader in, int sz)
特有方法:
// 讀取一個文本行
String readLine()
//生成字符緩沖流對象
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("test.txt")));
String str;
//一次性讀取一行
while ((str = reader.readLine()) != null) {
System.out.println(str);// 愛生活,愛Android
}
//關閉流
reader.close();
2).BufferedWriter
BufferedWriter:字符緩沖流,將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數組和字符串的高效寫入。
構造方法:
// 創建一個使用默認大小輸出緩沖區的緩沖字符輸出流
BufferedWriter(Writer out)
// 創建一個使用給定大小輸出緩沖區的新緩沖字符輸出流
BufferedWriter(Writer out, int sz)
特有方法:
// 寫入一個行分隔符
void newLine()
(4).FileReader、FileWriter
FileReader:InputStreamReader類的直接子類,用來讀取字符文件的便捷類,使用默認字符編碼。
FileWriter:OutputStreamWriter類的直接子類,用來寫入字符文件的便捷類,使用默認字符編碼。
5.高效流效率比對
讀取f盤下的一個視頻文件到項目中:文件大小29.5 MB
讀取方式一:
FileInputStream inputStream = new FileInputStream("f://滑板//HEEL_FLIP.mp4");
FileOutputStream outputStream = new FileOutputStream("HEEL_FLIP.mp4");
int len;
// 開始時間
long begin = System.currentTimeMillis();
// 一次讀取一個字節
while ((len = inputStream.read()) != -1) {
outputStream.write(len);
}
// 用時毫秒
System.out.println(System.currentTimeMillis() - begin);// 213195
//關閉流釋放資源
inputStream.close();
outputStream.close();
讀取方式二:
FileInputStream inputStream = new FileInputStream("f://滑板//HEEL_FLIP.mp4");
FileOutputStream outputStream = new FileOutputStream("HEEL_FLIP.mp4");
int len;
byte[] bs = new byte[1024];
// 開始時間
long begin = System.currentTimeMillis();
// 一次讀取一個字節數組
while ((len = inputStream.read(bs)) != -1) {
outputStream.write(bs, 0, len);
}
// 用時毫秒
System.out.println(System.currentTimeMillis() - begin);// 281
inputStream.close();
outputStream.close();
讀取方式三:
FileInputStream inputStream = new FileInputStream("f://滑板//HEEL_FLIP.mp4");
BufferedInputStream bis = new BufferedInputStream(inputStream);
FileOutputStream outputStream = new FileOutputStream("HEEL_FLIP.mp4");
BufferedOutputStream bos = new BufferedOutputStream(outputStream);
int len;
byte[] bs = new byte[1024];
// 開始時間
long begin = System.currentTimeMillis();
while ((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
}
// 用時毫秒
System.out.println(System.currentTimeMillis() - begin);// 78
bis.close();
bos.close();
註:由此可以看出高效緩沖流讀寫速度是非常快的,建議使用。
更多方法查看API
Java 常用IO流操作詳解