1.流的定義和分類
流代表經過管道流通的數據。把不同的輸入和輸出源抽象表述為流。
按“數據流的方向”——輸入流和輸出流(以程序為參照物)
按“處理數據單位”——字節流和字符流(圖片等多媒體等原始字節信息用自己流,文件等字符信息用字符流)
按“功能”——節點流和處理流
2.java.io包(所有流都繼承以下抽象流類型)
|
字節流(8bit) |
字符流(16bit) |
輸入流(向程序輸入) |
InputStream |
Reader |
輸出流 |
OutputStream |
Writer |
InputStream(Reader類似)
int read() //讀取一個字節并以整數的形式返回,已到輸入流結尾返回-1
int read(byte[] buffer) //讀取一系列字節并存儲到一個數組buffer,返回讀取的字節數
int read(byte[] buffer, int offset, int length) //讀取length個字節,并存儲到buffer,從offset開始,…
long skip(long n) //跳過n個字節不讀,返回實際跳過的字節數
void close()
OutputStream(Writer類似)
void write(int b) //向輸出流,寫入一個字節數據,該字節數據未參數b的低8位
void write(byte[] b) //將一個字節類型的數組中的數據寫入輸出流
void write(byte[] b, int off, int len) //將字節類型的數組從off開始的len個字節寫入輸出流
void flush() //將輸出流中緩存的數據全部寫出到目的地
3.字節流和處理流
節點流——可以從一個特定的數據源(節點)讀取數據(如:文件、內存)
處理流——是“連接”在已存在的流(節點流或處理流)之上,通過對數據的處理為程序提供更為強大的讀寫功能
常用處理流:緩沖流、轉換流、數據流、Print流、Object流
-------------------------------------
ByteArrayInputStream 把內存的一個緩沖區作為InputStream使用
StringBufferInputStream 把一個String對象作為InputStream
FileInputStream 把一個文件作為InputStream,實現對文件的讀取操作
DataInputStream 從stream中讀取基本類型數據
BufferedInputStream 使用緩沖區讀取字節數據
PrintStream 產生格式化輸出
4.如何判斷讀取文件是否到達末尾?
InputStream/Reader的read()返回-1
BufferedReader返回null
InputStream示例代碼:
<!--WizRtf2Html Charset=0 --> int temp = -1;
while((temp = bufferedInputStream.read()) != -1) {
System.out.println((char)temp);
}
BufferedReader示例代碼:
<!--WizRtf2Html Charset=0 --> String s = null;
while((s = bufferdeReader.readLine()) != null) {
System.out.println(s);
}
5.如何讀文件,寫文件?
// 讀文件
---字節
int temp = -1;
while((temp = bufferedInputStream.read()) != -1) {
System.out.println((char)temp);
}
---字符
String temp = null;
while((temp = bufferdeReader.readLine()) != null) {
System.out.println(temp);
}
// 寫文件
---字節
bufferedOutputStream.writr('A');
---字符
printWriter.print("格式化輸出");
6.如何實現在文件的任意位置進行讀寫?
RandomAccessFile,特殊文件流,實現了DataInput/out接口因此可以讀取寫入文件。
RandomAccessFile通過一個文件指針來確定讀取位置,默認文件開始處。指針可通過getFilePointer()獲取,通過seek()設置。
構造方法RandomAccessFile(File file,String mode)/RandomAccessFile(String name, String mode)
r rw rws(要求更新要寫入的文件內容及其數據) rwd(用于減少執行的IO操作數量,僅要求更新寫入存儲的文件內容)
7.使用Buffered緩沖流寫文件,為什么內容沒有寫入?
在使用緩沖流寫文件時,先將信息吸入緩沖區,如果不顯示調用flush和close則無法將緩沖區信息輸出到目標地點,因此文件為空。
OutputStream和Writer輸出流中,都有flush和close。
flush用于刷新輸出流并強制系寫出所有緩沖的輸出的字節
close方法用于關閉輸出流并釋放與此流有關的所有資源(close會默認執行flush功能)
8.讀寫文件時為什么中文字符經常產生亂碼?
計算機只能識別二進制信息,都是以二進制形式存儲。
字符集用于描述“字符”和“二進制”之間的映射關系,在編碼和解碼過程中都需要遵循相同的字符集才能正確顯示。
1)由于編碼和解碼的字符集不同引起亂碼
2)API使用不當,例如InputStream讀取中文字符(2字節),InputStream會將中文字分拆成2個字節2次讀取。
9.如何解決FileReader讀取文件亂碼問題?
開發者習慣選用FileReader讀取文件,但同樣出現亂碼問題。
FileReader繼承自InputStreamReader,其實內部實現過程中完成了字節流到字符流的轉變,只不過轉換時采用的字符集為系統平臺默認的字符集。如果保持設置為UTF8,用中文操作系統(GBK)就會讀取出錯。
解決辦法,放棄FileReader,獲取Inputstream對象時顯示指定合適的字符集
10.為什么DataInputStream和DateOutputStream讀寫文件會亂碼?
該Stream可以以基本類型為單位對文件進行讀寫操作,例如寫入一個int或讀取一個boolean值。
使用DataOutputStream寫入文件中的信息,除了包含信息之前外,還有“類型標識”等,只有使用DateInputStream才能正確讀取原有信息,其他方式會產生亂碼,這也是記事本打開文件時顯示亂碼的原因。