java - day013 - 流, FileInputStream, BufferedInputStream,

  • 流 Stream
    • 把数据的读写,抽象成数据在管道中流动.
    • 流是单向的
      • 输入流, 只能用来读取数据
      • 输出流, 只能用来输出数据
    • 流只能顺序读写数据
      • 流只能一次性从头到尾读写数据
      • 流动过的数据,不能反复流动
      • 重复读写数据,只能重新新建流

 

  • InputStream/OutputStream
    • 字节流的抽象父类
    • 方法
      • write(int b);
      • write(byte[]);
      • write(byte[] , start, length);
      • flush();刷出缓存数据
      • read();
      • read(byte[] buff);批量读取,返回读取的数据数量
      • available(); 剩余可读取的字节数量

 

  • FileInputStream/FileOutputStream
    • 直接插在文件上, 读写文件数据
    • 创建对象
      • new FileOutputStream(文件);
        • 不管文件是否存在, 都会新建一个空文件
        • 如果文件存在, 空文件会覆盖原文件
      • new FileOutputStream(文件, true);
        • 文件存在,追加数据
    • package day1302;
      
      import java.io.FileOutputStream;
      import java.io.IOException;
      
      public class Test1 {
          public static void main(String[] args) throws IOException {
      
              // 新建文件输出流
              FileOutputStream outF = 
                      new FileOutputStream("/Users/dingzhijie/Desktop/file.txt");
              outF.write(97);
              outF.write(98);
              outF.write(99);
              outF.write(356);
              
              byte[] a = 
                  {101,102,103,104,105,106,107,108,109,110};
              outF.write(a);
              
              outF.write(a, 2, 4);
              

                outF.close();

          }
      }
      package day1302;
      
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.util.Arrays;
      
      public class Test2 {
          public static void main(String[] args) throws IOException {
      
              FileInputStream inputF;
              
              // 因为流只能读取一次数据, 所以需要重复创建
              
              inputF = 
                  new FileInputStream("/Users/dingzhijie/Desktop/file.txt");
              
              // 单字节读取
              int b;
              while ((b = inputF.read()) != -1) {
                  System.out.println(b);
              }
              
              inputF.close();
              
              
              
              inputF = 
                  new FileInputStream("/Users/dingzhijie/Desktop/file.txt");
              
              // 批量读取
              int c;
              byte[] buff = new byte[5];
              while ((c = inputF.read(buff)) != -1) {
                  System.out.println(c+"\t"+Arrays.toString(buff));
              }
              
              inputF.close();
              
          }
      }

       


    • 复制文件
    • package day1302;
      
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.util.Scanner;
      
      public class Test3 {
          public static void main(String[] args) {
      
              // 文件复制
              System.out.println("源文件:");
              
              String s1 = new Scanner(System.in).nextLine();
              
              File from = new File(s1);
              
              if (!from.isFile()) {
                  System.out.println("不是文件");
                  return;
              }
              
              System.out.println("目标文件");
              String s2 = new Scanner(System.in).nextLine();
              
              File to = new File(s2);
              
              if (to.isDirectory()) {
                  System.out.println("不能是文件夹");
                  return;
              }
              
              try {
                  copy(from,to);
                  System.out.println("复制完成");
              } catch (Exception e) {
                  System.out.println("复制失败");
                  e.printStackTrace();
              }
              
              
          }
      
          
          // 首先添加异常的抛出管道
          private static void copy(File from, File to) throws Exception {
             
              /*
               * 在源文件上插入输入流, 输入数据到内存
               * 在目标文件上插入输出流, 从内存输出数据到目标文件
               * 
               */
              
              // 循环批量读取
              // 然后向目标文件输出
              
              FileInputStream in = new FileInputStream(from);
              FileOutputStream out = new FileOutputStream(to);
              
              byte[] buff = new byte[8192];
              int n;
              while ((n = in.read(buff)) != -1) {
                  out.write(buff, 0, n);
              }
              
              in.close();
              out.close();
              
          }
      }

       

  • 高级流 .  操作流
    • 与其他流相接, 提供特定的数据处理功能
    • 对高级流的操作, 会对相接的流执行相同操作
      • 关闭最后的高级流,会同样关闭相接的其他流 

 

  • BufferedInputStrwam/BufferedOutputStream
    • 缓冲流
    • 提供内存缓冲数组
    • 用来提高单字节的读写效率
    • 作用
      • 帮助单字节读取批量读写操作
      • 提高单字节读取效率,对批量读取效率提高无效
    • package day1303;
      
      import java.io.BufferedOutputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
      
      
      public class Test1 {
          public static void main(String[] args) throws IOException {
      
              /*
               * 
               */
              String path = "/Users/dingzhijie/Desktop/file3.txt";
              BufferedOutputStream bout = 
                      new BufferedOutputStream(new FileOutputStream(path));
              
              bout.write(97);
              bout.write(98);
              bout.write(99);
              
              // 写入数据是,先写入 BufferedOutputStream 内部的缓存数组中
              // 满 8192 (8k) 数量, 会自动触发批量写入操作,不满不会触发
              
              
              // 此时 三个数据 不会自动触发写入操作
              // 需要手动刷出缓存
              bout.flush();
              
              /*
               * 高级流的 close 方法
               * 会先执行 flush();
               * 然后关闭相接的流
               */
              bout.close();
              
          }
      }

       


    • 使用 BufferedInputStream / BufferedOutputStream 文件复制

    • package day1302;
      
      import java.io.BufferedInputStream;
      import java.io.BufferedOutputStream;
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.util.Scanner;
      
      public class Test4 {
          public static void main(String[] args) {
      
              // 文件复制
              System.out.println("源文件:");
              
              String s1 = new Scanner(System.in).nextLine();
              
              File from = new File(s1);
              
              if (!from.isFile()) {
                  System.out.println("不是文件");
                  return;
              }
              
              System.out.println("目标文件");
              String s2 = new Scanner(System.in).nextLine();
              
              File to = new File(s2);
              
              if (to.isDirectory()) {
                  System.out.println("不能是文件夹");
                  return;
              }
              
              try {
                  copy(from,to);
                  System.out.println("复制完成");
              } catch (Exception e) {
                  System.out.println("复制失败");
                  e.printStackTrace();
              }
              
              
          }
      
          
          // 首先添加异常的抛出管道
          private static void copy(File from, File to) throws Exception {
             
              /*
               * 在源文件上插入输入流, 输入数据到内存  input
               * 在目标文件上插入输出流, 从内存输出数据到目标文件  output
               * 
               */
              
              // 使用 BufferedInputStream / BufferedOutputStream 单字节读写
              
              FileInputStream in = new FileInputStream(from);
              BufferedInputStream bin = new BufferedInputStream(in);
              
              
              FileOutputStream out = new FileOutputStream(to);
              BufferedOutputStream bout = new BufferedOutputStream(out);
              
              
              int n;
              while ((n = bin.read()) != -1) {
                  bout.write(n);
              }
              
              bin.close();
              bout.close();
              
          }
      }

       

 

  • ObjectInputStream / ObjectOutputStream  对象序列化. 反序列化
    • 序列化
      • 对象的信息,按固定的格式,转成一串字节序列输出
    • ObjectOutputStream 对象序列化
      • writeObject(Object);
        • 把对象序列化输出
    • package day1304;
      
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectOutputStream;
      
      public class Test1 {
          public static void main(String[] args) throws IOException {
      
              /*
               * 
               * 把Student 对象序列化输出 , 保存到文件
               *  
               *  ObjectOutputStream  FileOutputStream
               * 
               */
              
              Student s1 = new Student(12, "张三", "男", 17);
              
              String path = "/Users/dingzhijie/Desktop/file4.txt";
              
              FileOutputStream fos = new FileOutputStream(path);
              ObjectOutputStream ofos = new ObjectOutputStream(fos);
              
              ofos.writeObject(s1);
              
              ofos.close();
              
              // 注意: 被序列化的对象的类 必须 实现 Serializable 接口
              // Serializable 是一个空接口,不需要实现任何抽象方法
              // 只是做一个标识,标识这个类的对象可以被序列化
              
          }
      }

       

    • ObjectInputStream
      • readObject();
        • 读取对象的序列化数据
        • 反序列化恢复对象
    • package day1304;
      
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      
      public class Test2 {
          public static void main(String[] args) throws IOException, ClassNotFoundException {
      
              /*
               * 读取序列化数据
               * 反序列化恢复学生对象
               * 插入文件输入流
               */
              
              String path = "/Users/dingzhijie/Desktop/file4.txt";
              FileInputStream fis = new FileInputStream(path);
              ObjectInputStream bfis = new ObjectInputStream(fis);
              
              Object s1 = bfis.readObject();
              Student s = (Student) s1;
              System.out.println(s.toString());
              
              bfis.close();
          }
      }

       

    • 不序列化的成员
      • static ,属于类, 不随对象被序列化输出
      • transient , 临时,
        • 只在程序运行期间在内存中存在,不会随对象持久的保存
      • 不序列化的成员反序列化时返回默认值

 

 

    • 序列化版本号
      • 旧版本的数据, 不允许恢复新版本的类型
      • 如果自己不定义, 编译器编译时,会根据类的定义信息自动生成一个版本号
    •        /**
           * 序列化版本号
           */
          private static final long serialVersionUID = 2018L;

       

      • 如果类被编译过后, 版本号变化,反序列化以前的旧数据会报错,
      • 可以手动修改以前数据的版本号,执行反序列化

 

posted @ 2019-07-14 16:26  Dingzhijie  阅读(313)  评论(0编辑  收藏  举报