1. 程式人生 > >JAVA語言入門教學系列之IO篇

JAVA語言入門教學系列之IO篇

本文主要向大家介紹了JAVA語言入門教學系列之IO篇,通過具體的內容向大家展示,希望對大家學習JAVA語言有所幫助。

前戲
有很多同學單純的認為IO不就是一個讀檔案和寫檔案嗎,不重要,只要簡單的複製貼上就OK,
會用個File以及什麼流就算"熟練掌握 "了。
使用場景也就上傳檔案才用的到,僅此而已。
呵呵呵呵,那就大錯特錯了,IO的使用範圍很廣,最能體現IO價值的就是網路上的資料傳遞,
尤其是進入網際網路時代後,各種常見的分散式架構,都少不了IO的體現。
並且很多大廠的面試題中都會體現出對IO的重視,包括衍生出來的NIO、序列化等等。
因此學好IO,變成了一件很重要的事情。

IO基本概念
IO可以簡單的理解成INPUT和OUT,代表輸入輸出的意思。輸入就是讀,輸出就是寫。
IO可以讀寫硬碟、光碟、記憶體、鍵盤、網路等資源上的資料。

IO中的流就相當於現實生活中的水流一樣,一開啟自來水的龍頭開關,水就從一頭流向另一頭。
可以理解成每個按順序排列的水滴就是需要傳輸的位元組。
把有序資料理解成流,流負責傳輸資料,以便於輸入輸出。資料是流動的,是有方向的流動。

流的分類
按資料的走向可以分為:輸入流,輸出流。
按資料的單位可以分為:位元組流、字元流。
按裝飾模式可以分為:節點流(底層)、處理流(上層)。
輸入流與輸出流
輸入流:只能從中讀取資料,而不能向其寫入資料。一般用於將資料從網路、硬碟讀取到記憶體中。
輸出流:只能向其寫入資料,而不能從中讀取資料。一般用於將資料從記憶體中寫入到網路、硬碟。
輸入流主要由InputStream和Reader作為父類。
輸出流主要由OutputStream和Writer作為父類。
他們都是抽象的,因此無法直接建立物件。

位元組流與字元流
位元組流與字元流的用法幾乎完全一樣,區別在於所操作的單位不同,位元組流操作8位的位元組,
而字元流操作16位的字元。
位元組流主要由InputStream和OutputStream作為父類。
字元流主要由Reader和Writer作為父類。

節點流與處理流
節點流(上層):
向特定的節點寫入&讀取資料的流。程式連線到實際的資料來源,和實際的輸入輸出節點連線。
處理流(底層):
對一個已存在的流進行連線或封裝,通過封裝後的流來實現資料讀寫功能。
使用處理流進行輸入輸出時,程式不會和實際的輸入輸出節點連線,對底層的處理流做了一層封裝。
程式可以採用相同的輸入輸出程式碼來訪問不同的資料來源。(涉及到裝飾器模式)
處理流使得java程式無需理會輸入輸出的節點是磁碟、網路還是其他,
只要將這些節點流包裝成處理流,
就可以使用相同的輸入輸出程式碼來讀寫不同的輸入輸出裝置的資料。
節點流用於和底層的物理儲存節點直接關聯,不同的物理節點獲取節點流的方式可能存在差異。
程式可以把不同的物理節點流包裝成統一的處理流,
允許程式使用統一的輸入輸出程式碼來讀寫不同的物理儲存節點資源。
常用的輸入輸出流體系
io流按功能分成許多類,每個功能又提供位元組流&字元流,
位元組流與字元流又分別提供了輸入流與輸出流。
如果輸入輸出的是文字內容可以使用字元流,如果輸入輸出的是二進位制內容,可以使用位元組流。

分類	位元組輸入流	位元組輸出流	字元輸入流	字元輸出流抽象父類	InputStream	OutputStream	Reader	Writer訪問檔案?(節點流 )	FileInputStream	FileOutputStream	FileReader	FileWriter訪問陣列?(節點流 )	ByteArrayInputStream	ByteArrayOutputStream	CharArrayReader	CharArrayWriter訪問管道?(節點流)	PipedInputStream	PipedOutputStream	PipedReader	PipedWriter訪問字串?(節點流 )	?	?	StringReader	StringWriter緩衝流	BufferedInputStream	BufferedOutputStream	BufferedReader	BufferedWriter轉換流	?	?	InputStreamReader	OutputStreamWriter物件流	ObjectInputStream	ObjectOutputStream	?	?過濾器流	FilterInputStream	FilterOutputStream	FilterReader	FilterWriter列印流	?	PrintStream	?	PrintReader推回輸入流	PushbackInputStream	?	PushbackReader	?特殊流	DataInputStream	DataOutputStream	?	?

位元組流
位元組流是IO最原始的方式,因為計算機處理資料總是以一個byte為基本單位的,
位元組流就是每次讀取的單位為byte。位元組流是所有流的基礎,也是其他高階流的前提。
位元組流可以處理所有型別的資料,包括:音樂、圖片、文字、視訊、各種檔案等等。
多數以"Stream"結尾的類都是位元組流。
字元流只能處理文字,讀寫的單位是字元。多數以"Writer"與"Reader"結尾的類都是位元組流。

java的基礎位元組流的類為:InputStream,OutputStream。

通過他們倆可以衍生出許多子類,常見的有:

FileInputStream,FileOutputStream,ObjectInputStream,ObjectOutputStream,BufferedInputStream,BufferedOutputStream等。

byte是計算機最基本的單位,所以位元組流可以應付幾乎所有的流的處理,只不過,在處理具體資料格式的時候,效率沒有具體的實現類高,如字元格式,物件格式等。主要操作物件是byte陣列,

通過read()和wirte()方法把byte陣列中的資料寫入或讀出。

使用位元組流複製檔案

public class FileInputOutStreamDemo1 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;

    try {
        fis = new FileInputStream("enya恩雅-only time.mp3");
        fos = new FileOutputStream("new-enya恩雅-only time.mp3");
         
        byte[] temp = new byte[1024];
        while(fis.read(temp)!=-1) {
            fos.write(temp);
        }
         
        temp = new byte[1024];
        //將字串寫入到檔案
        fos = new FileOutputStream("aaa.txt");
        fos.write("我愛你親愛的姑娘".getBytes());//直接覆蓋,而不是追加。如果想追加怎麼辦?
        fis = new FileInputStream("aaa.txt");
        fis.read(temp);
        System.out.println(new String(temp));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(fis!=null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fos!=null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
     
    System.out.println("結束");
}

}

可以理解成把輸入資料想象成儲存在一個水管當中,

輸入流的read()方法從水管中讀取一個或多個水滴,

水滴的單位是位元組或字元,當使用陣列作為讀取方法引數時,read(byte []),

這個陣列相當於一個竹筒,

使用竹筒去水管中取水,程式重複這個取水的過程,直到read(byte [])返回-1為止。

字元流
針對文字檔案,使用字元流來寫入和讀出字元資料。無需再使用位元組流進行包裝,
字元流是由位元組流包裝而來,
它包括:StringReader,StringWriter,BufferedReader,BufferedWriter。
對於前者,他們的使用方法和位元組流類似,主要還是read()和wirte(),
而後者多加了一個readLine()方法,用於讀取文章型別的文字。
FileReader、FileWriter,節點流,會直接和指定檔案相關聯。

使用字元流複製文字檔案

public class FileWriterDemo1 {
public static void main(String[] args) {

    FileReader fr = null;
    FileWriter fw = null;

    try {
        char[] temp = new char[1024];
        // 將字串寫入到檔案
        fw = new FileWriter("aaa.txt");
        fw.write("我愛你親愛的姑娘{{55555:0}}");// 直接覆蓋,而不是追加。如果想追加怎麼辦?
        fr = new FileReader("aaa.txt");
        fr.read(temp);
        System.out.println(new String(temp));
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fr != null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
        }
        if (fw != null) {
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    System.out.println("結束");
}

}

字元流物件在建立時,一般需要提供一個輸入or輸出流。

例如在建立BufferedReader或者BufferedWriter物件時,

需要提供InputStreamReader或OutputStreamWriter物件。

對於特定支付格式的文字內容,還需要在建立的時候提供字元格式型別作為構造引數。

小例子:字元輸入流

File f = new File(“D:\VSS存放目錄\KOOF\3-開發階段\3.3-資料庫”,“koof30.sql”);
FileReader fi = new FileReader(f);
BufferedReader in = new BufferedReader(fi);
String s ;
String total = “”;
while((s=in.readLine())!=null){
total += s+"\n";
}

處理流(上層)與節點流(底層)
處理流隱藏底層裝置上節點流的差異,並對外提供更加方便的輸入輸出方法,
讓我們只關心上層流的操作,有點像應用層的感覺。
可以使用處理流來包裝節點流,通過處理流執行輸入輸出功能,
節點流則負責與底層的IO設別、檔案互動。
處理流的構造引數不是一個物理節點,而是已經存在的節點流,而節點流的構造引數都是物理節點。
上面的例子都是使用節點流(FileInputStream、FileOutputStream、FileReader、FileWriter)。
在使用節點流過程中比較繁瑣,因此我們可以使用處理流。

public class PrintStreamDemo1 {
public static void main(String[] args) {
PrintStream ps = null;
try {
ps = new PrintStream(new FileOutputStream(“bbb.txt”));
&nb

最後,如果你跟我一樣都喜歡java,想成為一名優秀的程式設計師,也在學習java的道路上奔跑,歡迎你加入java學習群:72030155 群內每天都會分享java最新業內資料,分享java免費課程,共同交流學習,讓學習變(編)成(程)一種習慣!