概述:
字符流是可以直接讀寫字符的IO流。
字符流讀取字符, 就要先讀取到字節數據, 然後轉爲字符. 如果要寫出字符, 需要把字符轉爲字節再寫出。
字符輸入流(FileReader)
概述:
FileReader類的read()方法可以按照字符大小讀取文件。
僞代碼:
FileReader fr = new FileReader("aaa.txt" );
int ch;
while ((ch = fr.read()) != -1 ) {
System.out .println((char )ch);
}
fr.close();
字符流(FileWriter)
概述:
FileWriter類的write()方法可以自動把字符轉爲字節寫出。
僞代碼:
FileWriter fw = new FileWriter("xxx.txt" );
fw.write ("aaa" );
fw.close ();
什麼情況下使用字符流?
字符流也可以拷貝文本文件, 但不推薦使用. 因爲讀取時會把字節轉爲字符, 寫出時還要把字符轉回字節。
程序需要讀取一段文本, 或者需要寫出一段文本的時候可以使用字符流。
讀取的時候是按照字符的大小讀取的,不會出現半個中文。寫出的時候可以直接將字符串寫出,不用轉換爲字節數組。
注意:
- 字符流只能拷貝純文本文件,也就是能使用 win記事本打開的文檔。
- 不可以拷貝圖片,音頻,視頻等其它文件。
- 原因: 因爲在讀的時候會將字節轉換爲字符,在轉換過程中,可能找不到對應的字符,就會用?代替,寫出的時候會將字符轉換成字節寫出去,如果是?,直接寫出,這樣寫出之後的文件就亂碼了,文件則會損壞。
字符流拷貝文件的幾種方式
自定義字符數組的拷貝:
僞代碼:
FileReader fr = new FileReader("aaa.txt" );
FileWriter fw = new FileWriter("bbb.txt" );
int len ;
char [] arr = new char [1024 *8 ];
while ((len = fr.read (arr)) != -1 ) {
fw.write (arr, 0 , len );
}
fr.close ();
高效流的拷貝(帶緩衝的字符流)
BufferedReader的read()方法讀取字符時會一次讀取若干字符到緩衝區, 然後逐個返回給程序, 降低讀取文件的次數, 提高效率。
BufferedWriter的write()方法寫出字符時會先寫到緩衝區, 緩衝區寫滿時纔會寫到文件, 降低寫文件的次數, 提高效率。
僞代碼:
BufferedReader br = new BufferedReader(new FileReader("aaa.txt" ));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt" ));
int ch;
while ((ch = br. read()) != - 1 ) {
bw . write(ch);
}
br. close();
bw . close();
字符緩衝流中特有方法:
readLine(); BufferedReader的readLine()方法可以讀取一行字符(不包含換行符號)。
newLine(); BufferedWriter的newLine()可以輸出一個跨平臺的換行符號”\r\n”。
僞代碼:
BufferedReader br = new BufferedReader(new FileReader("aaa.txt" ));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt" ));
String line;
while ((line = br. readLine()) != null ) {
bw . write(line);
bw . newLine();
}
br. close();
bw . close();
IO流之—其它流
概述:
IO流中的其它一些流,開發中用到的次數不多,也不是很難,僞代碼中添加的註解也就沒那麼詳細。
概述:使用指定的碼錶讀寫字符:
FileReader是使用默認碼錶讀取文件, 如果需要使用指定碼錶讀取, 那麼可以使用InputStreamReader(字節流,編碼表)。
FileWriter是使用默認碼錶寫出文件, 如果需要使用指定碼錶寫出, 那麼可以使用OutputStreamWriter(字節流,編碼表)。
僞代碼:
BufferedReader br =
new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt" ), "UTF-8" ));
BufferedWriter bw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt" ), "GBK" ));
int ch;
while ((ch = br. read()) != - 1 ) {
bw . write(ch);
}
br. close();
bw . close();
概述:
序列流可以把多個字節輸入流整合成一個, 從序列流中讀取數據時, 將從被整合的第一個流開始讀, 讀完一個之後繼續讀第二個, 以此類推。
僞代碼:
FileInputStream fis1 = new FileInputStream("a.txt" );
FileInputStream fis2 = new FileInputStream("b.txt" );
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
FileOutputStream fos = new FileOutputStream("c.txt" );
int b;
while((b = sis.read()) != -1 ) {
fos.write(b);
}
sis.close ();
fos.close ();
內存輸出流(ByteArrayOutputStream)
概述:
該輸出流可以向內存中寫數據, 把內存當作一個緩衝區, 寫出之後可以一次性獲取出所有數據。
使用方式:
創建對象: new ByteArrayOutputStream()
寫出數據: write(int), write(byte[])
獲取數據: toByteArray()
僞代碼:
FileInputStream fis = new FileInputStream("a.txt" );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b;
while ((b = fis.read()) != -1 ) {
baos.write(b);
}
System.out .println(baos);
fis.close();
隨機訪問流(RandomAccessFile)
概述:
RandomAccessFile類不屬於流,是Object類的子類。但它融合了InputStream和OutputStream的功能。
支持對隨機訪問文件的讀取和寫入。
概述:
對象操作流,也叫序列化流。該流可以將一個對象寫出, 或者讀取一個對象到程序中. 也就是執行了序列化和反序列化的操作。
注意:
要寫出的對象必須實現Serializable接口才能被序列化。
不用必須加id號。(Eclipse中報黃線的提示)
僞代碼:
Person p1 = new Person("張三" , 23 );
Person p2 = new Person("李四" , 24 );
Person p3 = new Person("馬哥" , 18 );
Person p4 = new Person("輝哥" , 20 );
ArrayList<Person> list = new ArrayList<>();
list .add(p1);
list .add(p2);
list .add(p3);
list .add(p4);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("f.txt" ));
oos.writeObject(list );
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("f.txt" ));
ArrayList<Person> list = (ArrayList<Person>)ois.readObject();
@SuppressWarnings("unchecked" )
for (Person person : list ) {
System.out.println(person);
}
ois.close();
概述:
DataInputStream, DataOutputStream可以按照基本數據類型大小讀寫數據。
例如按Long大小寫出一個數字, 寫出時該數據佔8字節. 讀取的時候也可以按照Long類型讀取, 一次讀取8個字節。
僞代碼:
// 將int類型的數據寫出到b.txt 文件中
DataOutputStream dos = new DataOutputStream(new FileOutputStream("b.txt" ))
dos.writeInt (997 )
dos.writeInt (998 )
dos.writeInt (999 )
dos.close ()
//讀取b.txt 文件中的int數據類型。
DataInputStream dis = new DataInputStream(new FileInputStream("b.txt" ))
int x = dis.readInt ()
int y = dis.readInt ()
int z = dis.readInt ()
System.out .println (x )
System.out .println (y )
System.out .println (z )
dis.close ()
打印流(PrintStream和PrintWriter)
概述:
該流可以很方便的將對象的toString()結果輸出, 並且自動加上換行, 而且可以使用自動刷出的模式。
System.out就是一個PrintStream, 其默認向控制檯輸出信息。
使用方式:
打印: print(), println()
自動刷出: PrintWriter(OutputStream out, boolean autoFlush, String encoding)
打印流只操作數據目的
僞代碼:
PrintWriter pw = new PrintWriter(new FileOutputStream("g.txt" ), true );
pw.write(97 );
pw.print ("大家好" );
pw.println ("你好" );
pw.close ();
標準輸入輸出流
概述:
System.in是InputStream, 標準輸入流, 默認可以從鍵盤輸入讀取字節數據
System.out是PrintStream, 標準輸出流, 默認可以向Console中輸出字符和字節數據
Properties類的概述和作爲Map集合的使用
概述:
屬性類 是IO和集合Map的一個結合。用的時候和普通的Map集合用法一樣。
Properties 類表示了一個持久的屬性集。
Properties 可保存在流中或從流中加載。
屬性列表中每個鍵及其對應值都是一個字符串。