IO流--簡單總結概述
重新深入的學習了IO流,將之前沒搞懂的地方搞懂,這一篇旨在幫助大家理清IO流初始的結構體系。
- 什麼是流。
流是一組有順序的,有起點和終點的位元組集合,是對資料傳輸的總稱和抽象。即資料在兩個裝置間的傳輸成為流,其本質就是資料傳輸。在根據資料傳輸特性將流抽象為各種類。
2.流的分類。
根據處理資料型別的不同:字元流(其實就是位元組流加編碼表)和位元組流。 位元組流和字元流的區別:
- 讀寫單位不同:位元組流以位元組為單位,字元流以字元為單位,根據碼錶對映字元,一次讀取多個位元組
- 處理物件的不同:位元組流能處理所有型別的資料(圖片,Mp3,avi等),而字元流只能處理字元型別的資料。
- 位元組流的操作本身是不會用到緩衝區的,是檔案本身的直接操作的;而字元流的操作會用到緩衝區。
根據資料流向的不同:輸入流和輸出流。無碼首先要明確的一點,輸入和輸出是對誰而言的?就是相對程式而言,也可以理解為記憶體,就是記憶體從外部(硬碟)讀取資料。而輸出就是,記憶體向硬碟中寫入資料。
3.位元組流
從輸入位元組流的繼承圖可以看出:InputStream 是所有的輸入位元組流的父類,它是一個抽象類。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三種基本的介質流,它們分別從Byte 陣列、StringBuffer、和本地檔案中讀取資料。
PipedInputStream 是從與其它執行緒共用的管道中讀取資料,與Piped 相關的知識後續單獨介紹。
ObjectInputStream 和所有FilterInputStream的子類都是裝飾流(裝飾器模式的主角)。意思是FileInputStream類可以通過一個String路徑名建立一個物件,FileInputStream(String name)。
DataInputStream必須裝飾一個類才能返回一個物件,DataInputStream(InputStream in)。
- inputstream
private static void demoread()throws IOException {
// TODO Auto-generated method stub
InputStream fis=new FileInputStream("wujie2.txt");
int ch=0;
while((ch=fis.read())!=-1){//read()方法,返回一個整數,若讀取到流的末尾,返回-1;
System.out.println((char)ch);
}
}
IO 中輸出位元組流的繼承圖可見上圖,可以看出:OutputStream 是所有的輸出位元組流的父類,它是一個抽象類。
ByteArrayOutputStream、FileOutputStream是兩種基本的介質流,它們分別向Byte 陣列、和本地檔案中寫入資料。
PipedOutputStream 是向與其它執行緒共用的管道中寫入資料,
ObjectOutputStream 和所有FilterOutputStream的子類都是裝飾流。具體例子跟InputStream是對應的。
- outputstream
public static void main(String[] args) throws IOException{ OutputStream fos=new FileOutputStream("wujie2.txt"); fos.write("wujiedashuaib".getBytes());//位元組流write操作的是位元組,所以需要getbytes方法 demoread(); }
3.字元流常用操作。
reder:
在上面的繼承關係圖中可以看出:Reader 是所有的輸入字元流的父類,它是一個抽象類。
CharReader、StringReader是兩種基本的介質流,它們分別將Char 陣列、String中讀取資料。
PipedReader 是從與其它執行緒共用的管道中讀取資料。
BufferedReader 很明顯就是一個裝飾器,它和其子類負責裝飾其它Reader 物件。
FilterReader 是所有自定義具體裝飾流的父類,其子類PushbackReader 對Reader 物件進行裝飾,會增加一個行號。
InputStreamReader 是一個連線位元組流和字元流的橋樑,它將位元組流轉變為字元流。FileReader可以說是一個達到此功能、常用的工具類,在其原始碼中明顯使用了將FileInputStream 轉變為Reader 的方法。
FileReader fwFileReader=new FileReader("wujie2.txt");
//取出的是二進位制
char[] buf=new char[3];
int num=0;
while((num=fwFileReader.read(buf))!=-1){//read(char[])將字元讀入陣列/返回讀取的字元數,若到達流末尾則返回-1
System.out.println(new String(buf));
}
fwFileReader.close();
Writer:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//建立一個可以往檔案中寫入字元資料的輸出流物件。
/*
* 既然是往一個檔案中寫入文字資料,那麼在建立物件時,
* 就必須明確該檔案(用於儲存資料的目的地)
*
* 如果檔案不存在,自動建立。
* 檔案存在,被覆蓋。
*
* 如果建構函式中加入true,可以實現對檔案進行續寫
*/
FileWriter fwFileWriter=new FileWriter("wujie.txt",true);
/*
* 呼叫writer物件中的write(string)方法,寫入資料。
*
* 其實資料寫入到臨時緩衝區中
*/
fwFileWriter.write("wujie");
//重新整理,將資料直接寫入目標
//fwFileWriter.flush();
//關閉流,關閉前先重新整理資料。
fwFileWriter.close();
}
- buffereredwriter/bufferedreader.緩衝流,提高效率(也就是一個裝飾器類,另寫。)
public static void main(String[] args) throws IOException {
FileWriter fwFileWriter=new FileWriter("wujie.txt",true);
BufferedWriter bfw =new BufferedWriter(fwFileWriter); //建立緩衝流,只要將字元流傳參給它。
String str="wujiedadada"; bfw.write(str); //寫操作 bfw.close(); //關閉緩衝流 out.close(); //關閉流}
轉換流:InputStreamReader/OutPutStreamWriter
轉換流的特點:
(1)其是字元流和位元組流之間的橋樑
(2)可對讀取到的位元組資料經過指定編碼轉換成字元
(3)可對讀取到的字元資料經過指定編碼轉換成位元組
何時使用轉換流?
當位元組和字元之間有轉換動作時;
流操作的資料需要編碼或解碼時,如果操作文字檔案需要明確具體的編碼解碼。FileWriter和Filereader就不行了,因為他們用的是預設的編碼表。
public static void writeText_3() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("u8_1.txt"),"UTF-8");//使用utf8編碼表寫入
osw.write("你好");
osw.close();
}
public static void readText_2() throws IOException, FileNotFoundException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("u8_1.txt"),"utf-8");//指定utf-8來讀取檔案,如果使用預設的FileReader,出來的是亂碼
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
當需要使用緩衝流的時候;
public static void main(String[] args) throws IOException {
/*
* 1,需求:將鍵盤錄入的資料寫入到一個檔案中。
*
* 2,需求:將一個文字檔案內容顯示在控制檯上。
*
* 3,需求:將一個檔案檔案中的內容複製到的另一個檔案中。
*/
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt")));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}