一、介紹
流是資料源或資料目标的輸入或輸出裝置的抽象表示。支援流輸入和輸出的主要包是java.io,但是也有其他的包,比如java.nio.file。java.io包支援兩種類型的流——包含二進制資料的位元組流和包含字元資料的字元流。
當寫資料到位元組流中時,資料會以位元組序列的形式寫到流中,與它們在記憶體中的形式完全一樣,在這個過程中不會發生資料轉換。即java.io包中的InputStream和OutputStream的派生類,通常用來讀取二進制資料,如圖像和聲音。
将字元串作為字元資料讀入流時,預設Unicode字元會首先被自動轉化成主機的本地字元表示,之後再寫到流中。包括Reader和Writer類。字元流用于存儲和提取文本,也可以使用字元流讀取由非java程式建立的文本檔案。
但是,Read和Write并不是取代InputStream和OutputStream,有時,你還必須同時使用"基于byte的類"和"基于字元的類"。為此,它還提供了兩個"擴充卡(adapter)"類。InputStreamReader負責将InputStream轉化成Reader,而OutputStreamWriter則将OutputStream轉化成Writer。
二、位元組流
包java.io中的兩個類InputStream和OutputStream,java基于他們對流I/O操作提供支援。InputStream和OutputStream都是抽象類,無法建立執行個體,但是可以用于派生具有更加實際輸入輸出功能的類。這兩個類都實作了Closeable接口,而Closeable接口隻聲明了方法close()——關閉流并且釋放流對象儲存的所有資源。
1、InputStream類
InputStream包含三個read()方法用于從流中讀取資料:
public abstract int read(); 抽象方法,以int類型傳回流中可用的下一個位元組。讀取到末尾,傳回-1。
public int read(byte[] array); 該方法從流中讀取位元組填充到數組array的連續元素中,最大讀取長度為array.length個位元組。讀取到末尾,傳回-1。
public int read(byte[] array, int offset, int length); 該方法從流中讀取length長度的位元組填充到數組array中,将array[offset]作為存放起始位置。讀取到末尾,傳回-1。
public int available(); 傳回輸入流中可以讀取的位元組數。注意:若輸入阻塞,目前線程将被挂起,如果InputStream對象調用這個方法的話,它隻會傳回0,這個方法必須由繼承InputStream類的子類對象調用才有用。
public long skip(long n); 忽略輸入流中的n個位元組,傳回值是實際忽略的位元組數, 跳過一些位元組再讀取。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
InputStream類的派生類結構:
2、OutputStream類
OutputStream提供了3個write()方法來輸出資料,和InputStream相對應:
public abstract void write(int b); 先将int轉換成byte類型,把低位元組寫入到輸出流中。
public void write(byte[] array); 将數組array中的位元組寫到輸出流。
public void write(byte[] array, int offset, int length); 将數組array中從array[offset]開始的length個位元組寫到輸出流。
public void flush(); 将資料緩沖區中資料全部輸出,并清空緩沖區。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
OutputStream類的派生類結構:
3、FileInputStream類
FileInputStream類是InputStream類的子類,用來處理以檔案作為資料輸入源的資料流。
使用方法:
方式1:
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream(fin);
方式2:
FileInputStream in=new FileInputStream("d: /abc.txt");
方式3:
構造函數将 FileDescriptor()對象作為其參數。
FileDescriptor() fd=new FileDescriptor();
FileInputStream f2=new FileInputStream(fd);
如果發生I/O類型錯誤,會抛出IOException類型的異常。
4、FileOutputStream類
FileOutputStream類用來處理以檔案作為資料輸出目的資料流;一個表示檔案名的字元串,也可以是File或FileDescriptor對象。
建立一個檔案流對象方法:
方式1:
File f=new File("d:/abc.txt");
FileOutputStream out=new FileOutputStream (f);
方式2:
FileOutputStream out=new
FileOutputStream("d:/abc.txt");
方式3:構造函數将 FileDescriptor()對象作為其參數。
FileDescriptor() fd=new FileDescriptor();
FileOutputStream f2=new FileOutputStream(fd);
方式4:構造函數将檔案名作為其第一參數,将布爾值作為第二參數。
FileOutputStream f=new FileOutputStream("d:/abc.txt",true);
如果發生I/O類型錯誤,會抛出IOException類型的異常。
使用過程:
(1)生成檔案流對象(對檔案讀操作時應該為FileInputStream類,而檔案寫應該為FileOutputStream類);
(2)調用FileInputStream或FileOutputStream類中的功能函數如read()、write(int b)等)讀寫檔案内容;
(3)關閉檔案close()。
注意:
(1)檔案中寫資料時,若檔案已經存在,則覆寫存在的檔案;
(2)的讀/寫操作結束時,應調用close方法關閉流。
例子:利用FileInputStream讀取一個檔案,并存入緩存中,然後通過FileOutputStream寫到一個新的檔案
1 import java.io.*;
2
3 public class FileStreamDemo {
4 public static void main(String[] args) throws IOException {
5
6 //建立兩個檔案,face.gif是已經存在檔案,newFace.gif是新建立的檔案
7 File inFile = new File("1.gif");
8 File outFile = new File("new1.gif");
9
10 //建立流檔案讀入與寫出類
11 FileInputStream inStream = new FileInputStream(inFile);
12 FileOutputStream outStream = new FileOutputStream(outFile);
13
14 //通過available方法取得流的最大字元數
15 byte[] b = new byte[inStream.available()];
16 inStream.read(b); //讀入流,儲存在byte數組
17 outStream.write(b); //寫出流,儲存在檔案newFace.gif中
18
19 inStream.close();
20 outStream.close();
21 }
22 }
5、File類
File類與InputStream / OutputStream類同屬于一個包,它不允許通路檔案内容。
File類主要用于命名檔案、查詢檔案屬性和處理檔案目錄。
6、從一個流構造另一個流
java的流類提供了結構化方法,如,底層流和高層過濾流。而高層流不是從輸入裝置讀取,而是從其他流讀取。同樣高層輸出流也不是寫入輸出裝置,而是寫入其他流。
使用"分層對象(layered objects)",為單個對象動态地,透明地添加功能的做法,被稱為Decorator Pattern。Decorator模式要求所有包覆在原始對象之外的對象,都必須具有與之完全相同的接口。這使得decorator的用法變得非常的透明--無論對象是否被decorate過,傳給它的消息總是相同的。這也是Java I/O類庫要有"filter(過濾器)"類的原因:抽象的"filter"類是所有decorator的基類。Decorator模式常用于如下的情形:如果用繼承來解決各種需求的話,類的數量會多到不切實際的地步。Java的I/O類庫需要提供很多功能的組合,于是decorator模式就有了用武之地。
為InputStream和OutputStream定義decorator類接口的類,分别是FilterInputStream和FilterOutputStream。
FilterInputStream的種類:
DataInputStream:與DataOutputStream配合使用,這樣你就能以一種"可攜帶的方式(portable fashion)"從流裡讀取primitives了(int,char,long等)
BufferedInputStream:用這個類來解決"每次要用資料的時候都要進行實體讀取"的問題。意思是"用緩沖區"。
LineNumberInputStream:跟蹤輸入流的行号;有getLineNumber( )和setLineNumber(int)方法
PushbackInputStream:有一個"彈壓單位元組"的緩沖區(has a one byte push-back buffer),這樣你就能把最後讀到的那個位元組再壓回去了。
FilterOutputStream的種類:
DataOutputStream:與DataInputStream配合使用,這樣你就可以用一種"可攜帶的方式(portable fashion)"往流裡寫primitive了(int, char, long,等)
PrintStream:負責生成帶格式的輸出(formatted output)。DataOutputStrem負責資料的存儲,而PrintStream負責資料的顯示。
BufferedOutputStream:用 這個類解決"每次往流裡寫資料,都要進行實體操作"的問題。也就是說"用緩沖區"。用flush( )清空緩沖區。
7、BufferedInputStream類
BufferedInputStream與BufferedOutputStream可以為InputStream、OutputStream類的對象增加緩沖區功能。建構BufferedInputStream執行個體時,需要給定一個InputStream類型的執行個體,實作BufferedInputStream時,實際上最後是實作InputStream執行個體。同樣地,在建構BufferedOutputStream時,也需要給定一個OutputStream執行個體,實作BufferedOutputStream時,實際上最後是實作OutputStream執行個體。
BufferedInputStream的資料成員buf是一個位數組,預設為2048位元組。當讀取資料來源時,例如檔案,BufferedInputStream會盡量将buf填滿。當使用read()方法時,實際上是先讀取buf中的資料,而不是直接對資料來源作讀取。當buf中的資料不足時,BufferedInputStream才會再實作給定的InputStream對象的read()方法,從指定的裝置中提取資料。
方式1:
File srcFile = new File(args[0]);
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile));
建立
BufferedInputStream
并儲存其參數,即輸入流
in
,以便将來使用。建立一個内部緩沖區數組并将其存儲在
buf
中。
方式2:
File srcFile = new File(args[0]);
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile),1024);
建立具有指定緩沖區大小的
BufferedInputStream
,并儲存其參數,即輸入流
in
,以便将來使用。建立一個長度為
size
的内部緩沖區數組并将其存儲在
buf
中。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
8、BufferedOutputStream類
BufferedOutputStream的資料成員buf是一個位數組,預設為512位元組。當使用write()方法寫入資料時,實際上會先将資料寫至buf中,當buf已滿時才會實作給定的OutputStream對象的write()方法,将buf資料寫至目的地,而不是每次都對目的地作寫入的動作。
方式1:
File desFile = new File(args[1]);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFile));
建立一個新的緩沖輸出流,以将資料寫入指定的基礎輸出流。
方式2:
File desFile = new File(args[1]);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFile),1024);
建立一個新的緩沖輸出流,以将具有指定緩沖區大小的資料寫入指定的基礎輸出流。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
例子:使用BufferedInputStream和BufferedOutputStream複制BuffferedStreamDemo.java的内容至BufferedStreamDemo.txt檔案并顯示輸出
1 import java.io.*;
2
3 public class BufferedStreamDemo {
4
5 public static void main(String[] args){
6 try{
7 byte[] data=new byte[1];
8
9 File srcFile=new File("BufferedStreamDemo.java");
10 File desFile=new File("BufferedStreamDemo.txt");//聲明兩個檔案執行個體
11
12 BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(srcFile));//執行個體化BufferedInputStream
13 BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(desFile));//執行個體化BufferedOutputStream
14
15 System.out.println("複制檔案: "+srcFile.length()+"位元組");
16 //将從BufferedStreamDemo.java檔案讀取的位元組寫到data,然後再寫到BufferedStreamDemo.txt
17 while(bufferedInputStream.read(data)!=-1){
18 bufferedOutputStream.write(data);
19 }
20
21 //将緩沖區中的資料全部寫出
22 bufferedOutputStream.flush();
23
24 System.out.println("複制完成");
25
26 //顯示輸出BufferedStreamDemo.txt檔案的内容
27 bufferedInputStream =new BufferedInputStream(new FileInputStream(new File("BufferedStreamDemo.txt")));
28 while(bufferedInputStream.read(data)!=-1){
29 String str=new String(data);
30 System.out.print(str);
31 }
32
33 bufferedInputStream.close();
34 bufferedOutputStream.close();
35
36 }catch(ArrayIndexOutOfBoundsException e){
37 System.out.println("using: java useFileStream src des");
38 e.printStackTrace();
39 }catch(IOException e){
40 e.printStackTrace();
41 }
42 }
43 }
9、DataInputStream類
DataInputStream和DataOutputStream可提供一些對Java基本資料類型寫入的方法,像讀寫int、double和boolean等的方法。由于Java的資料類型大小是規定好的,在寫入或讀出這些基本資料類型時,就不用擔心不同平台間資料大小不同的問題。
有時沒有必要存儲整個對象的資訊,而隻是要存儲一個對象的成員資料,成員資料的類型假設都是Java的基本資料類型,這樣的需求不必使用到與Object輸入、輸出相關的流對象,可以使用DataInputStream、DataOutputStream來寫入或讀出資料。
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(args[0]));
方法:
public String readUTF(); 讀入一個已使用UTF-8修改版格式編碼的字元串
public String readLine(); 是通過
BufferedReader.readLine()實作的。
public boolean readBoolean;
public int readInt();
public byte readByte();
public char readChar(); 等等一系列讀取基本資料類型的方法
如果發生I/O類型錯誤,會抛出IOException類型的異常。
10、DataOutputStream類
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(args[0]));
方法:
public void writeBoolean(boolean b); 将一個boolean值以1-byte形式寫入基本輸出流。
public void writeByte(int v); 将一個byte值以1-byte值形式寫入到基本輸出流中。
public void writeBytes(String s); 将字元串按位元組順序寫入到基本輸出流中。
public void writeChar(int v); 将一個char值以2-byte形式寫入到基本輸出流中。先寫入高位元組。
public void writeInt(int v); 将一個int值以4-byte值形式寫入到輸出流中先寫高位元組。
public void writeUTF(String str); 以機器無關的的方式用UTF-8修改版将一個字元串寫到基本輸出流。該方法先用writeShort寫入兩個位元組表示後面的位元組數。
public int size(); 傳回written的目前值。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
例子:先用DataOutputStream想文本寫入各種類型資料,再用DataInputStream從中讀取各種類型資料。
1 import java.io.*;
2
3 public class DataInputStreamDemo {
4
5 private static final int LEN = 5;
6
7 public static void main(String[] args) {
8 // 測試DataOutputStream,将資料寫入到輸出流中。
9 testDataOutputStream() ;
10 // 測試DataInputStream,從上面的輸出流結果中讀取資料。
11 testDataInputStream() ;
12 }
13
14 /**
15 * DataOutputStream的API測試函數
16 */
17 private static void testDataOutputStream() {
18
19 try {
20 File file = new File("file.txt");
21 DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
22
23 out.writeBoolean(true);
24 out.writeByte((byte)0x41);
25 out.writeChar((char)0x4243);
26 out.writeShort((short)0x4445);
27 out.writeInt(0x12345678);
28 out.writeLong(0x0FEDCBA987654321L);
29 out.writeUTF("abcdefghijklmnopqrstuvwxyz嚴12");
30
31 out.close();
32 } catch (FileNotFoundException e) {
33 e.printStackTrace();
34 } catch (IOException e) {
35 e.printStackTrace();
36 }
37 }
38 /**
39 * DataInputStream的API測試函數
40 */
41 private static void testDataInputStream() {
42
43 try {
44 File file = new File("file.txt");
45 DataInputStream in =
46 new DataInputStream(
47 new FileInputStream(file));
48
49 System.out.printf("byteToHexString(0x8F):0x%s\n", byteToHexString((byte)0x8F));
50 System.out.printf("charToHexString(0x8FCF):0x%s\n", charToHexString((char)0x8FCF));
51 System.out.printf("readBoolean():%s\n", in.readBoolean());
52 System.out.printf("readByte():0x%s\n", byteToHexString(in.readByte()));
53 System.out.printf("readChar():0x%s\n", charToHexString(in.readChar()));
54 System.out.printf("readShort():0x%s\n", shortToHexString(in.readShort()));
55 System.out.printf("readInt():0x%s\n", Integer.toHexString(in.readInt()));
56 System.out.printf("readLong():0x%s\n", Long.toHexString(in.readLong()));
57 System.out.printf("readUTF():%s\n", in.readUTF());
58
59 in.close();
60 } catch (FileNotFoundException e) {
61 e.printStackTrace();
62 } catch (IOException e) {
63 e.printStackTrace();
64 }
65 }
66
67 // 列印byte對應的16進制的字元串
68 private static String byteToHexString(byte val) {
69 return Integer.toHexString(val & 0xff);
70 }
71
72 // 列印char對應的16進制的字元串
73 private static String charToHexString(char val) {
74 return Integer.toHexString(val);
75 }
76
77 // 列印short對應的16進制的字元串
78 private static String shortToHexString(short val) {
79 return Integer.toHexString(val & 0xffff);
80 }
81 }
三、字元流
包java.io中的兩個類Reader和Writer,他們是能将位元組流以字元流方式進行讀寫的對象,是以字元流在本質上是以Reader和Writer封裝的位元組流。Reader和Writer都是抽象類,這兩個類都實作了聲明close()方法的AutoCloseable接口。
Reader和Writer類以及他們的子類本身都不是流,但是他們提供了一些方法,可用于将底層的流作為字元流讀寫。是以,通常使用底層的InputStream和OutputStream對象來建立Reader和Writer對象。
1、Reader類
還實作了Readable接口,該接口聲明了read()方法,用于将字元讀入作為參數傳入read()方法的CharBuffer對象。
public int read(); 讀取單個字元。
public int read(char[] cbuf); 讀取多個字元到字元數組cbuf。
public abstract int read(char[] cbuf,int off,int len); 讀取len個字元到字元數組cbuf中,從cbuf[off]開始存放。
public boolean ready(); 這個輸入流是否準備好了。
public void reset(); 重置輸入流。
public long skip(long n); 跳過n個字元讀取。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
Reader類的派生類結構:
2、Writer類
Writer類實作了Appendable接口,聲明了3種版本的append()方法,還有5個write()方法。
public Writer append(char c); 将字元c附加到Writer封裝的任意流後面。
public Writer append(CharSequence csq); 将CharSequence類型的參數附加到底層流的後面。
public Writer append(CharSequence csq, int start, int end); 将一個字元序列的子序列附加到底層流的後面。
public void write(int c); 寫一個單獨的字元。
public void write(String str); 寫一個字元串。
public void write(String str, int off, int len); 寫一個字元串的子串。
public void write(char[] cbuf); 寫一個字元數組。
public abstract void write(char[] cbuf, int off, int len); 寫一個字元數組的子串。
public abstract void flush(); 将資料緩沖區中資料全部輸出,并清空緩沖區。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
Writer類的派生類結構:
3、InputStreamReader類
若想對InputStream和OutputStream進行字元處理,可以使用InputStreamReader和OutputStreamWriter為其加上字元處理的功能,它們分别為Reader和Writer的子類。
舉個例子來說,若想要顯示純文字檔案的内容,不用費心地自行判斷字元編碼(例如範例14.15中要費心地自行判斷是ASCII英文字母或BIG5中文字),隻要将InputStream、OutputStream的執行個體作為建構InputStreamReader、OutputStreamWriter時的變量,就可以操作InputStreamReader和OutputStreamWriter來進行文本檔案的讀取,讓它們為您做字元判斷與轉換的動作。
如果以檔案操作為例,則記憶體中的字元資料需要通過OutputStreamWriter變為位元組流才能儲存在檔案中,讀取時需要将讀入的位元組流通過InputStreamReader變為字元流。過程如下:
寫入資料-->記憶體中的字元資料-->字元流-->OutputStreamWriter-->位元組流-->網絡傳輸(或檔案儲存)
讀取資料<--記憶體中的字元資料<--字元流<--InputStreamReader<--位元組流<--網絡傳輸(或檔案儲存)
構造方法:
public InputStreamReader(InputStream in); 建立一個使用預設字元集的 InputStreamReader。
public InputStreamReader(InputStream in, String charsetName); 建立使用指定字元集的 InputStreamReader。
public InputStreamReader(InputStream in, Charset cs); 建立使用指定字元集的 InputStreamReader。
public InputStreamReader(InputStream in, CharsetDecoder dec); 建立使用指定字元集解碼器的 InputStreamReader。
常用Charset:
US-ASCII | 7 位 ASCII 字元,也叫作 ISO646-US、Unicode 字元集的基本拉丁塊 |
ISO-8859-1 | ISO 拉丁字母表 No.1,也叫作 ISO-LATIN-1 |
UTF-8 | 8 位 UCS 轉換格式 |
UTF-16BE | 16 位 UCS 轉換格式,Big Endian(最低位址存放高位位元組)位元組順序 |
UTF-16LE | 16 位 UCS 轉換格式,Little-endian(最高位址存放低位位元組)位元組順序 |
UTF-16 | 16 位 UCS 轉換格式,位元組順序由可選的位元組順序标記來辨別 |
常用方法:
public String getEncoding(); 傳回此流使用的字元編碼的名稱。如果該編碼有曆史上用過的名稱,則傳回該名稱;否則傳回該編碼的規範化名稱。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
4、OutputStreamWriter類
構造方法:
public OutputStreamWriter(OutputStream out); 建立使用預設字元編碼的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out, String charsetName); 建立使用給定字元集的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out, Charset cs); 建立使用給定字元集的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out, CharsetEncoder enc); 建立使用給定字元集編碼器的 OutputStreamWriter。
常用方法:
public String getEncoding(); 傳回此流使用的字元編碼的名稱。如果該編碼具有曆史名稱,則傳回該名稱;否則傳回該編碼的規範化名稱。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
例子:從一個檔案中用InputStreamReader讀取,然後将位元組流轉換成字元流存在字元串數組;用OutputStreamWriter向另一個檔案寫入該數組。
1 import java.io.*;
2
3 public class InputStreamReaderDemo {
4 public static void main(String[] args) throws Exception { // 所有的異常抛出
5 File f1 = new File("helpinfo.txt");
6 File f2 = new File("test.txt");
7 Writer out = null;
8 Reader in = null;
9 out = new OutputStreamWriter(new FileOutputStream(f2));// 通過子類執行個體化父類對象,位元組流變為字元流
10 in = new InputStreamReader(new FileInputStream(f1));
11 char c[] = new char[1024];
12 in.read(c);
13 System.out.print(c);
14 out.write(c); // 使用字元流輸出
15 in.close();
16 out.close();
17 }
18 }
5、FileReader類
FileReader類建立了一個可以讀取字元流檔案内容的Reader類。
構造方法:
public FileReader(File file); 在給定從中讀取資料的 File 的情況下建立一個新 FileReader。
public FileReader(String fileName); 在給定從中讀取資料的檔案名的情況下建立一個新 FileReader。
public FileReader(FileDescripter fd); 在給定從中讀取資料的 FileDescriptor 的情況下建立一個新 FileReader。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
6、FileWriter類
FileWriter類建立一個可以用字元流寫檔案的Writer類。
構造方法:
public FileWriter(File file); 在給出 File 對象的情況下構造一個FileWriter對象。
public FileWriter(File file, boolean append); 在給出File對象的情況下構造一個FileWriter對象,如果第二個參數為
true
,則将位元組寫入檔案末尾處,而不是寫入檔案開始處。
public FileWriter(FileDescripter fd); 構造與某個檔案描述符相關聯的FileWriter對象。
public FileWriter(String fileName); 在給出檔案名的情況下構造一個FileWriter對象。
public FileWriter(String fileName, boolean append); 在給出檔案名的情況下構造 FileWriter 對象,如果第二個參數為
true
,則将位元組寫入檔案末尾處,而不是寫入檔案開始處。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
例子:從一個文本中讀取字元存在數組中,然後再再到另一個文本。
1 import java.io.*;
2
3 public class FileReaderDemo {
4 public static void main (String args[ ] ) throws Exception {
5 FileReader fr = new FileReader("helpinfo.txt");
6 FileWriter fw = new FileWriter("test.txt");
7 char data[]=new char[1024];
8 int num = fr.read(data);
9 System.out.println(num);
10 fw.write(data);
11 fr.close();
12 fw.close();
13 }
14 }
7、BufferedReader類
從字元輸入流中讀取文本,緩沖各個字元,進而提供字元、數組和行的高效讀取。可以指定緩沖區的大小,或者可使用預設的大小。大多數情況下,預設值就足夠大了。通常,Reader 所作的每個讀取請求都會導緻對基礎字元或位元組流進行相應的讀取請求。是以,建議用 BufferedReader 包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)。例如:BufferedReader in = new BufferedReader(new InputStream(System.in));
構造函數:
public BufferedReader(Reader in); 建立一個使用預設大小輸入緩沖區的緩沖字元輸入流。
public BufferedReader(Reader in, int size); 建立一個使用指定大小輸入緩沖區的緩沖字元輸入流。
常用方法:
public String readline(); 讀取一個文本行,通過下列字元之一即可認為某行已終止:換行 ('\n')、回車 ('\r') 或回車後直接跟着換行。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
8、BufferedWriter類
将文本寫入字元輸出流,緩沖各個字元,進而提供單個字元、數組和字元串的高效寫入。可以指定緩沖區的大小,或者接受預設的大小。在大多數情況下,預設值就足夠大了。該類提供了newLine() 方法,它使用平台自己的行分隔符概念,此概念由系統屬性line.separetor定義。并非所有平台都使用新行符 ('\n') 來終止各行。是以調用此方法來終止每個輸出行要優于直接寫入新行符。通常 Writer 将其輸出立即發送到基礎字元或位元組流。除非要求提示輸出,否則建議用 BufferedWriter 包裝所有其 write() 操作可能開銷很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,BufferedWriter out = new BufferedWriter(new FileWriter("test.txt"));
構造方法:
public BufferedWriter(Writer out); 建立一個使用預設大小輸出緩沖區的緩沖字元輸出流。
public BufferedWriter(Writer out, int size); 建立一個使用指定大小輸出緩沖區的新緩沖字元輸出流。
常用方法:
public void newline(); 寫入一個行分隔符。行分隔符字元串由系統屬性line.separetor定義,并且不一定是單個新行 ('\n') 符。
如果發生I/O類型錯誤,會抛出IOException類型的異常。
例子:從一個文本中讀取字元存在數組中,然後再再到另一個文本。
1 import java.io.*;
2
3 public class BufferedReaderDemo {
4
5 public static void main(String[] args) {
6 BufferedReader br = null;
7 BufferedWriter bw = null;
8
9 String b = null;
10 File file = new File("abc.txt");
11 if (!file.exists() != false) {
12 try {
13 file.createNewFile();
14 } catch (IOException e) {
15 e.printStackTrace();
16 }
17 }
18 try {
19 bw = new BufferedWriter(new FileWriter(file));
20 FileReader fr = new FileReader("helpinfo.txt");
21 br = new BufferedReader(fr);
22 while ((b = br.readLine()) != null) {
23 System.out.println(b);
24 bw.write(b); //輸出字元串
25 bw.newLine();//換行
26 bw.flush();
27 }
28 } catch (Exception e) {
29 e.printStackTrace();
30 }finally {
31 try {
32 br.close();
33 //bw.close();
34 } catch (IOException e) {
35 e.printStackTrace();
36 }
37 }
38 }
39 }
四、寫在最後
我寫這篇部落格的初衷是讓自己對java的各種I/O有一個更為清楚的認識,是以文中所舉的例子都是一些最為基礎的使用方法。由于編寫時間較短以及本人技術水準有限,是以可能會有一些遺漏和錯誤,大家也可以指出來讓我予以改正。
希望這篇部落格不僅能給我,也能給一些像我一樣對java的I/O不清楚的同學一點點幫助。
謝謝!~~~
文章來源,在此謝謝部落客http://www.cnblogs.com/FishAndWater/p/3458074.html