Java IO流 總結
阿新 • • 發佈:2018-12-28
IO流分類:
1. 輸入流(讀)和輸出流(寫)。
2. 因為處理的資料不同,分為位元組流和字元流。
close()和flush()的區別:
- flush():將緩衝區的資料刷到目的地中後,流可以使用。
- close():將緩衝區的資料刷到目的地中後,流就關閉了,該方法主要用於結束呼叫的底層資源。這個動作一定做。
流的操作規律:
- 明確源和目的。
- 資料來源:就是需要讀取,可以使用兩個體系:InputStream、Reader;
- 資料匯:就是需要寫入,可以使用兩個體系:OutputStream、Writer;
- 操作的資料是否是純文字資料?
- 如果是:資料來源:Reader
資料匯:Writer - 如果不是:資料來源:InputStream
資料匯:OutputStream
- 如果是:資料來源:Reader
- 明確操作的資料裝置。
- 資料來源對應的裝置:硬碟(File),記憶體(陣列),鍵盤(System.in)
- 資料匯對應的裝置:硬碟(File),記憶體(陣列),控制檯(System.out)。
- 需要在基本操作上附加其他功能嗎?
- 比如緩衝,如果需要就進行裝飾。
位元組流: InputStream OutputStream
適合操作非文字檔案
處理位元組資料的流物件。裝置上的資料無論是圖片或者dvd,文字,它們都以二進位制儲存的。二進位制的最終都是以一個8位為資料單元進行體現,所以計算機中的最小資料單元就是位元組。意味著,位元組流可以處理裝置上的所有資料,所以位元組流一樣可以處理字元資料。
輸入流:
基類:InputStream(抽象)
實現類: FileInputStream
FileInputStream fi = new FileInputStream(file);
讀取:
int i;
while((i=fi. read())!=-1){
System.out.print((char)i);
}
輸出流:
基類:OutputStream(抽象)
實現類: FileOutputStream
FileOutputStream fo = new FileOutputStream("C:/a.txt",false);
字元流讀寫檔案:
private static void method2(String src, String dest) throws IOException {
//1,指定資料來源
FileInputStream in = new FileInputStream(src);
//2,指定目的地
FileOutputStream out = new FileOutputStream(dest);
//3,讀資料
byte[] buffer = new byte[1024];
int len = -1;
while ( (len=in.read(buffer)) != -1) {
//4,寫資料
out.write(buffer, 0, len);
}
//5,關閉流
in.close();
out.close();
}
【注】
- 路徑: C:/a.txt -> C:\\a.txt
- false: 不覆蓋檔案,true:更新覆蓋原檔案
- 原檔案不存在則新建
- 路徑可由 File 物件代替
字元流: Reader Writer
適合操作文字檔案
字元每個國家都不一樣,所以涉及到了字元編碼問題,那麼GBK編碼的中文用unicode編碼解析是有問題的,所以需要獲取中文位元組資料的同時+ 指定的編碼表才可以解析正確資料。為了方便於文字的解析,所以將位元組流和編碼表封裝成物件,這個物件就是字元流。只要操作字元資料,優先考慮使用字元流體系。
輸入流:Reader
實現類:FileReader
//自定義緩衝區
import java.io.*;
class FileReaderDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("demo.txt"); //建立讀取流物件和指定檔案關聯。
//因為要使用read(char[])方法,將讀取到字元存入陣列。所以要建立一個字元陣列,一般陣列的長度都是1024的整數倍。
char[] buf = new char[1024];
int len = 0;
while(( len=fr.read(buf)) != -1) {
System.out.println(new String(buf,0,len));
}
fr.close();
}
}
輸出流:Writer
實現類:FileWriter
緩衝流: Buffer
位元組緩衝流:
BufferedInputStream
BufferedOutputStream
字元緩衝流 高效 讀取檔案
private static void method4(String src, String dest) throws IOException {
//1,指定資料來源
BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
//2,指定目的地
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
//3,讀資料
byte[] buffer = new byte[1024];
int len = -1;
while ( (len = in.read(buffer)) != -1) {
//4,寫資料
out.write(buffer, 0, len);
}
//5,關閉流
in.close();
out.close();
}
字元緩衝流:
BufferedReader(讀)
FileReader fr = new FileReader("bufdemo.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null){ //readLine方法返回的時候是不帶換行符的。
System.out.println(line);
}
bufr.close();
BufferedWriter(寫)
FileWriter fw = new FileWriter("bufdemo.txt");
BufferedWriter bufw = new BufferedWriter(fw);//讓緩衝區和指定流相關聯。
for(int x=0; x<4; x++){
bufw.write(x+"abc");
bufw.newLine(); //寫入一個換行符,這個換行符可以依據平臺的不同寫入不同的換行符。
bufw.flush();//對緩衝區進行重新整理,可以讓資料到目的地中。
}
bufw.close();//關閉緩衝區,其實就是在關閉具體的流。
字元緩衝流讀寫檔案
public class CopyTextFile {
public static void main(String[] args) throws IOException {
//1,指定資料來源, 是資料來源中讀資料,採用輸入流
BufferedReader in = new BufferedReader(new FileReader("file.txt"));
//2,指定目的地,是把資料寫入目的地,採用輸出流
BufferedWriter out = new BufferedWriter(new FileWriter("copyFile.txt"));
//3,讀資料
String line = null;
while ( (line = in.readLine()) != null ) {
out.write(line);//4,寫資料
out.newLine();//寫入換行符號
}
//5,關閉流
out.close();
in.close();
}
}
轉換流: InputStreamReader OutputStreamWriter
轉換流特有功能:
- 轉換流可以將位元組轉成字元,原因在於,將獲取到的位元組通過查編碼表獲取到指定對應字元。
凡是操作裝置上的文字資料,涉及編碼轉換,必須使用轉換流。
轉換流 InputStreamReader
【注意】:在讀取指定的編碼的檔案時,一定要指定編碼格式,否則就會發生解碼錯誤,而發生亂碼現象。
程式碼演示:
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//演示位元組轉字元流的轉換流
readCN();
}
public static void readCN() throws IOException{
//建立讀取檔案的位元組流物件
InputStream in = new FileInputStream("c:\\cn8.txt");
//建立轉換流物件
//InputStreamReader isr = new InputStreamReader(in);這樣建立物件,會用本地預設碼錶讀取,將會發生錯誤解碼。
InputStreamReader isr = new InputStreamReader(in,"utf-8");
//使用轉換流去讀位元組流中的位元組
int ch = 0;
while((ch = isr.read())!=-1){
System.out.println((char)ch);
}
//關閉流
isr.close();
}
}
轉換流 OutputStreamWriter
【注意】:在寫出指定的編碼的檔案時,一定要指定編碼格式,否則讀取時編碼格式不同可能發生亂碼現象。
將字串按照指定的編碼表轉成位元組,在使用位元組流將這些位元組寫出去。
程式碼演示:
public static void writeCN() throws Exception {
//建立與檔案關聯的位元組輸出流物件
FileOutputStream fos = new FileOutputStream("c:\\cn8.txt");
//建立可以把字元轉成位元組的轉換流物件,並指定編碼
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
//呼叫轉換流,把文字寫出去,其實是寫到轉換流的緩衝區中
osw.write("你好");//寫入緩衝區。
osw.close();
}
列印流
PrintWriter
package com.qfedu.bhy.test_printwriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 列印流輸出異常日誌資訊
* @author bhy
*
*/
public class MyException extends Exception{
//設定異常資訊
public String getMessage() {
return "異常資訊--列印異常日誌";
}
//定義異常時執行的方法
public void printException() {
PrintWriter pw = null;
FileWriter fw = null;
try {
fw = new FileWriter("F:/print.txt",true);//true:檔案不覆蓋
pw = new PrintWriter(fw);
} catch (IOException e) {
e.printStackTrace();
}finally {
this.printStackTrace(pw);//this.printStackTrace(PrintWriter s); 寫出當前異常資訊到指定列印流中
pw.print(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
.format(new Date())+"\r\n");//追加時間資訊到列印流中
//關閉流
if(fw!=null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(pw!=null) {
pw.close();
}
}
}
}
附上自定義異常使用程式碼
package com.qfedu.bhy.test_printwriter;
public class TestPrintWriter {
public static void main(String[] args){
try { /捕獲異常
print();
} catch (MyException e) { //處理異常
e.printException();//呼叫自定義異常的異常處理方法
}
}
public static int print()throws MyException{//宣告異常
int[] arr = new int[] {1,4,0,3};
int n = 0 ;
for (int i = 0; i < arr.length+1; i++) {
if(i > arr.length-1 || arr[i] == 0) {
throw new MyException();//丟擲自定義異常物件
}else {
n = arr[i+1]/arr[i];
}
}
return n;
}
}
物件流
- ObjectInputStream
- ObjectOutputStream
物件流–實現序列化:
import java.io.*;
class ObjectStreamDemo {
public static void main(String[] args) throws Exception{
writeObj();
readObj();
}
public static void readObj()throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Object obj = ois.readObject();//讀取一個物件。
System.out.println(obj.toString());
}
public static void writeObj()throws IOException{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi",25)); //寫入一個物件。
oos.close();
}
}
class Person implements Serializable{
private static final long serialVersionUID = 42L;//生成一個序列化ID號
private transient String name;//用transient修飾後name將不會進行序列化
public int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return name+"::"+age;
}
}