Java學(xué)習(xí)筆記 20 - 轉(zhuǎn)換流、緩沖流

本文主要內(nèi)容
1兴猩、轉(zhuǎn)換流
2期吓、緩沖流
3、各種流文件復(fù)制方式的效率比較
4峭跳、IO流對象的操作規(guī)律

01轉(zhuǎn)換流

A: 轉(zhuǎn)換流概述
OutputStreamWriter 是字符流通向字節(jié)流的橋梁:可使用指定的字符編碼表膘婶,將要寫入流中的字符編碼成字節(jié)
將字符串按照指定的編碼表轉(zhuǎn)成字節(jié),在使用字節(jié)流將這些字節(jié)寫出去

B: OutputStreamWriter寫文本文件

  • java.io.OutputStreamWriter 繼承Writer類,字符通向字節(jié)的橋梁蛀醉,將字符流轉(zhuǎn)字節(jié)流
    一個字符輸出流悬襟,寫文本文件
    FileWriter是OutputStreamWriter的子類
    write()字符,字符數(shù)組拯刁,字符串

  • 構(gòu)造方法:
    OutputStreamWriter(OuputStream out)接收所有的字節(jié)輸出流
    OutputStreamWriter(OutputStream out, String charsetName)
    其中String charsetName 傳遞編碼表名字 GBK UTF-8

      /*
       * 轉(zhuǎn)換流對象OutputStreamWriter寫文本
       * 采用UTF-8編碼表寫入
       */
      public static void writeUTF()throws IOException{
          //創(chuàng)建字節(jié)輸出流脊岳,綁定文件
          FileOutputStream fos = new FileOutputStream("c:\\utf.txt");
          //創(chuàng)建轉(zhuǎn)換流對象,構(gòu)造方法保證字節(jié)輸出流垛玻,并指定編碼表是UTF-8
          OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
          osw.write("你好");
          osw.close();
      }
      
      /*
       * 轉(zhuǎn)換流對象 OutputStreamWriter寫文本
       * 文本采用GBK的形式寫入
       */
      public static void writeGBK()throws IOException{
          //創(chuàng)建字節(jié)輸出流割捅,綁定數(shù)據(jù)文件
          FileOutputStream fos = new FileOutputStream("c:\\gbk.txt");
          //創(chuàng)建轉(zhuǎn)換流對象,構(gòu)造方法帚桩,綁定字節(jié)輸出流亿驾,使用GBK編碼表
          OutputStreamWriter osw = new OutputStreamWriter(fos);
          //轉(zhuǎn)換流寫數(shù)據(jù)
          osw.write("你好");
          
          osw.close();
      }
    

C: InputSteamReader讀取文本文件

  • java.io.InputStreamReader 繼承 Reader,字符輸入流,讀取文本文件
  • 讀取的方法: read() 讀取1個字符账嚎,讀取字符數(shù)組
  • InputStreamReader(InputStream in) 接收所有的字節(jié)輸入流,可以傳遞的字節(jié)輸入流: FileInputStream
  • InputStreamReader(InputStream in,String charsetName) 傳遞編碼表的名字
/*
 *  轉(zhuǎn)換流,InputSteamReader讀取文本
 *  采用UTF-8編碼表,讀取文件utf
 */
public static void readUTF()throws IOException{
    //創(chuàng)建自己輸入流,傳遞文本文件
    FileInputStream fis = new FileInputStream("c:\\utf.txt");
    //創(chuàng)建轉(zhuǎn)換流對象,構(gòu)造方法中,包裝字節(jié)輸入流,同時寫編碼表名
    InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
    char[] ch = new char[1024];
    int len = isr.read(ch);
    System.out.println(new String(ch,0,len));
    isr.close();
}
/*
 *  轉(zhuǎn)換流,InputSteamReader讀取文本
 *  采用系統(tǒng)默認編碼表,讀取GBK文件
 */
public static void readGBK()throws IOException{
    //創(chuàng)建自己輸入流,傳遞文本文件
    FileInputStream fis = new FileInputStream("c:\\gbk.txt");
    //創(chuàng)建轉(zhuǎn)換流對象,構(gòu)造方法,包裝字節(jié)輸入流
    InputStreamReader isr = new InputStreamReader(fis);
    char[] ch = new char[1024];
    int len = isr.read(ch);
    System.out.println(new String(ch,0,len));
    
    isr.close();
}

D: 轉(zhuǎn)換流子類父類的區(qū)別

  • a: 繼承關(guān)系
    OutputStreamWriter:
    |--FileWriter:
    InputStreamReader:
    |--FileReader;

  • b: 區(qū)別
    OutputStreamWriter和InputStreamReader是字符和字節(jié)的橋梁:也可以稱之為字符轉(zhuǎn)換流莫瞬。字符轉(zhuǎn)換流原理:字節(jié)流+編碼表。
    FileWriter和FileReader:作為子類郭蕉,僅作為操作字符文件的便捷類存在疼邀。
    當(dāng)操作的字符文件,使用的是默認編碼表時可以不用父類召锈,而直接用子類就完成操作了今缚,簡化了代碼横漏。
    以下三句話功能相同

  • InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));//默認字符集。

  • InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"GBK");//指定GBK字符集哈恰。

  • FileReader fr = new FileReader("a.txt");

02緩沖流

A: 緩沖流概述
可提高IO流的讀寫速度
分為字節(jié)緩沖流與字符緩沖流

B: 字節(jié)輸出流緩沖流BufferedOutputStream
java.io.BufferedOuputStream 作用: 提高原有輸出流的寫入效率
BufferedOuputStream 繼承 OutputStream
方法,寫入 write 字節(jié),字節(jié)數(shù)組

  • 構(gòu)造方法:
    BufferedOuputStream(OuputStream out)
    可以傳遞任意的字節(jié)輸出流, 傳遞的是哪個字節(jié)流,就對哪個字節(jié)流提高效率

          public class BufferedOutputStreamDemo {
              public static void main(String[] args)throws IOException {
                  //創(chuàng)建字節(jié)輸出流,綁定文件
                  //FileOutputStream fos = new FileOutputStream("c:\\buffer.txt");
                  //創(chuàng)建字節(jié)輸出流緩沖流的對象,構(gòu)造方法中,傳遞字節(jié)輸出流
                  BufferedOutputStream bos = new
                          BufferedOutputStream(new FileOutputStream("c:\\buffer.txt"));
                  
                  bos.write(55);
                  
                  byte[] bytes = "HelloWorld".getBytes();
                  
                  bos.write(bytes);
                  
                  bos.write(bytes, 3, 2);
                  
                  bos.close();
              }
          }
    

C: 字節(jié)輸入流緩沖流BufferedInputStream
繼承InputStream,標(biāo)準的字節(jié)輸入流
讀取方法 read() 單個字節(jié),字節(jié)數(shù)組

  • 構(gòu)造方法:
    BufferedInputStream(InputStream in)
    可以傳遞任意的字節(jié)輸入流,傳遞是誰,就提高誰的效率,可以傳遞的字節(jié)輸入流 FileInputStream

          public class BufferedInputStreamDemo {
              public static void main(String[] args) throws IOException{
                  //創(chuàng)建字節(jié)輸入流的緩沖流對象,構(gòu)造方法中包裝字節(jié)輸入流,包裝文件
                  BufferedInputStream bis = new 
                          BufferedInputStream(new FileInputStream("c:\\buffer.txt"));
                  byte[] bytes = new byte[10];
                  int len = 0 ;
                  while((len = bis.read(bytes))!=-1){
                      System.out.print(new String(bytes,0,len));
                  }
                  bis.close();
              }
          }
    

D:字符輸出流緩沖流BufferedWriter
java.io.BufferedWriter 繼承 Writer
寫入方法 write () 單個字符,字符數(shù)組,字符串

  • 構(gòu)造方法:
    BufferedWriter(Writer w)傳遞任意字符輸出流妥衣,傳遞誰,就高效誰
    能傳遞的字符輸出流 FileWriter, OutputStreamWriter

          public class BufferedWrierDemo {
              public static void main(String[] args) throws IOException{
                  //創(chuàng)建字符輸出流,封裝文件
                  FileWriter fw = new FileWriter("c:\\buffer.txt");
                  BufferedWriter bfw = new BufferedWriter(fw);
                  
                  bfw.write(100);
                  bfw.flush();
                  bfw.write("你好".toCharArray());
                  bfw.flush();
                  
                  bfw.close();
                  
              }
          }
    
  • 方法介紹
    void newLine() 寫換行
    該方法具有平臺無關(guān)性
    JVM: 安裝的是Windows版本,newLine()寫的就是\r\n
    安裝的是Linux版本,newLine()寫的就是\n

          public class BufferedWrierDemo {
              public static void main(String[] args) throws IOException{
                  //創(chuàng)建字符輸出流,封裝文件
                  FileWriter fw = new FileWriter("c:\\buffer.txt");
                  BufferedWriter bfw = new BufferedWriter(fw);
                  
                  bfw.write(100);
                  bfw.flush();
                  
                  bfw.write("你好");
                  bfw.newLine();
                  bfw.flush();
                  
                  bfw.write("我好好");
                  bfw.newLine();
                  bfw.flush();
    
                  bfw.close();
              }
          }
    

E:字符輸入流緩沖流BufferedReader
字符輸入流緩沖流BufferedReader讀取文本行

  • java.io.BufferedReader 繼承 Reader
    從字符輸入流中讀取文本幔亥,緩沖各個字符歉备,從而實現(xiàn)字符谈竿、數(shù)組和行的高效讀取

  • 讀取功能 read() 單個字符,字符數(shù)組

  • 構(gòu)造方法:
    BufferedReader(Reader r)可以任意的字符輸入流( FileReader、InputStreamReader )

  • 方法
    String readLine() 讀取文本行 \r\n ,方法讀取到流末尾,返回null

  • 注意
    獲取內(nèi)容的方法一般都有返回值
    int 沒有返回的都是負數(shù)
    引用類型 找不到返回null
    boolean 找不到返回false

          public class BufferedReaderDemo {
              public static void main(String[] args) throws IOException {
                  int lineNumber = 0;
                  //創(chuàng)建字符輸入流緩沖流對象,構(gòu)造方法傳遞字符輸入流,包裝數(shù)據(jù)源文件
                  BufferedReader bfr = new BufferedReader(new FileReader("c:\\a.txt"));
                  //調(diào)用緩沖流的方法 readLine()讀取文本行
                  //循環(huán)讀取文本行, 結(jié)束條件 readLine()返回null
                  String line = null;
                  while((line = bfr.readLine())!=null){
                      lineNumber++;
                      System.out.println(lineNumber+"  "+line);
                  }
                  bfr.close();
              }
          }
    

F:字符流緩沖區(qū)流復(fù)制文本文件

        /*
         *  使用緩沖區(qū)流對象,復(fù)制文本文件
         *  數(shù)據(jù)源  BufferedReader+FileReader 讀取
         *  數(shù)據(jù)目的 BufferedWriter+FileWriter 寫入
         *  讀取文本行, 讀一行,寫一行,寫換行
         */
        public class Copy_1 {
            public static void main(String[] args) throws IOException{
                BufferedReader bfr = new BufferedReader(new FileReader("c:\\w.log"));   
                BufferedWriter bfw = new BufferedWriter(new FileWriter("d:\\w.log"));
                //讀取文本行, 讀一行,寫一行,寫換行
                String line = null;
                while((line = bfr.readLine())!=null){
                    bfw.write(line);
                    bfw.newLine();
                    bfw.flush();
                }
                bfw.close();
                bfr.close();
            }
        }

03四種文件復(fù)制方式的效率比較

  • 字節(jié)流讀寫單個字節(jié) 125250 毫秒
  • 字節(jié)流讀寫字節(jié)數(shù)組 193 毫秒
  • 字節(jié)流緩沖區(qū)流讀寫單個字節(jié) 1210 毫秒
  • 字節(jié)流緩沖區(qū)流讀寫字節(jié)數(shù)組 73 毫秒
        public class Copy {
            public static void main(String[] args)throws IOException {
                long s = System.currentTimeMillis();
                copy_4(new File("c:\\q.exe"), new File("d:\\q.exe"));
                long e = System.currentTimeMillis();
                System.out.println(e-s);
            }
            
            /*
             * 方法,實現(xiàn)文件復(fù)制
             *  1. 字節(jié)流讀寫單個字節(jié)
             */
            public static void copy_1(File src,File desc)throws IOException{
                FileInputStream fis = new FileInputStream(src);
                FileOutputStream fos = new FileOutputStream(desc);
                int len = 0 ;
                while((len = fis.read())!=-1){
                    fos.write(len);
                }
                fos.close();
                fis.close();
            }
            
            /*
             * 方法,實現(xiàn)文件復(fù)制
             *  2. 字節(jié)流讀寫字節(jié)數(shù)組
             */
            public static void copy_2(File src,File desc)throws IOException{
                FileInputStream fis = new FileInputStream(src);
                FileOutputStream fos = new FileOutputStream(desc);
                int len = 0 ;
                byte[] bytes = new byte[1024];
                while((len = fis.read(bytes))!=-1){
                    fos.write(bytes,0,len);
                }
                fos.close();
                fis.close();
            }
            
            /*
             * 方法,實現(xiàn)文件復(fù)制
             *  3. 字節(jié)流緩沖區(qū)流讀寫單個字節(jié)
             */
            public static void copy_3(File src,File desc)throws IOException{
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc));
                int len = 0 ;
                while((len = bis.read())!=-1){
                    bos.write(len);
                }
                bos.close();
                bis.close();
            }
            
            /*
             * 方法,實現(xiàn)文件復(fù)制
             *  4. 字節(jié)流緩沖區(qū)流讀寫字節(jié)數(shù)組
             */
            public static void copy_4(File src,File desc)throws IOException{
                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc));
                int len = 0 ;
                byte[] bytes = new byte[1024];
                while((len = bis.read(bytes))!=-1){
                    bos.write(bytes,0,len);
                }
                bos.close();
                bis.close();
            }
        }

04IO流對象的操作規(guī)律

  • A: IO流對象的操作規(guī)律
    • a: 明確一:要操作的數(shù)據(jù)是數(shù)據(jù)源還是數(shù)據(jù)目的沮尿。
      先根據(jù)需求明確要讀,還是要寫
      源:InputStream Reader
      目的:OutputStream Writer

    • b: 明確二:要操作的數(shù)據(jù)是字節(jié)還是文本呢?

      • 源:
        • 字節(jié):InputStream
        • 文本:Reader
      • 目的:
        • 字節(jié):OutputStream
        • 文本:Writer
    • c: 明確三:明確數(shù)據(jù)所在的具體設(shè)備畜疾。

      • 源設(shè)備:
        • 硬盤:文件 File開頭赴邻。
        • 內(nèi)存:數(shù)組,字符串啡捶。
        • 鍵盤:System.in;
        • 網(wǎng)絡(luò):Socket
      • 目的設(shè)備:
        • 硬盤:文件 File開頭姥敛。
        • 內(nèi)存:數(shù)組,字符串瞎暑。
        • 屏幕:System.out
        • 網(wǎng)絡(luò):Socket
        • 完全可以明確具體要使用哪個流對象彤敛。
      • d: 明確四:是否需要額外功能呢?
        • 轉(zhuǎn)換嗎了赌?轉(zhuǎn)換流墨榄。InputStreamReader OutputStreamWriter
        • 高效嗎?緩沖區(qū)對象勿她。BufferedXXX

05 流的繼承關(guān)系

java.lang.Object
—— java.io.OutputStream 抽象類袄秩,輸出字節(jié)流的所有類的超類
——> java.io.FileOutputStream 用于寫入數(shù)據(jù)文件原始字節(jié)的流
——>>> java.io.FilterOutputStream
——>>>>> java.io.BufferedOutputStream 字節(jié)輸出流緩沖流

java.lang.Object
—— java.io.InputStream抽象類,字節(jié)輸入流的所有類的超類
——> java.io.FileInputStream 用于讀取數(shù)據(jù)文件原始字節(jié)的流
——>>> java.io.FilterInputStream
——>>>>>java.io.BufferedInputStream字節(jié)讀取緩沖流

java.lang.Object
—— java.io.Writer 寫入字符流的抽象類
——> java.io.OutputStreamWriter
——>>> java.io.FileWriter 用于寫入字符流
——> java.io.BufferedWriter 字符輸出緩沖流

java.lang.Object
—— java.io.Reader 讀取字符流的抽象類
——> java.io.InputStreamReader
—— >>> java.io.FileReader 用于讀取字符流
——> java.io.BufferedReader字符輸入緩沖流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逢并,一起剝皮案震驚了整個濱河市之剧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砍聊,老刑警劉巖背稼,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玻蝌,居然都是意外死亡蟹肘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門灶伊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疆前,“玉大人,你說我怎么就攤上這事聘萨≈窠罚” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵米辐,是天一觀的道長胸完。 經(jīng)常有香客問我,道長翘贮,這世上最難降的妖魔是什么赊窥? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮狸页,結(jié)果婚禮上锨能,老公的妹妹穿的比我還像新娘扯再。我一直安慰自己,他們只是感情好址遇,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布熄阻。 她就那樣靜靜地躺著,像睡著了一般倔约。 火紅的嫁衣襯著肌膚如雪秃殉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天浸剩,我揣著相機與錄音钾军,去河邊找鬼。 笑死绢要,一個胖子當(dāng)著我的面吹牛吏恭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袖扛,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼砸泛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蛆封?” 一聲冷哼從身側(cè)響起唇礁,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惨篱,沒想到半個月后盏筐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡砸讳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年琢融,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片簿寂。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡漾抬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出常遂,到底是詐尸還是另有隱情纳令,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布克胳,位于F島的核電站平绩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漠另。R本人自食惡果不足惜捏雌,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望笆搓。 院中可真熱鬧性湿,春花似錦纬傲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至着裹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間米同,已是汗流浹背骇扇。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留面粮,地道東北人少孝。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像熬苍,于是被迫代替她去往敵國和親稍走。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容