說起IO流,腦子裏浮現出的就是inputstream,outputstream,reader,writer之類的東西,但是,這些類我們該怎麼選擇,他們之間有什麼區別和聯繫,好多人卻不太清楚。今天就跟大家聊聊Java的IO流。
I就是input,O就是output,IO流就是輸入-輸出流。輸入和輸出就有了一個方向的問題。一般情況下,我們所說的輸入和輸出都是相對於內存來說的,從外設到內存就是輸入,從內存到外設就是輸出。這個是從流向來區分的。還可以從操作的內容來區分,就是字符流和字節流。Java中InputStream和OutputStream就是字節流,Reader和Writer就是字符流。按照流的角色,可以分爲節點流和處理流。可以從一個特定的IO設備讀寫數據的流就是節點流,處理流就是對已存在的數據流進行連接和封裝。
Java的IO流的類都存在於java.io包中,字節流的基類是InputStream和OutputStream,字符流的基類是Reader和Writer。我們通過下表來說明一下常用的類有哪些。
分類 | 字節輸入流 | 字節輸出流 | 字符輸入流 | 字符輸出流 |
抽象基類 | InputStream | OutputStream | Reader | Writer |
訪問文件 | FileInputStream | FileOutputStream | FileReader | FileWriter |
訪問數組 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
訪問字符串 | StringReader | StringWriter | ||
緩衝流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
轉換流 | InputStreamReader | InputStreamWriter | ||
對象流 | ObjectInputStream | ObjectOutputStream |
在我們的實際工作中,最常用的就是FileReader、FileWriter來操作文件,但是兩個在讀取的時候只能一個字符一個字符去讀,如果想讀一行怎麼辦呢?使用BufferedReader和BufferedWriter,他們是具有緩衝的IO流,在讀寫文件的實現,先去操作緩衝區,緩衝區滿了,再一次性的寫入IO設備,此時要注意調用flush方法,否則不會自動寫入IO設備中。
如下是FileReader和FileWriter的示例,在操作結束之後,一定要調用close方法,否則會發生內存泄露。一般情況下都使用try。。。catch。。。finally來實現。
FileWriter fw = null;
FileReader fr = null;
try {
//創建寫文件
fw = new FileWriter(new File("1.txt"));
//向文件中寫入字符串
fw.write("hello,welcome");
//調用flush方法,將內容寫到文件
fw.flush();
//創建讀文件
fr = new FileReader(new File("1.txt"));
//創建緩衝區,用於接收讀取的字符
char[] buffer = new char[8];
StringBuilder sb = new StringBuilder();
//nRead爲讀取到的字符,調用read方法,返回讀取到的字符個數,如果讀取結束,返回-1
int nRead = 0;
while( (nRead = fr.read(buffer)) != -1) {
sb.append(new String(buffer,0,nRead));
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
//關閉資源
if(fw != null) {
fw.close();
fw = null;
}
if(fr != null) {
fr.close();
fr = null;
}
}
BufferedReader和BufferedWriter的使用方法也是類似的。BufferedReader可以讀取一行數據。
BufferedWriter bw = null;
BufferedReader br = null;
try {
//創建寫文件
bw = new BufferedWriter(new FileWriter("1.txt"));
//向文件中寫入字符串
bw.write("hello,welcome");
//調用flush方法,將內容寫到文件
bw.flush();
//創建讀文件
br = new BufferedReader(new FileReader("1.txt"));
StringBuilder sb = new StringBuilder();
String str = null;
while( (str = br.readLine()) != null) {
sb.append(str);
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
//關閉資源
if(bw != null) {
bw.close();
bw = null;
}
if(br != null) {
br.close();
br = null;
}
}
初次之外,DataInputStream和DataOutputStream也是需要了解的。他們是用來對對象進行序列化的,可將一個對象已二進制的方式,寫入文件,通過網絡等方式進行傳輸後,再進行反序列化。操作的對象一定要實現java.io.Serializable接口。
以上,就是JDK提供的一些Java IO流的基本用法。在工作中,要學會使用一些工具類來簡化操作,如apache的FileUtils類,IOUtils類等。在JDK1.5還有了NIO,也就是非阻塞的IO流。包括一些Netty、Mina等NIO的框架也有待於大家的瞭解。