Java学习笔记 20 - 转换流、缓冲流

本文主要内容
1、转换流
2、缓冲流
3、各种流文件复制方式的效率比较
4、IO流对象的操作规律

01转换流

A: 转换流概述
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字节
将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去

B: OutputStreamWriter写文本文件

  • java.io.OutputStreamWriter 继承Writer类,字符通向字节的桥梁,将字符流转字节流
    一个字符输出流,写文本文件
    FileWriter是OutputStreamWriter的子类
    write()字符,字符数组,字符串

  • 构造方法:
    OutputStreamWriter(OuputStream out)接收所有的字节输出流
    OutputStreamWriter(OutputStream out, String charsetName)
    其中String charsetName 传递编码表名字 GBK UTF-8

      /*
       * 转换流对象OutputStreamWriter写文本
       * 采用UTF-8编码表写入
       */
      public static void writeUTF()throws IOException{
          //创建字节输出流,绑定文件
          FileOutputStream fos = new FileOutputStream("c:\\utf.txt");
          //创建转换流对象,构造方法保证字节输出流,并指定编码表是UTF-8
          OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
          osw.write("你好");
          osw.close();
      }
      
      /*
       * 转换流对象 OutputStreamWriter写文本
       * 文本采用GBK的形式写入
       */
      public static void writeGBK()throws IOException{
          //创建字节输出流,绑定数据文件
          FileOutputStream fos = new FileOutputStream("c:\\gbk.txt");
          //创建转换流对象,构造方法,绑定字节输出流,使用GBK编码表
          OutputStreamWriter osw = new OutputStreamWriter(fos);
          //转换流写数据
          osw.write("你好");
          
          osw.close();
      }
    

C: InputSteamReader读取文本文件

  • java.io.InputStreamReader 继承 Reader,字符输入流,读取文本文件
  • 读取的方法: read() 读取1个字符,读取字符数组
  • InputStreamReader(InputStream in) 接收所有的字节输入流,可以传递的字节输入流: FileInputStream
  • InputStreamReader(InputStream in,String charsetName) 传递编码表的名字
/*
 *  转换流,InputSteamReader读取文本
 *  采用UTF-8编码表,读取文件utf
 */
public static void readUTF()throws IOException{
    //创建自己输入流,传递文本文件
    FileInputStream fis = new FileInputStream("c:\\utf.txt");
    //创建转换流对象,构造方法中,包装字节输入流,同时写编码表名
    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();
}
/*
 *  转换流,InputSteamReader读取文本
 *  采用系统默认编码表,读取GBK文件
 */
public static void readGBK()throws IOException{
    //创建自己输入流,传递文本文件
    FileInputStream fis = new FileInputStream("c:\\gbk.txt");
    //创建转换流对象,构造方法,包装字节输入流
    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: 转换流子类父类的区别

  • a: 继承关系
    OutputStreamWriter:
    |--FileWriter:
    InputStreamReader:
    |--FileReader;

  • b: 区别
    OutputStreamWriter和InputStreamReader是字符和字节的桥梁:也可以称之为字符转换流。字符转换流原理:字节流+编码表。
    FileWriter和FileReader:作为子类,仅作为操作字符文件的便捷类存在。
    当操作的字符文件,使用的是默认编码表时可以不用父类,而直接用子类就完成操作了,简化了代码。
    以下三句话功能相同

  • 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流的读写速度
分为字节缓冲流与字符缓冲流

B: 字节输出流缓冲流BufferedOutputStream
java.io.BufferedOuputStream 作用: 提高原有输出流的写入效率
BufferedOuputStream 继承 OutputStream
方法,写入 write 字节,字节数组

  • 构造方法:
    BufferedOuputStream(OuputStream out)
    可以传递任意的字节输出流, 传递的是哪个字节流,就对哪个字节流提高效率

          public class BufferedOutputStreamDemo {
              public static void main(String[] args)throws IOException {
                  //创建字节输出流,绑定文件
                  //FileOutputStream fos = new FileOutputStream("c:\\buffer.txt");
                  //创建字节输出流缓冲流的对象,构造方法中,传递字节输出流
                  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: 字节输入流缓冲流BufferedInputStream
继承InputStream,标准的字节输入流
读取方法 read() 单个字节,字节数组

  • 构造方法:
    BufferedInputStream(InputStream in)
    可以传递任意的字节输入流,传递是谁,就提高谁的效率,可以传递的字节输入流 FileInputStream

          public class BufferedInputStreamDemo {
              public static void main(String[] args) throws IOException{
                  //创建字节输入流的缓冲流对象,构造方法中包装字节输入流,包装文件
                  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 () 单个字符,字符数组,字符串

  • 构造方法:
    BufferedWriter(Writer w)传递任意字符输出流,传递谁,就高效谁
    能传递的字符输出流 FileWriter, OutputStreamWriter

          public class BufferedWrierDemo {
              public static void main(String[] args) throws IOException{
                  //创建字符输出流,封装文件
                  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() 写换行
    该方法具有平台无关性
    JVM: 安装的是Windows版本,newLine()写的就是\r\n
    安装的是Linux版本,newLine()写的就是\n

          public class BufferedWrierDemo {
              public static void main(String[] args) throws IOException{
                  //创建字符输出流,封装文件
                  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
    从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取

  • 读取功能 read() 单个字符,字符数组

  • 构造方法:
    BufferedReader(Reader r)可以任意的字符输入流( FileReader、InputStreamReader )

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

  • 注意
    获取内容的方法一般都有返回值
    int 没有返回的都是负数
    引用类型 找不到返回null
    boolean 找不到返回false

          public class BufferedReaderDemo {
              public static void main(String[] args) throws IOException {
                  int lineNumber = 0;
                  //创建字符输入流缓冲流对象,构造方法传递字符输入流,包装数据源文件
                  BufferedReader bfr = new BufferedReader(new FileReader("c:\\a.txt"));
                  //调用缓冲流的方法 readLine()读取文本行
                  //循环读取文本行, 结束条件 readLine()返回null
                  String line = null;
                  while((line = bfr.readLine())!=null){
                      lineNumber++;
                      System.out.println(lineNumber+"  "+line);
                  }
                  bfr.close();
              }
          }
    

F:字符流缓冲区流复制文本文件

        /*
         *  使用缓冲区流对象,复制文本文件
         *  数据源  BufferedReader+FileReader 读取
         *  数据目的 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四种文件复制方式的效率比较

  • 字节流读写单个字节 125250 毫秒
  • 字节流读写字节数组 193 毫秒
  • 字节流缓冲区流读写单个字节 1210 毫秒
  • 字节流缓冲区流读写字节数组 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);
            }
            
            /*
             * 方法,实现文件复制
             *  1. 字节流读写单个字节
             */
            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();
            }
            
            /*
             * 方法,实现文件复制
             *  2. 字节流读写字节数组
             */
            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();
            }
            
            /*
             * 方法,实现文件复制
             *  3. 字节流缓冲区流读写单个字节
             */
            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();
            }
            
            /*
             * 方法,实现文件复制
             *  4. 字节流缓冲区流读写字节数组
             */
            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流对象的操作规律

  • A: IO流对象的操作规律
    • a: 明确一:要操作的数据是数据源还是数据目的。
      先根据需求明确要读,还是要写
      源:InputStream Reader
      目的:OutputStream Writer

    • b: 明确二:要操作的数据是字节还是文本呢?

      • 源:
        • 字节:InputStream
        • 文本:Reader
      • 目的:
        • 字节:OutputStream
        • 文本:Writer
    • c: 明确三:明确数据所在的具体设备。

      • 源设备:
        • 硬盘:文件 File开头。
        • 内存:数组,字符串。
        • 键盘:System.in;
        • 网络:Socket
      • 目的设备:
        • 硬盘:文件 File开头。
        • 内存:数组,字符串。
        • 屏幕:System.out
        • 网络:Socket
        • 完全可以明确具体要使用哪个流对象。
      • d: 明确四:是否需要额外功能呢?
        • 转换吗?转换流。InputStreamReader OutputStreamWriter
        • 高效吗?缓冲区对象。BufferedXXX

05 流的继承关系

java.lang.Object
—— java.io.OutputStream 抽象类,输出字节流的所有类的超类
——> java.io.FileOutputStream 用于写入数据文件原始字节的流
——>>> java.io.FilterOutputStream
——>>>>> java.io.BufferedOutputStream 字节输出流缓冲流

java.lang.Object
—— java.io.InputStream抽象类,字节输入流的所有类的超类
——> java.io.FileInputStream 用于读取数据文件原始字节的流
——>>> java.io.FilterInputStream
——>>>>>java.io.BufferedInputStream字节读取缓冲流

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字符输入缓冲流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容