IO流之----字符流(Reader和Writer)和其它流

概述:

字符流是可以直接讀寫字符的IO流。
字符流讀取字符, 就要先讀取到字節數據, 然後轉爲字符. 如果要寫出字符, 需要把字符轉爲字節再寫出。

字符輸入流(FileReader)

概述:

  • FileReader類的read()方法可以按照字符大小讀取文件。

僞代碼:

FileReader fr = new FileReader("aaa.txt");              //創建輸入流對象,關聯aaa.txt
int ch;
while((ch = fr.read()) != -1) {                         //將讀到的字符賦值給ch
    System.out.println((char)ch);                       //將讀到的字符強轉後打印
}
fr.close();                                             //關流 

字符流(FileWriter)

概述:

  • FileWriter類的write()方法可以自動把字符轉爲字節寫出。

僞代碼:

FileWriter fw = new FileWriter("xxx.txt");  //創建輸出流對象,關聯文件xxx.txt,如果文件不存在,則會自動創建。
fw.write("aaa");        //將aaa寫出到xxx.txt文件中
fw.close();         //關閉流

什麼情況下使用字符流?

  • 字符流也可以拷貝文本文件, 但不推薦使用. 因爲讀取時會把字節轉爲字符, 寫出時還要把字符轉回字節。
  • 程序需要讀取一段文本, 或者需要寫出一段文本的時候可以使用字符流。
  • 讀取的時候是按照字符的大小讀取的,不會出現半個中文。寫出的時候可以直接將字符串寫出,不用轉換爲字節數組。

注意:

- 字符流只能拷貝純文本文件,也就是能使用  win記事本打開的文檔。
- 不可以拷貝圖片,音頻,視頻等其它文件。
    - 原因: 因爲在讀的時候會將字節轉換爲字符,在轉換過程中,可能找不到對應的字符,就會用?代替,寫出的時候會將字符轉換成字節寫出去,如果是?,直接寫出,這樣寫出之後的文件就亂碼了,文件則會損壞。

字符流拷貝文件的幾種方式

自定義字符數組的拷貝:

僞代碼:

FileReader fr = new FileReader("aaa.txt");          //創建字符輸入流,關聯aaa.txt
FileWriter fw = new FileWriter("bbb.txt");          //創建字符輸出流,關聯bbb.txt

int len;                                            //記錄每次讀取到的個數
char[] arr = new char[1024*8];                      //創建字符數組
while((len = fr.read(arr)) != -1) {                 //將數據讀到字符數組中
    fw.write(arr, 0, len);                          //從字符數組將數據寫到文件上
}
fr.close();                                         //關流釋放資源fw.close(); 

高效流的拷貝(帶緩衝的字符流)

  • BufferedReader的read()方法讀取字符時會一次讀取若干字符到緩衝區, 然後逐個返回給程序, 降低讀取文件的次數, 提高效率。
  • BufferedWriter的write()方法寫出字符時會先寫到緩衝區, 緩衝區寫滿時纔會寫到文件, 降低寫文件的次數, 提高效率。

僞代碼:

BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));  //創建字符輸入流對象,關聯aaa.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));  //創建字符輸出流對象,關聯bbb.txt

    int ch;             
    while((ch = br.read()) != -1) {     //read一次,會先將緩衝區讀滿,從緩衝去中一個一個的返給臨時變量ch
    bw.write(ch);                   //write一次,是將數據裝到字符數組,裝滿後再一起寫出去
    }

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.write("\r\n");                 //只支持windows系統
    bw.newLine();                       //跨平臺的
}

br.close();
bw.close(); 

IO流之—其它流

  • 概述:
  • IO流中的其它一些流,開發中用到的次數不多,也不是很難,僞代碼中添加的註解也就沒那麼詳細。

轉換流(InputStreamReader和OutputStreamWriter):

概述:使用指定的碼錶讀寫字符:

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();

序列流(SequenceInputStream):

概述:

  • 序列流可以把多個字節輸入流整合成一個, 從序列流中讀取數據時, 將從被整合的第一個流開始讀, 讀完一個之後繼續讀第二個, 以此類推。

僞代碼:

FileInputStream fis1 = new FileInputStream("a.txt");            //創建輸入流對象,關聯a.txt
FileInputStream fis2 = new FileInputStream("b.txt");            //創建輸入流對象,關聯b.txt
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);  //將兩個流整合成一個流
FileOutputStream fos = new FileOutputStream("c.txt");           //創建輸出流對象,關聯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的功能。
  • 支持對隨機訪問文件的讀取和寫入。

對象操作流(ObjectInputStream和ObjectOutputStream)

概述:

  • 對象操作流,也叫序列化流。該流可以將一個對象寫出, 或者讀取一個對象到程序中. 也就是執行了序列化和反序列化的操作。

注意:

  • 要寫出的對象必須實現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)

概述:

  • 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("你好");               //自動刷出,只針對的是println方法
pw.close();

標準輸入輸出流

概述:

  • System.in是InputStream, 標準輸入流, 默認可以從鍵盤輸入讀取字節數據
  • System.out是PrintStream, 標準輸出流, 默認可以向Console中輸出字符和字節數據

Properties類的概述和作爲Map集合的使用

概述:

  • 屬性類 是IO和集合Map的一個結合。用的時候和普通的Map集合用法一樣。
  • Properties 類表示了一個持久的屬性集。
  • Properties 可保存在流中或從流中加載。
  • 屬性列表中每個鍵及其對應值都是一個字符串。
發佈了28 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章