3、IO流和序列化与反序列化

Java I/O(input/output)
文件 | 内存 | 键盘 —> 程序 的过程叫做
程序 —> 文件 | 内存 | 控制台的过程叫做

文件(File类)
相关记录或放在一起的数据的集合叫做文件
通过Java.io.File类访问文件属性
/*
*创建文件对象语法
*参数内(path name(路径名称))为文件的目录
*如"c:\\test.txt"或"c:/test.txt"
*"\"为转义符所以需再转义
*/
File file = new File(String pathname);
File类的常用方法
方法名称
说明
boolean exists()
判断文件或目录是否存在
boolean isFile()
判断是否是文件
boolean isDirectory()
判断是否是目录
String getPath()
返回此对象表示的文件的相对路径名
String getAbsolutePath()
返回此对象表示的文件的绝对路径名
String getName()
返回此对象表示的文件或目录的名称
boolean delete()
删除此对象制定的文件或目录
boolean createNewFile()
创建名称的空文件,不能创建文件夹
long length()
返回文件的长度,单位为字节,如果文件不存在,则返回0L
*相对路径:当前的位置继续向下的路径
*绝对路径:从根目录(如:C:\)向下的路径
1汉字字符=2字节
1英文字符=1字节

知识点:流
  • 通过流来读写文件
    • 流是一组有序的数据序列
    • 以先进先出方式发送信息的通道
    • 文件 | 内存 | 键盘 —> 程序的过程叫做
    • 程序 —> 文件 | 内存 | 控制台的过程叫做
  • 关闭流时按照后创建的先关闭的顺序关闭

  • 流的分类
    • 按流向区分
      • 输出流
        • OutputStream和Writer作为父类
      • 输入流
        • InputStream和Reader作为父类
*输入输出流是相对于计算机内存来说的

    • 按照处理数据单元划分
      • 字节流
        • 字节输入流InputStream作为父类
        • 字节输出流OutputStream作为父类
      • 字符流
        • 字符输入流Reader作为父类
        • 字符输出流Writer作为父类
*字节流是8位通用字节流,字符流是16为Unicode字符流
————————————————————————————————
1.1输入流(InputStream&Reder)
用来读数据
InputStream&Reder都是抽象父类

1.1.1字节输入流( InputStream抽象类 —> FileInputStream子类 )
通过父类类型指向子类对象创建

      • InputStream类常用方法
        • int read():从输入流一个字节一个字节的读,返回该字节的整数表示形式,如果到了末位,返回-1
        • int read(byte[] b):从输入流读取若干个字节,把这些字节保存到数组b中,返回的是读取到的字节数,如果到了末位,返回-1
        • int read(byte[] b,int off,int len):从输入流读取若干个字节,把这些字节保存到数组b中,off指的是字节数组中开始保存数据的起始下标,len指的是想读取的字节数,返回的是读取到的字节数,如果到了末位,返回-1
        • void close():关闭流
        • int available():可以从输入流中读取的字节数目
      • 子类FileInputStream常用的构造方法
        • FileInputStream(File file):参数为文件类对象
        • FileInputStream(String name):参数为路径
//创建父类类型
InputStream is = null;
    try {
        //创建输入流对象:父类类型指向子类对象
         is = new FileInputStream("C:\\Users\\Administrator\\Desktop\\first.txt");
        //创建byte数组,空间为文件中未读取的字节数
        byte[] b = new byte[is.available()];
        //读取文件,每一个字节保存在byte数组中
        is.read(b);
        //遍历byte数组并打印其中内容,需转换为char输出
        for(byte a : b){
            System.out.print((char)a);
        }
    }catch (FileNotFoundException e) {
        e.printStackTrace();
    }catch (IOException e) {
        e.printStackTrace();
    }finally{
        try{
            //关闭流,无论程序是否发生异常都会运行
            is.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
————————————————————————————————
1.1.2字符输入流( Rader抽象类 —> InputStreamRader子类 —> FileReader孙子类 )
通过父类类型指向子类对象创建

  • Reader类常用方法
    • int read()
    • int read(char[] c]
    • read(char[]c , int off , int len)
    • void colse()
  • 子类InputStreamReader常用的构造方法
    • InputStreamReader(InputStream in)
    • InputStreamReader(InputStream in,String charsetName):第二个参数可以指定读取的编码格式
  • 孙子类FileReader
    • FileReader类是InputStreamReader类的子类
    • 构造方法
      • FileReader(File file)
      • FileReader(String name)
    • 该类只能按照本地平台的字符编码来读取数据,用户不能指定其他的字符编码类型
      • System.out.println(System.getProperty("file.encoding"));获得本地平台的字符编码类型
  • 中文出现乱码:
    • 原因:文件编码格式和程序环境的编码格式不一致
    • 解决方法:字符流去读的时候,指定字符流的编码格式
      • FileReader无法指定编码格式,按照系统默认的编码格式读取
      • *使用InputStreamReader,该类可以指定编码格式
//读取文件产生乱码时解决方法
//查看本地平台的字符编码格式
System.out.println(System.getProperty("file.encoding"));
//创建FileInputStream和Reader类型
FileInputStream fis = null;
Reader fr = null;
//捕获异常
try {
    /*
     * 文件读取出现乱码:文件编码格式和程序环境的编码格式不一致
     */
    // Reader read = newFileReader("C:\\Users\\Administrator\\Desktop\\测试.txt");
    // int i = read.read();
    // while(i != -1){
    // System.out.println((char)i);
    // i = read.read();
    // }
     
    /*
     * 使用InputStreamReader指定编码格式输入文件
     */
    //实例化fis和fr对象
    fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
    fr = new InputStreamReader(fis,"UTF-8");
    //读取文件并打印内容
    int i1 = fr.read();;
    while(i1 !=-1){
        System.out.print((char)i1);
        i1 = fr.read();
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
1.1.3缓冲流BufferedReader
为了提高读取文本文件的效率,可以使用FileReader类与BufferedReader类
BufferedReader可以 包装Reader的子类

  • BufferedReader类是Reader类的子类
  • BufferedReader类带有缓冲区
  • 按行读取内容的readLine()方法
————————————————————————————————
1.2输出流(OutputStream&Writer)
用来写数据
OutputStream&Writer都是抽象父类

1.2.1字节输出流( OutputStream抽象类 —> FileOutputStream子类 )
通过父类类型指向子类对象创建

      • OutputStream类常用方法
        • void write(int c):写一个字节
        • void write(byte[] buf):写一个字节数组
        • void write(byte[] b,int off,int len):写一个字节数组,从哪里开始写,写多长
        • void close():关闭流
        • void flush():强制把缓冲区的数据写到输出流中
      • 子类FileOutputStream常用的构造方法
        • FileOutputStream(File file):参数为文件类对象
        • FileOutputStream(String name):参数为路径
        • FileOutputStream(String name,boolean append):第一个参数为路径,第二个参数判断是否在源文件的内容上追加内容,true追加,false不追加,默认不追加
        • //创建父类类型
          OutputStream os = null;
              try {
                  //创建输出流对象:父类类型指向子类对象
                  os = new FileOutputStream("C:/Users/Administrator/Desktop/first.txt");
                  //要写入的字符串:Hello World
                  String str = "Hello World!";
                  //将字符串转化为byte字节数组
                  byte[] tybes =  str.getBytes();
                  //将tybes数组写入路径中的文件
                  os.write(tybes);
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              }finally{
                  try {
                      //清空缓冲区
                      os.flush();
                      //关闭流
                      os.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          ————————————————————————————————
1.2.2字符输出流( Writer抽象类 —> OutputStreamWriter子类 )
通过父类类型指向子类对象创建

  • Writer类常用方法
    • Write(String str)
    • write(String str , int off , int len)
    • void close():关闭流
    • void flush():清空缓冲区
  • 子类OutputStreamWriter常用的构造方法
    • OutputStreamWriter(OutputStream out)
    • OutputStreamWriter(OutputStream out , String charsetName)
  • 孙子类FileStreamWtiter
    • FileStreamWtiter是OutputStreamWriter的子类
    • 构造方法(以下两种构造方法,都可以重载,可以指定一个boolean类型的参数,用来指定追加还是覆盖文件内容)
      • FileStreamWtiter(File File)
      • FileStreamWtiter(String path)
      • /*
         * 输出流
         */
        //声明父类类型
        Writer fw = null;
        //捕获异常
        try {
            //实例化子类对象:(路径,追加or覆盖) true:追加 false:覆盖
            fw = new FileWriter("C:\\Users\\Administrator\\Desktop\\测试.txt",true);
            //需要输出的字符串
            String info = "输入和输出处理最后一部分内容";
            //输出方法
            fw.write(info);
            //清空缓冲区方法
            fw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                //关闭流
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        ————————————————————————————————
1.1.3缓冲流BufferedWriter
为了提高读取文本文件的效率,可以使用FileWriter类与BufferedWriter类
BufferedWriter可以 包装Writer的子类

  • BufferedWriter类是Writer类的子类
  • BufferedWriter类带有缓冲区
  • BufferedWriter类常用的构造方法
    • BufferedWriter(Writer out)
————————————————————————————————
1.3读写二进制文件

  • DataInputStream类
    • FileInputStream的子类
    • 与FileInputStream类结合使用读取二进制文件

  • DateOutputStream类
    • FileOutputStream的子类
    • 与FileOutputStream类结合使用写二进制文件
    • /*
       * 拷贝二进制文件:图片、音频文件、视频文件等
       */
      //声明父类类型:读取
      DataInputStream dis = null;
      FileInputStream fis = null;
      //声明父类类型:输出
      DataOutputStream dos = null;
      FileOutputStream fos = null;
      //捕获异常
      try {
          //输入流:读取文件
          fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\Fate素描.jpg");
          dis = new DataInputStream(fis);
          byte[] b = new byte[fis.available()];
          dis.read(b);
       
          //输出流:输出文件
          fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\Fate素描(2).jpg");
          dos = new DataOutputStream(fos);
          fos.write(b);
          dos.close();
          fos.close();
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }finally{
          try {
              dos.close();
              fos.close();
              dis.close();
              fis.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      ————————————————————————————————
1.4序列化和反序列化
    • 序列化
      • Java对象(内存) ——> 二进制的字节序列(流)
      • *序列化是将对象的状态写入到特定的流中的过程
    • 反序列化
      • 二进制的字节序列(流) ——> Java对象(内存)
      • *反序列化是从特定的流中获取数据重新构建对象的过程

    • 常见异常
      • NotSerializableExcaption:类没有实现Serializable接口,不可被序列化

    • 序列化的步骤(ObjectOutputStream)
      • 实现Serializable接口
      • 创建对象输出流
      • 调用writeObject()方法将对象写入文件
      • 关闭对象输出流

  • 反序列化的步骤(ObjectInputStream)
    • 实现Serializable接口
    • 创建对象输入流
    • 调用readerObject()方法读取文件中的对象
    • 关闭对象输出流
***关键字transient:修饰字段后,屏蔽该字段,该字段不会被序列化或反序列化
//学生类:实现序列化接口
class StudentTest implements Serializable{
    public String name;
     
    public StudentTest(String name) {
        this.name = name;
    }
}
//测试类
public class Test4 {
    public static void main(String[] args) {
        //创建学生对象
        StudentTest stu = new StudentTest("张三");
        /*
         * 序列化
         */
        //声明对象输出类型
        ObjectOutputStream oos = null;
        FileOutputStream fos = null;
        //捕捉异常
        try {
            //创建对象输出对象
            fos = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
            oos = new ObjectOutputStream(fos);
            //输出学生对象
            oos.writeObject(stu);
            //清空缓冲区
            oos.flush();
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                //关闭流
                oos.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         
        /*
         * 反序列化
         */
        //声明对象输入类型
        ObjectInputStream ois = null;
        FileInputStream fis = null;
        //捕捉异常
        try {
            //创建对象输入对象
            fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\测试.txt");
            ois = new ObjectInputStream(fis);
            //输入学生对象
            StudentTest stu1 = (StudentTest) ois.readObject();
            //打印学生对象信息
            System.out.println("反序列化后的信息:"+stu1.name);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
        e.printStackTrace();
        }finally{
            try {
                //关闭流
                ois.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值