1. 程式人生 > >關於IO流操作

關於IO流操作

輸入流和輸出流相對於記憶體裝置而言.

將外設中的資料讀取到記憶體中:輸入
將記憶體的數寫入到外設中:輸出。


字元流的由來:
其實就是:位元組流讀取文字位元組資料後,不直接操作而是先查指定的編碼表。獲取對應的文字。
在對這個文字進行操作。簡單說:位元組流+編碼表 

---------------------------------------

位元組流的兩個頂層父類:
1,InputStream  2,OutputStream.

字元流的兩個頂層父類:
1,Reader 2,Writer

這些體系的子類都以父類名作為字尾。 
而且子類名的字首就是該物件的功能。

就從熟悉的文字開始字元流,


//需求:將一些文字儲存到硬碟一個檔案中。
記住;如果要操作文字資料,建議優先考慮字元流。
而且要將資料從記憶體寫到硬碟上,要使用字元流中的輸出流。Writer
硬碟的資料基本體現是檔案。 希望找到一個可以操作檔案的Writer.

找到了FileWriter

//需求:讀取一個文字檔案。將讀取到的字元列印到控制檯.
同上,找到了FileReader

作業:將c盤的一個文字檔案複製到d盤。
分析:
複製原理:
讀取c盤檔案中的資料,
將這些資料寫入到d盤當中。
連讀帶寫。

==========================

字元流緩衝區:
BufferedWriter 
    :newLine();
    
BufferedReader:
    : readLine();


使用緩衝區複製一個文字檔案。 

裝飾設計模式:
    對一組物件的功能進行增強時,就可以使用該模式進行問題的解決。 
    

裝飾和繼承都能實現一樣的特點:進行功能的擴充套件增強。 

有什麼區別呢?

首先有一個繼承體系。
Writer
    |--TextWriter:用於操作文字
    |--MediaWriter:用於操作媒體。
    
想要對操作的動作進行效率的提高。
按照面向物件,可以通過繼承對具體的進行功能的擴充套件。 
效率提高需要加入緩衝技術。
    
Writer
    |--TextWriter:用於操作文字
        |--BufferTextWriter:加入了緩衝技術的操作文字的物件。
    |--MediaWriter:用於操作媒體。
        |--BufferMediaWriter:

到這裡就哦了。但是這樣做好像並不理想。
如果這個體系進行功能擴充套件,有多了流物件。
那麼這個流要提高效率,是不是也要產生子類呢?是。這時就會發現只為提高功能,進行的繼承,
導致繼承體系越來越臃腫。不夠靈活。 

重新思考這個問題?
既然加入的都是同一種技術--緩衝。
前一種是讓緩衝和具體的物件相結合。 
可不可以將緩衝進行單獨的封裝,哪個物件需要緩衝就將哪個物件和緩衝關聯。

class Buffer{
    Buffer(TextWriter w)
    {}
    
    Buffer(MediaWirter w)
    {
    
    }
}
class BufferWriter extends Writer{
    BufferWriter(Writer w)
    {
    }
}
Writer
    |--TextWriter:用於操作文字
    |--MediaWriter:用於操作媒體。
    |--BufferWriter:用於提高效率。
    
裝飾比繼承靈活。

特點:裝飾類和被裝飾類都必須所屬同一個介面或者父類。 

--------------------------------------

位元組流:

InputStream  
    

OutputStream

位元組流:
FileInputStream 
FileOutputStream
BufferedInputStream
BufferedOutputStream
字元流:
Writer Reader
FileReader
FileWriter
BufferedReader
BufferedWriter


================================================================

轉換流:
InputStreamReader :位元組到字元的橋樑。解碼。
OutputStreamWriter:字元到位元組的橋樑。編碼。

流的操作規律:
之所以要弄清楚這個規律,是因為流物件太多,開發時不知道用哪個物件合適。

想要知道開發時用到哪些物件。只要通過四個明確即可。

1,明確源和目的(匯)
    源:InputStream  Reader
    目的:OutputStream  Writer

2,明確資料是否是純文字資料。
    源:是純文字:Reader
        否:InputStream
    目的:是純文字 Writer
        否:OutputStream
    
    到這裡,就可以明確需求中具體要使用哪個體系。
    
3,明確具體的裝置。
    源裝置:
        硬碟:File
        鍵盤:System.in
        記憶體:陣列
        網路:Socket流
        
    目的裝置:
        硬碟:File
        控制檯:System.out
        記憶體:陣列
        網路:Socket流

4,是否需要其他額外功能。
    1,是否需要高效(緩衝區);
        是,就加上buffer.
    2,轉換。
    


需求1:複製一個文字檔案。
    1,明確源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是純文字?
        是!
        源:Reader
        目的:Writer
        
    3,明確具體裝置。
        源:
            硬碟:File
        目的:
            硬碟:File
    
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("b.txt");
        
    4,需要額外功能嗎?
        需要,需要高效。
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
================================================

需求2:讀取鍵盤錄入資訊,並寫入到一個檔案中。
        
    1,明確源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是純文字呢?
        是,
        源:Reader
        目的:Writer
    3,明確裝置
        源:
            鍵盤。System.in
        目的:
            硬碟。File
            
        InputStream in = System.in;
        FileWriter fw = new FileWriter("b.txt");
        這樣做可以完成,但是麻煩。將讀取的位元組資料轉成字串。再由字元流操作。
    4,需要額外功能嗎?
        需要。轉換。    將位元組流轉成字元流。因為名確的源是Reader,這樣操作文字資料做便捷。
            所以要將已有的位元組流轉成字元流。使用位元組-->字元 。InputStreamReader
        InputStreamReader isr = new InputStreamReader(System.in);
        FileWriter fw = new FileWriter("b.txt");
        
        還需要功能嗎?
        需要:想高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
            
        
===================================================
    
需求3:將一個文字檔案資料顯示在控制檯上。
    1,明確源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是純文字呢?
        是,
        源:Reader
        目的:Writer
    3,明確具體裝置
        源:
            硬碟:File
        目的:
            控制檯:System.out
            
        FileReader fr = new FileReader("a.txt");
        OutputStream out = System.out;//PrintStream
    4,需要額外功能嗎?
        需要,轉換。
        FileReader fr= new FileReader("a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        需要,高效。 
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
================================================================

需求4:讀取鍵盤錄入資料,顯示在控制檯上。
    1,明確源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是純文字呢?
        是,
        源:Reader
        目的:Writer
    3,明確裝置。
        源:
            鍵盤:System.in
        目的:
            控制檯:System.out
        
        InputStream in = System.in;
        OutputStream out = System.out;
        
    4,明確額外功能?
        需要轉換,因為都是位元組流,但是操作的卻是文字資料。
        所以使用字元流操作起來更為便捷。
        InputStreamReader isr = new InputStreamReader(System.in);
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        
        為了將其高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        
============================================================

5,將一箇中文字串資料按照指定的編碼表寫入到一個文字檔案中.
    
    1,目的。OutputStream,Writer
    2,是純文字,Writer。
    3,裝置:硬碟File 
    FileWriter fw = new FileWriter("a.txt");
    fw.write("你好"); 
    
    注意:既然需求中已經明確了指定編碼表的動作。
    那就不可以使用FileWriter,因為FileWriter內部是使用預設的本地碼錶。
    只能使用其父類。OutputStreamWriter.
    OutputStreamWriter接收一個位元組輸出流物件,既然是操作檔案,那麼該物件應該是FileOutputStream
    
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
    
    需要高效嗎?
    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName));

什麼時候使用轉換流呢?

    1,源或者目的對應的裝置是位元組流,但是操作的卻是文字資料,可以使用轉換作為橋樑。
        提高對文字操作的便捷。
    2,一旦操作文字涉及到具體的指定編碼表時,必須使用轉換流 。
    


 

 

day22 學習結果:

1,流的操作規律。四個明確必須記住,並應用?

2,將提到的5個需求必須全用 需求,規律(思路),程式碼,來體現?必須做!!!

3,File物件基本使用。瞭解建立,刪除,獲取,判斷等。

4,File物件的過濾器。

5,遞迴的使用和注意事項,並舉例。

6,列出一個目錄中所有的內容,包含子目錄。以及刪除一個帶內容的目錄,任選其一。

7,Properties的所有方法的使用,以及應用場景和其練習都要會!

鍵值對配置資訊。properties就可以解析。

id=003
name=lisi
age=30

xml配置資訊。可以使用Java中提供的物件,也可以使用第三方工具。DOM4j 
<persons>
    <person id="003">
        <name>lisi</name>
        <age>30</age>    
    </person>
    
    <person id="007">
        <name>lisi3</name>
        <age>33</age>    
    </person>
</persons>

8,綜合練習必須先明確思路,然後注意程式碼細節。找時間完整搞定。

綜合練習題:

1,
取出D:盤下全部的.java檔案的檔案路徑儲存在java.txt檔案中


2,
有五個學生,每個學生有3門課的成績,定義一種比較直觀的文字檔案格式,
輸入學生姓名和成績,輸入的格式:name,30,30,30從鍵盤輸入以上資料(包括姓名,三門課成績),
按總分數從高到低的順序將學生資訊存放在磁碟檔案"stu.txt"中。