java檔案字元流
字元流
字元流處理的單元為2個位元組的Unicode字元,分別操作字元、字元陣列或字串。
我們已知道位元組流處理單元為1個位元組,操作位元組和位元組陣列。所以字元流是由Java虛擬機器將位元組轉化為2個位元組的Unicode字元為單位的字元而形成的,所以它對多國語言支援性比較好!如果是視訊檔案、圖片、歌曲,就用位元組流好點,如果是關係到中文(文字)的,用字元流好點。
所有檔案的儲存是都是位元組(byte)的儲存,在磁碟上保留的並不是檔案的字元而是先把字元編碼成位元組,再儲存這些位元組到磁碟。在讀取檔案(特別是文字檔案)時,也是一個位元組一個位元組地讀取以形成位元組序列.
1.位元組流可用於任何型別的物件,包括二進位制物件,而字元流只能處理字元或者字串;
2. 位元組流提供了處理任何型別的IO操作的功能,但它不能直接處理Unicode字元,而字元流就可以。
繼承關係
FileReader–>FileInputStream–>Reader
FileReader只能用於從檔案中讀取字元資料
FileWriter–>FileOutputStream–>Writer
FileWriter用於向檔案中寫字元
舉個例子
import java.io.FileNotFoundException;
import java.io.FileReader ;
import java.io.FileWriter;
import java.io.IOException;
public class lianxiIO {
public static void main(String[] args){
String str = "白日依山盡\n";
char[] ch = str.toCharArray();
FileWriter fw = null;
FileReader fr = null;
try {
fw = new FileWriter("登鶴雀樓.txt" ); //注意:這是相對路徑,在所建立的java專案裡
fw.write(ch);
fw.write("黃河入海流\n");
fw.write("欲窮千里目\n");
fw.write("更上一層樓\n");
fw.close();
} catch (IOException e) {
System.err.println("流的建立、寫和關閉都可能產生IOException異常。");
System.exit(-1);
}
try {
fr = new FileReader("登鶴雀樓.txt");
int i;
while ((i = fr.read()) != -1) {
System.out.print((char) i);
}
System.out.println();
fr.close();
} catch (FileNotFoundException e) {
System.err.println("檔案未找到!");
System.exit(-2);
} catch (IOException e) {
System.err.println("讀和關閉都可能產生IOException異常。");
System.exit(-3);
}
}
}
結果:
白日依山盡
黃河入海流
欲窮千里目
更上一層樓
一.位元組流在操作時不會用到緩衝區(記憶體),是直接對檔案本身進行操作的。而字元流在操作時使用了緩衝區,通過緩衝區再操作檔案。
二.在硬碟上的所有檔案都是以位元組形式存在的(圖片,聲音,視訊),而字元值在記憶體中才會形成。
三.字元流其實是通過轉換流變化為位元組流再進行IO操作
轉換流
在進行字元流到檔案流的轉換Java提供了兩個轉換流:InputStreamReader和OutputStreamWriter。
①InputStreamReader類是從位元組輸入流獲得資料,然後轉換為字元資料交給程式使用。
OutputStreamWrite類是將程式輸出的字元資料,先轉換為位元組資料後,再寫到輸出流中。
②InputStreamReader類是Reader類的直接子類。其構造方法的引數中必須指定一個InputStream位元組輸入流作為資料來源,除此之外,還必須有相應的字元編碼規範,以便將指定的字元編碼轉換為Unicode字元編碼。
OutputStreamWriter類是Writer類的直接子類。同樣,其構造方法的引數中也必須指定一個OutputStream位元組輸出流(作為資料目的地)和字元編碼規範。
舉個例子
public static void main(String[] args) throws IOException {
InputStreamReader ir = new InputStreamReader(System.in);
OutputStream fileOut = null;
int i;
OutputStreamWriter ow = null;
try {
fileOut = new FileOutputStream("encode.txt");
ow = new OutputStreamWriter(fileOut, "UTF8");
//ow = new OutputStreamWriter(new FileOutputStream("encoding.txt"),"UTF8");
System.out.println("寫入檔案的編碼是:" + ow.getEncoding());//獲取檔案編碼格式getEncoding()
System.out.print("請輸入:");
while ((i = ir.read()) != '#') {
ow.write(i);
}
} catch (FileNotFoundException e) {
System.err.println("發生了FileNotFoundException異常。");
} catch (UnsupportedEncodingException e) {
System.err.println("發生了UnsupportedEncodingException異常。");
} finally {
ow.close();
fileOut.close();
}
InputStream fileIn = null;
InputStreamReader irFile = null;
try {
fileIn = new FileInputStream("encode.txt");
irFile = new InputStreamReader(fileIn, "UTF8");
System.out.println("從檔案讀入的編碼是:" + irFile.getEncoding());
System.out.print("從檔案讀入的是:");
while ((i = irFile.read()) != -1) {
System.out.print((char) i);
}
} catch (FileNotFoundException e) {
System.err.println("發生了 FileNotFoundException異常。");
} catch (UnsupportedEncodingException e) {
System.err.println("發生了 UnsupportedEncodingException異常。");
} finally {
irFile.close();
fileIn.close();
}
}
}
寫入檔案的編碼是:UTF8
請輸入:克拉拉#
從檔案讀入的編碼是:UTF8
從檔案讀入的是:克拉拉
在FileOutputStream(“encoding.txt”,true) 新增 true,則將位元組寫入檔案末尾處,而不是寫入檔案開始處
UTF-8包含全世界所有國家需要用到的字元,是國際編碼,通用性強。
緩衝流
為了提高資料的傳輸效率,特意引入緩衝流(Buffered Stream)的概念,為每一個流配置一個緩衝(Buffered),緩衝區就是存放傳輸資料的一塊記憶體,向緩衝流中寫資料時,系統先將資料傳送到緩衝區,不是直接傳送給外設,緩衝區會自動記錄資料,當緩衝區的資料滿了的時候,才將資料全部發送給外設,當從緩衝流中讀資料的時候,系統實際是從緩衝區中讀取資料,緩衝區為空的時候,系統就會從外部的相關裝置自動讀取資料,填滿緩衝區。
1、BufferedReader類
2、BufferedWriter類
FileReader類和FileWriter類以字元為單位進行資料讀寫操作,資料的傳輸效率很低。Java提供BufferedReader和BufferedWriter類以緩衝流的方式進行資料讀寫操作,這兩個流自帶緩衝區。
舉個例子:從鍵盤輸入一首詩,以輸入的格式儲存在檔案中,再顯示在控制檯
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入唐詩,每輸入一行按回車鍵,直接按回車鍵結束:");
try{
int count=0;
FileWriter fw = new FileWriter("詩.txt");
BufferedWriter bw = new BufferedWriter(fw); //建立緩衝字元輸出流物件
String line = null;
while((line=in.readLine())!= null){
if(line.length()== 0)break;
count++;
bw.write(count+")"+line+"\r\n"); //"\r\n"表示在檔案中換行
}
bw.close();
in.close();
}catch(IOException e){
System.err.println(e.toString());
}
}
}
從檔案讀取這樣寫
File file = new File("詩.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
while((line = br.readLine())!=null){
System.out.println(line);
}
這樣也可以
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("詩.txt")));