乘城程序猿
愿能苦中求乐,累中求歇。痛苦并快乐

缓冲流:

  缓冲流 也叫做高效流  是对4格基本的FileXxx流的增强

    字节缓冲流:BufferedInputStream,BufferedOutputStream

    字符缓冲流: BufferedReader,BufferedWriter

  缓冲流的基本原理 是在创建流对象时 会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写 减少系统IO次数 从而提高读写效率

  字节缓冲流:

    构造方法:

      public BufferedInputStream(Inputstream in):创建一个新d缓冲输入流

      public BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流

     代码示例:

      //创建字节缓冲输入流

      BufferedInputStream bis=new BufferedInputStream(new FileInputStream("bis.txt"));

      //创建字节缓冲输出流

      BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("bos.txt"));

   为什么说通过缓冲区读写能提高读写效率呢? 我测试了一下

      通过基本流复制一个大文件(300MB);

//记录开始时间
            long start =System.currentTimeMillis();
        //创建流对象
            try(FileInputStream fis=new FileInputStream(
new FileInputStream("jdk8.exe")); FileOutputStream fos=new FileOutputStream(
new FileOutputStream("copy.exe"));){ //读写数据 int b; while((b=fis.read())!=-1){ fos.write(b); } }catch (IOException e){ e.printStackTrace(); } //结束时间 long end=System.currentTimeMillis(); System.out.println("复制流时间:"+(end-start)+"毫秒");

      使用缓冲高效流同样复制一个300MB文件

 //记录开始时间
        long start=System.currentTimeMillis();
        //创建流对象
        try(BufferedInputStream bis=new BufferedInputStream(
new FileInputStream("jdk8.exe")); BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream("copy.exe")); ){ //读写数据 int b; while ((b=bis.read())!=-1){ bos.write(b); } }catch (IOException e){ e.printStackTrace(); } //记录结束时间 long end=System.currentTimeMillis(); System.out.println("缓冲流复制时间:"+(end-start)+"毫秒");

      使用数组的方式 重写缓冲高效流

//记录开始时间
        long start=System.currentTimeMillis();
        //创建流对象
        try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream( "jdk8.exe"));
            BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream( "jdk8.exe"));
        ){
            //读写数据
            int b;
            byte[] bytes=new byte[8*1024];
            while ((b=bis.read(bytes))!=-1){
                bos.write(bytes,0,b);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("缓冲流复制时间:"+(end-start)+"毫秒");

  对比请自行进行 这里就不贴结果了

  字符缓冲流

    构造方法:

      public BufferedReader(Reader in):创建一个 新的缓冲输入流

      public BufferedWriter(Writer out):创建一个新的缓冲输出流

    代码示例:

      //创建字符缓冲输入流

      BufferedReader br=new BufferedReader(new FileReader("br.txt"));

      //创建字符缓冲输出流

      BufferedWriter bw=new BuffereWriter(new FileWriter("bw.txt"));

     缓冲字符流特有方法:

       BufferedReader:public String readLine():读一行文字

       BufferedWriter:public void newLine():写一行行分隔符 由系统属性定义符号

转换流

  字符编码:就是一套自然语言的字符与二进制之间的对应规则

   字符集:也就是编码表 是一个系统支持的所有字符的集合 包括各国家文字,标点符号 图形符号 数字等  常见的编码表:Ascii字符集 ISO-8859-1字符表 GBXxx字符集 Unicode字符集等

    常见的编码问题:    

    使用 FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何 问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。 怎么去解决呢?

   转换流IO.InputStreamReader 是Reader的子类 是从字节流到字符流的桥梁 它读取字节 并使用指定的字符集将其解码为字符 它的字符集可以由名称指定 也可以接收平台的默认字符集

    构造方法:

     InputStreamReader(InputStream in):创建一个使用默认字符集的字符流

     InoutStreamReader(InputStream in,String charsetName):创建一个指定字符集的字符流

    代码示例:

      InputStramReader(InputStream in):创建一个使用默认字符集的字符流

      InputStramReader(InputStream in,String charsetName):创建一个指定字符集的字节流

   OutputStreamWriter类

     转换流IO.OutputStreamWriter 是Writer的子类 是从字符流到字节流的桥梁.使用指定的字符集将字符编码为字节 它的字符集可以由名称指定 也可以接收平台的默认字符集

    构造方法:

      OutputStreamWriter(OutputStream in):创建一个使用默认字符集的字符流

      OutputStreamWriter(OutputStream in,String charsetName):创建一个指定字符集的字符流

    代码示例:

      OutputStreamWriter isr=new OutputStreamWriter(new FileOutputStream("out.txt"));

      OutputStreamWriter isr2=new OutputStreamWriter(new FileOutputStream("out.txt"),"GBK");

序列化

  用一个字节序列可以表示一个对象 该字节序列包含该对象的数据 对象的类型和对象中存储的属性等信息。字节序列写出到文件之后 相当于文件中持久保存了一个对象的信息,都可以用来在内存中创建对象。反之 字节序列还可以从文件中读取出来 重构对象 对它进行反序列化。对象的数据 对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象

  ObjectOutputStream类:

    IO.ObjectOutputStream类 将Java对象的原始数据类型写出到文件 实现对象的持久存储

    构造方法:

     public ObjectOutputStream(OutputStream out):创建一个指定OutputStream的ObjectOutputStream

     代码示例:

       FileOutputStream fileout=new FileOutputStream("employee.txt");

       ObjectOutputStream out=new ObjectOutputStream(fileOut);

   序列化操作:

     1.对象想要序列化 必须满足两个条件:

       该类必须实现IO.Serializable接口,Serializable是一个标记接口 不实现此接口的类将不会使任何状态序列化或反序列化 会抛出NotSerializableException

       该类的所有属性必须使可序列化的 如果由一个属性不需要可序列化的 则该属性必须注明使瞬态的 使用transient关键字修饰

     2.写出对象方法

      public final void writeObject(object obj):将指定的对象写出

  ObjectInputStream类:

    ObjectInputStream反序列化流 将之前使用ObjectOutputStream序列化的原始数据回复为对象

    构造方法:

      public ObjectInputStream(InputStream in):创建一个指定InputStream的ObjectInputStream读取对象的方法:

    如果能找到一个对象的class文件  我们可以进行反序列化操作 调用objectInputStream读取对象的方法:

      public final object readObject():读取一个对象

    对于JVM可以反序列化对象 它必须使能够找到class文件的类  如果找不到该类的class文件 则抛出一个classNotFoundException异常

    另外 当JVM反序列化对象时  能找到class文件 但是class文件在序列化对象之后发生了修改该 那么反序列化 操作也会失败 抛出一个InvalidClassException异常 会导致这个异常的原因是:

    1.该类的序列版本号从流中读取的类描述符的坂本号不匹配

    2.该类包含未知数据类型

    3.该类没有可访问的无参构造方法

  Serializable接口 给需要序列化的类 提供了一个序列版本号 serialVersionUID该版本的目的在于沿着序列化的对象和对于类是否版本匹配

 

打印流

  说到打印 我们就会想起学Java时学的第一句语句System.out.println()和System.out.print() 这两个方法都老子io.PrintStream类,该类能够方便地打印各种数据类型的值 是一种便捷的输出方式

   PrintStream类:

    构造方法:

      public PrintStream(String fineName):使用指定的文件名创建一个新的打印流

    代码示例:

      PrintStream ps=new PrintStrem("aa.txt");

   改变打印流向:

    System.out 就是PrintStream类型的 只不过它的流向是系统规定的 打印在控制台是 我们也可以改变它的流向

      

//调用系统的打印流,控制台直接输出97
   System.out.println(97);
//创建打印流 指定文件名称
    PrintStream ps=new PrintStream("aa.txt");
//设置系统的打印流流向 输出到文件
    System.setOut(ps);
//调用系统的打印流 aa.txt中输出97
    System.out.println(97);

  

posted on 2018-07-30 16:47  Sleep_Alone  阅读(158)  评论(0编辑  收藏  举报