• 缓冲流,转换流


    1.缓冲流

    1.定义

    缓冲流,也是高效流,是对四个基本的FileXxx流的增强. 所以也是四个流

    • 字节缓冲流:BufferedInputStream, BufferedOutputStream
    • 字符缓冲流:BufferedReader, BufferedWriter

    缓冲流的基本原理,实在创建对象时,会创建一个内置默认大小的缓冲区数组,通过缓冲区读写,减少系统io次数

    2.字节缓冲流

    构造方法
    • public BufferedInputStream(InputStream in):创建一个新的缓冲流对象
    • public BufferedOutputStream(OutputStream out):创建一个新的缓冲流对象

    构造举例

    // 创建字节缓冲输入流
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
    // 创建字节缓冲输出流
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
    

    使用缓冲流进行案例实现

    public class BufferedDemo{
      public static void main(String[] args){
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try(
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk.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)+"毫秒");
        }
      }
    }
    

    使用数组,加快速度

    public class BufferedDemo{
      public static void main(String[] args){
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try(
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk.exe"));
          BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.exe"));
        ){
          //读写数据
          int len;
          byte[] bytes = new byte[8*1024];
          while((len=bis.read())!=-1){
            bos.write(bytes, 0, len);
          }catch(IOException e){
            e.printStackTrace();
          }
          // 记录结束的时间
          long end = System.currentTImeMillis();
          System.out.println("索要时间为"+(end-start)+"毫秒");
        }
      }
    }
    

    3.字符缓冲流

    构造方法
    • public BufferedReader(Reader in):创建一个新的缓冲输入流
    • public BufferedWriter(Writer out):创建一个新的缓冲输出流

    构造举例

    // 创建字符缓冲输入流
    BufferedReader br = new BufferedReader(new FileReader("br.txt"));
    // 创建字符缓冲输出流
    BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
    
    特有方法

    字符缓冲流的基本方法和普通字符流调用方式一致

    • BufferedReader:public String readLine():读一行文字
    • BuffferedWriter:public void newLine():写一行行分隔符,有系统定义符号

    readLine方法演示

    public class BufferedReaderDemo{
      public static void main(String[] args) throws IOException{
        //创建流对象
        BufferedReader br = new BufferedReader(new FileReader("in.txt"));
        //定义字符串,保存读取的一行文字
        String line = null;
        //循环读取,读到最后返回null
        while((line=br.read())!=null){
          System.out.println(line);
          System.out.println("-----");
        }
        //释放资源
        br.close();
      }
    }
    

    newLine方法演示

    public class BufferedWriterDemo{
      public static void main(String[] args) throws IOException{
        // 创建流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));
        //写出数据
        bw.write("黑马");
        bw.newLine();
        bw.write("程序");
        bw.newLine();
        //释放资源
        bw.close();
      }
    }
    

    2.转换流

    1.IuputStreamReader

    转换流java.io/InputStreamReader, 是Reader的子类, 他读去字节, 并使用指定的字符集将其解码为字符.

    构造方法
    • InputStreamReader(InputStream in):创建一个使用默认字符集的字符流
    • InputStreamReader(InputStream in, String charsetName):创建一个指定字符集的字符流

    构造举例

    InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
    InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"), "GBK");
    
    指定编码读取
    public class ReaderDemo{
      public static void main(String[] args) throws IOException{
        // 定义文件位置, 文件为gbk编码
        String FileName = "E:\file_txt";
        // 创建流对象指定为GBK
        InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName), "GBK");
        //定义变量, 保存字符
        int read;
        //循环读取
        while((read=isr.read())!=-1){
          System.out.println((char) read);
        }
        //关闭资源
        isr.close();
      }
    }
    

    2.OutputStreamWrite

    Write的子类

    构造方法

    • OutputStreamWriter(OutputStream in):创建一个使用默认字符集的字符流
    • OutputStreamWriter(OutputStream in, String chasetName):创建一个指定字符集的字符流

    构造例子

    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");
    
    指定编码写出
    public class OutputDemo{
      public static void main(String[] args) throws IOException{
    		//定义文件路径
        String FileName = "E:\out.txt";
        //创建流对象
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName), "GBK");
        osw.write("你好");
        osw.close();
      }
    }
    

    3.序列化

    Java中提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该 对象的数据 、 对象的 类型 和 对象中存储的属性 等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

    反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据 、对象的类型 和对象中 存储的数据信息,都可以用来在内存中创建对象。

    1.ObjectOutputStream类

    构造方法
    • public ObjectOutputStream(OutputStream out):穿件一个指定的OutputStream的ObjectOutputStream

    构造例子

    FileOutputStream FileOut = new FileOutputStream("a.txt");
    ObjectOutputStream out = new ObjectOutputStream(FileOut);
    
    序列化操作

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

    • 该类是java.io.Serializable接口,Serializable是一个标记接口,不实现此接口不会使用任何状态序列化和反序列化, 会抛出NotSerializableException
    • 该类的所有属性必须是可序列化的,如果有一个属性不要可序列化的, 则改属性必须是注明是瞬态的,使用transient关键字修饰
    public class Employle implements java.io.Serializable{
      public String name;
      public String address;
      public transient int age; //tanisent瞬态修饰成员, 不会被序列化
    }
    

    2.写出对象方法

    • public final void writeObject(Object obj):将制定的对象写出
    public class Serializable{
      public static void main(String[] args){
        Employee e = new Employee();
        e.name = "张三";
        e.address = "北大";
        e.age = 20;
        try{
          //创建序列化流对象
          ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("a.txt"));
          //写出对象
          out.writeObject(e);
          //释放资源
          out.close();
          Fileout.close();
          System.out.println("Serializable 打他 is saved")
        }catch(IOException i){
          i.printStackTrace();
        }
      }
    }
    

    2.ObjectInputStream

    构造方法
    • public ObjectInputStream(InputStream in):穿件一个指定InputStream的ObjectInputStream.
    反序列化操作1

    如果可以找到一个对象的class文件,我们可以进行反序列化操作

    • public final Object readObject():读取一个对象
    public class DeserialixeDemo{
      public static void main(String[] args){
        Employee e = null;
        try{
          //创建反序列化流
          FileInputStream fileIn = new FileInputStream("a.txt");
          ObjectInputStream in = new ObjectInputStream(FileIn);
          //读取一个对象
          e = (Employee) in .readObject();
          //释放资源
          in.close();
          fileIn.close();
        }catch(IOException i){
          //捕获异常
          i.printStackTrace();
          return;
        }catch(ClassNotFoundException c){
          // 捕获找不到异常
          System.out.println("not found");
          c.printStrackTrace();
          return;
        }
        // 无异常,直接打印输出
        System.out.println(e.name);
        System.out.println(e.address);
        System.out.println(e.age);
      }
    }
    
    反序列化操作2

    另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操

    作也会失败,抛出一个 InvalidClassException 异常。发生这个异常的原因如下:

    • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
    • 该类包含未知数据类型
    • 该类没有可访问的无参数构造方法

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

    public class Employee implements java.io.Serializable{
      //加入序列版本号
      private static final long serialVersionUID = 1L;
      public String name;
      public String address;
      //添加新的属性,重新编译
      public int eid;
      public void adressCheck(){
        System.out.println("adress check"+name+"--"+adress);
      }
    }
    

    4.打印流

    平时我们使用控制台打印,print和println来自于java.io.PrintStream

    1.PrintStream类

    构造方法
    • public PrintStream(String FileName):使用指定的文件名创建一个新的打印流

    构造例子

    PrintStream ps = new PrintStream("ps.txt");
    
    改变打印流向

    System.out就是PrintStream类型的

    public class PrintDemo{
      public static void main(String[] args) throws IOException{
        //调用系统的打印流
        System.out.println(97);
        //创建打印流,指定文件的名称
        PrintStream ps = new PrintStream("ps.txt");
        // 设置系统的流向到ps.txt中
        System.setOut(ps);
        //调用打印的方法, ps.txt中输出97
        System.out.println(97);
      }
    }
    

     

  • 相关阅读:
    eclipse + maven 环境配置
    腾讯管家去除桌面快捷小图标
    C# 在同一个项目里启动不同的类文件
    面试题-数据库篇
    面试题-编程篇
    DevExpress控件-GridControl根据条件改变单元格(Dev GridControl 单元格着色)
    Developer Express控件gridcontrol中gridView的某一个单元格是否可以自由输入
    oracle11g如何创建数据库
    通过第三方组件NPOI读取Excel的方法
    Oracle11g常用的命令
  • 原文地址:https://www.cnblogs.com/liudemeng/p/11363328.html
Copyright © 2020-2023  润新知