IO流(学习Java第24天)(字符缓冲流、打印流、对象序列化和反序列化、Commons IO)

目录

一、字符缓冲流

二、打印流概述

 三、对象序列化和反序列化

四、Commons IO


一、字符缓冲流

  • 构造方法
    • 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(): 读一行文字。 
    • BufferedWriter:public void newLine(): 写一行行分隔符,由系统属性定义符号。

/**
 *  字符输出流的缓冲流
 *  java.io.BufferedWriter 继承 Writer 本身就是字符输出流(只能操作文本文件)
 *  BufferedWriter自己的功能: void newLine() 写入换行
 *  操作系统不同,换行符号也不同,方法newLine()换行,屏蔽掉操作系统的特性
 *  JVM版本是Window,newLine()  \r\n
 *  JVM版本是Linux,newLine()   \n
 *  JVM版本是Mac,newLine()   \r
 *  BufferedWriter构造方法中
 *    BufferedWriter(Writer w)传递任意字符输出流
 *    传递哪个流,就对这个流高效处理,可以传递的字符输出流
 *       FileWriter , OutputStreamWriter
 */
public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException{
        //创建字符输出流
        //FileWriter fw = new FileWriter("e://123.txt");
        //创建字符输出流的缓冲流,构造方法中,传递字符输出流
        BufferedWriter bfw = new BufferedWriter(new FileWriter("e://123.txt") );
        bfw.write("第一行");
        //使用方法换行
        bfw.newLine();
        bfw.write("第二行");
        bfw.close();
    }
}

 

/**
 *  java.io.BufferedReader 字符输入流缓冲流
 *  继承 Reader,本身也是字符输入流 (只能操作文本文件)
 *  BufferedReader自己的功能: String readLine()读取文本一行
 *  BufferedReader构造方法

 *    BufferedReader(Reader r)构造方法可以传递任意字符输入流
 *    能传递的字符输入流:
 *    FileReader  InputStreamReader
 *    readLine()读取文本行,返回字符串
 *    读取到文件的末尾返回 null
 *     readLine()读取文本行,是否包含换行符 ?  ( \r \n) 没有,返回的都是有效字符
 */
public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException{
        //创建字符输入流
       // FileReader fr = new FileReader("e:/123.txt");
        //创建字符输入流的缓冲流,构造方法中,传递字符输入流
        BufferedReader bfr = new BufferedReader( new FileReader("e:/123.txt"));
        //缓冲流对象的方法 String readLine 读取文本一行
        String line = null;
        while ( (line = bfr.readLine()) != null){
            System.out.println(line);
        }
        bfr.close();
    }
}
/**
 *       String line = bfr.readLine();
 System.out.println(line);
 line = bfr.readLine();
 System.out.println(line);
 line = bfr.readLine();
 System.out.println(line);
 line = bfr.readLine();
 System.out.println(line);
 */

二、打印流概述

打印流是专门负责数据输出打印的流对象,我们经常使用的控制台输出语句System.out.println(),就是打印流实现的输出。System.out的运行结果就是PrintStream打印流对象。

  • PrintStream继承OutputStream,本质上是字节输出流。
  • PrintWriter继承Writer,本质上是字符输出流。
/**
 *  打印流:  负责输出,不负责输入
 *  java.io.PrintStream  字节流
 *  java.io.PrintWriter  字符流
 *  打印流特点:
 *    1: 方便打印各种数据 (println(数据原样输出))
 *    2: 只负责输出目的,不负责数据源
 *    3: 打印流永远不会抛出IOException
 *       但是,不抛出别的异常
 *    4: 可以启用自动刷新
 *  java.io.PrintStream  字节流
 *    构造方法封装的就是数据目的
 *    File对象,String 文件名, OutputStream字节输出流
 *
 *  java.io.PrintWriter  字符流
 *    构造方法封装的就是数据目的
 *    File对象,String 文件名, OutputStream字节输出流,Writer字符输出流
 *
 *  打印流的方法,不需要讲解
 */
public class PrintWriterDemo {
    public static void main(String[] args) throws IOException {
        method_2();
    }
    /**
     * 打印流输出数据,带自动刷新PrintWriter
     * 前提:
     *   1: 打印流的输出目的,必须是流对象
     *   2: 构造方法第二个参数, true
     *       File String  流对象new FileOutputStream(File可以是String)
     *   3: 方法只能调用println,print,format 三个中的一个
     */
    public static void  method_2()throws IOException{
        FileOutputStream fos = new FileOutputStream("day12/print.txt");
        //创建打印流对象,开启自动刷新
        PrintWriter pw = new PrintWriter(fos,true);
        pw.println(1);
        pw.close();
    }
    /**
     * 打印流输出数据,输出目的是字节输出流
     */
    public static void method()throws IOException{
        FileOutputStream fos = new FileOutputStream("day12/print.txt");
        //创建打印流对象,构造方法传递字节输出流
        PrintWriter pw = new PrintWriter(fos);
        //打印数据
        pw.println(100);
        pw.close();
    }
}

 三、对象序列化和反序列化

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

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

  • ObjectOutputStream类

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

构造方法
public ObjectOutputStream(OutputStream out) : 创建一个指定OutputStream的ObjectOutputStream。
FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
序列化方法
public final void writeObject (Object obj) : 将指定的对象写出。

 

  • 序列化操作
    • 一个对象要想序列化,必须满足两个条件:
    • 该类必须实现java.io.Serializable接口,Serializable是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException 。
    • 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态(只是使用,不必存储进序列)的,使用transient 关键字修饰。
  •  ObjectInputStream类

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

构造方法
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream。
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream读取对象的方法:
public final Object readObject () : 读取一个对象。
对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个ClassNotFoundException 异常。 

 

/**
 *  java.io.Serializable接口
 *  实现此接口,可以开启序列化和反序列化功能
 *  关键字: 瞬态  transient  阻止变量被序列化
 *  自定义序列号,如果自己定义了,javac编译的时候,不写了
 */
public class Person implements Serializable{
    private String name;
   private  int age;
    static final long serialVersionUID = 100L;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
/**
 *  对象的序列化和对象的反序列化
 *  java.io.ObjectOutputStream 写对象 序列化流
 *  java.io.ObjectInputStream  读对象 反序列化流
 */
public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException ,ClassNotFoundException{
//        write();
        read();
      /*  Person person = new Person("a",5);
        System.out.println(person);*/
    }
    /**
     * 对象的反序列化,从硬盘中读取对象
     * ObjectInputStream
     * 构造方法,传递字节输入流(绑定文件,必须是序列化文件)
     *     Object readObject()
     *   读取对象的方法 readObject()抛出异常,抛出的是ClassNotFoundException
     *   反序列化,必须有class文件支持
     */
    public static void read()throws IOException,ClassNotFoundException{
        //创建反序列化流,构造方法传递字节输入流
        ObjectInputStream ois = new ObjectInputStream( new FileInputStream("day12/person.txt"));
        //读取对象
        Object object =  ois.readObject();
        System.out.println(object);
    }
    /**
     * 对象的序列化,对象写入到硬盘中存储
     * ObjectOutputStream
     * 构造方法,传递字节输出流(绑定文件)
     *    void writeObject(Object obj)
     */
    public static void write()throws IOException{
        //创建序列化流,构造方法传递字节输出流
        ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("day12/person.txt"));
        Person person = new Person("张三",20);
        //写入对象
        oos.writeObject(person);
        oos.close();
    }
}

四、Commons IO

IO技术开发中,代码量很大,而且代码的重复率较高。如果我们要遍历目录,拷贝目录就需要使用方法的递归调用,也增大了程序的复杂度。

Apache软件基金会,开发了IO技术的工具类`commonsIO`,大大简化IO开发。

  • 添加第三方jar包

Apahce软件基金会属于第三方,(Oracle公司第一方法,我们自己第二方吗,其他都是第三方)我们要使用第三方开发好的工具,需要添加jar包。

jar包:就是Java自己的压缩包,包中是开发好的功能,全部以class文件形态出现,我们添加直接使用即可。

    • 在module下创建文件夹lib
    • 将jar包文件复制到lib文件夹中
    • lib文件夹上按鼠标右键,选择Add as Library;level选项:选择module
  • CommonsIO的使用
IOUtils类
  静态方法:IOUtils.copy(InputStream in,OutputStream out)传递字节流,实现文件复制。
  静态方法:IOUtils.closeQuietly(任意流对象)悄悄的释放资源,自动处理close()方法抛出的异常。
FileUtils类
  静态方法:FileUtils.copyDirectoryToDirectory(File src,File dest);传递File类型的目录,进行整个目录的复制,自动进行递归遍历。
  静态方法:writeStringToFile(File file,String str)写字符串到文本文件中。
  静态方法:readFileToString(File file)读取文本文件,返回字符串。

 

public class CommonsIODemo {
    public static void main(String[] args)throws IOException {
       // IOUtils.copy(new FileInputStream("e:/1.avi"),new FileOutputStream("e:/copy/1.avi"));
       // FileUtils.writeStringToFile(new File("day12/1.txt"),"你想写什么,就写什么OK?");
        //String string = FileUtils.readFileToString(new File("day12/1.txt"));
       // System.out.println(string);
        FileUtils.copyDirectoryToDirectory(new File("c:/java"),new File("e:/copy"));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值