Java中的輸入輸出流根據格式又可以分為字節流和字符流:(成對)
字節流:FileInputStream,FileOutputStream ; BufferedInputStream,BufferedOutputStream ;
字符流:FileReader,FileWriter ; BufferedReader,BufferedWriter
字符流和字節流的主要區別:
1.字節流讀取的時候,讀到一個字節就返回一個字節;(一個英文字符是一個字節);字符流使用了字節流讀到一個或多個字節(一個中文是兩個字節,在UTF-8碼表中是3個字節,這要看編碼方式,不同的編碼中文是不同的大小)時。先去查指定的編碼表,將查到的字符返回。
2.字節流可以處理所有類型數據,如:圖片,MP3,AVI視頻文件,而字符流只能處理字符數據。只要是處理純文本數據,就要優先考慮使用字符流,除此之外都用字節流。
下面根據字節流和字符流來依次說明:
字節流:
1. FileInputStream,FileOutputStream( 這兩個都是成對出現,前者進行輸入(讀文件)操作,后者進行輸出(寫文件)操作)
FileInputStream類稱為文件輸入流。它的作用是將文件中的數據輸入到內存中,我們可以利用它來讀文件。由於它屬於字節流,因此在讀取Unicode字符(如中文)的文件時可能會出現問題。
該類的構造方法:
·FileInputStream(File file):打開一個到實際文件的連接來創建一個FileInputStream,該文件通過文件系統中的File對象file指定。
·FileInputStream(String name):打開一個到實際文件的連接來創建一個FileInputStream,該文件通過文件系統中的路徑名name指定。
這里提一下File類,File類的對象不但可以表示文件,還可以表示目錄;當創建一個文件對象后,就可以利用它來對文件或目錄的屬性進行操作,如:文件名、最后修改日期、文件大小等等;需要注意的是,File對象並不能直接對文件進行讀/寫操作,只能查看文件的屬性;創建格式:File file = new File("test.txt");
FileOutputStream類稱為文件輸出流,他的作用是將數據寫到文件中,我們可以利用它來寫文件。
該類的構造方法:
·FileOutputStream(File file):創建一個向指定File對象表示的文件中寫入數據的文件輸出流。
·FileOutputStream(String name):創建一個向具有指定名稱的文件中寫入數據的輸出文件流。
常用到的方法:
·void write(byte[] b):將b.length個字節從指定byte數組寫入此文件輸出流中。
·void write(byte[] b,int off,int len):將指定byte數組中從偏移量off開始的len個字節寫入此文件輸出流。
·void write(int b):將指定字節寫入此文件輸出流。
2. BufferedInputStream,BufferedOutputStream(這對可以和上面一組對比着看,主要就是相差了一個緩沖區)
BufferedInputStream類稱為緩沖輸入流,其本身帶有一個緩沖區,在讀取數據時,先放到緩沖區中,可以減少對數據源的訪問,提高運行的效率。
構造方法:
·BufferedInputStream(InputStream in):創建一個BufferedInputStream並保存其參數,即輸入流in,以便將來使用。
·BufferedInputStream(InputStream in,int size):創建一個具有指定緩沖區大小的BufferedInputStream並保存其參數,即輸入流in,以便將來使用。
常用方法:
·int read():從輸入流中讀取數據的下一個字節。
·int read(byte[] b,int off,int len):從此字節輸入流中給定偏移量處開始將各字節讀取到指定的byte數組中。
BufferedOutputStream類稱為緩沖輸出流,其本身也帶有一個緩沖區,在寫入數據時,先放到緩沖區中,實現緩沖的數據流。要注意在使用BufferedOutputStream
寫完數據后,要調用flush()
方法或close()
方法,強行將緩沖區中的數據寫出。否則可能無法寫出數據。
構造方法:
·BufferedOutputStream(OutputStream out):創建一個新的緩沖輸出流,來將數據寫入指定的底層輸入流。
·BufferedOutputStream(OutputStream out,int size):創建一個新的緩沖輸出流,來將具有指定緩沖區大小的數據寫入指定的底層輸出流。
常用方法:
·void flush():刷新此緩沖的輸出流。
·void write(byte[] b,int off,int len):將指定byte數組中從偏移量off開始的len個字節寫入此緩沖的輸出流。
·void write(int b):將指定的字節寫入此緩沖的輸出流。
字符流:
FileReader,FileWriter ; BufferedReader,BufferedWriter(放在一起說)
FileReader類稱為文件讀取流,允許以字符流的形式對文件進行讀操作(該類將從文件中逐個地讀取字符,效率比較低下,因此一般將該類對象包裝到緩沖流中進行操作。BufferedReader類主要為字符流提供緩沖,所以FileReader一般配合BufferReader來用)
構造方法:
FileReader(String fileName)
FileReader(File file)
常用方法://都是繼承自Reader的方法
int read()
int read(char[] b)
int read(char[] b , int off ,int len)
FileWriter類稱為文件寫入流,以字符流的形式對文件進行寫操作與FileReader類相似,FileWriter類同樣需要使用緩沖流進行包裝,所以FileWriter一般配BufferedWriter來用
構造方法:
FileWriter(String fileName)
FileWriter(String fileName, boolean append) //boolean append是否在原有基礎上繼續寫
FileWriter(File file)
FileWriter(File file, boolean append)//boolean append是否在原有基礎上繼續寫
常用方法:
void write(char[] b)
void write(char[] b, int off, int len)
void write(int b)
void write(String str)
void write(String str, int off, int len)
Writer append(char c)
Writer append(CharSequence csq)
Writer append(CharSequence csq, int start, int end)
為了提高字符流讀寫的效率,引入了緩沖機制,進行字符批量的讀寫,提高了單個字符讀寫的效率。BufferedReader用於加快讀取字符的速度,BufferedWriter用於加快寫入的速度。BufferedReader和BufferedWriter類各擁有8192個字符的緩沖區。當BufferedReader在讀取文本文件時,會先盡量從文件中讀入字符數據並放滿緩沖區,而之后若使用read()方法,會先從緩沖區中進行讀取。如果緩沖區數據不足,才會再從文件中讀取,使用BufferedWriter時,寫入的數據並不會先輸出到目的地,而是先存儲至緩沖區中。如果緩沖區中的數據滿了,才會一次對目的地進行寫出。
BufferedReader
是為了提供讀的效率而設計的一個包裝類,它可以包裝字符流。可以從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。
構造方法:
BufferedReader(Reader in) //創建一個使用默認大小輸入緩沖區的緩沖字符輸入流。
BufferedReader(Reader in, int sz) //
創建一個使用指定大小輸入緩沖區的緩沖字符輸入流。
常用方法:
int read() //讀取單個字符。
int read(char[] cbuf, int off, int len) //將字符讀入數組的某一部分。
String readLine() //讀取一個文本行。(不包括換行符)
BufferedWriter:
構造方法:
BufferedWriter(Writer out) //創建一個緩沖字符輸出流,使用默認大小的輸出緩沖區
BufferedWriter(Writer out, int sz) //創建一個緩沖字符輸出流,使用給定大小的輸出緩沖區
常用方法:
void write(int c) //寫入單個字符。
void write(char[] cbuf, int off, int len) //寫入字符數組的某一部分。
void write(String s, int off, int len) //寫入字符串的某一部分。
void newLine() //寫入一個行分隔符。
void close() //關閉此流,但要先刷新它
void flush() //刷新該流的緩沖
亂碼問題:
雖然前面提到處理純文本數據,就要優先考慮使用字符流,但是考慮到編碼的因素,可以使用包裝InputStreamReader
的BufferedReader
,包裝OutputStreamWriter
的BufferedWriter
來復制文件,好處就是可以指定復制文件的時候使用的字符編碼使不產生亂碼。下面講一下InputStreamReader
和OutputStreamWriter
:
InputStreamReader:
它使用指定的字符集讀取字節並將它們解碼為字符。 它使用的字符集可以通過名稱指定,也可以明確指定,或者可以接受平台的默認字符集。每次調用一個InputStreamReader的read()方法都可能導致從底層字節輸入流中讀取一個或多個字節。為了獲得最高效率,通常在BufferedReader中包裝InputStreamReader。
使用格式: BufferedReader
reader = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile),"UTF-8"));
OutputStreamWriter:
它使用指定的字符集將字符編碼為字節(是
InputStreamReader的逆過程
)。它的字符集可以由名稱指定,也可以接受平台的默認字符集。
使用格式:
BufferedWriter
writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(destFile),
"UTF-8"
));