欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java之缓冲流、Properties集合以及序列化与反序列化详解

程序员文章站 2024-03-07 15:32:57
...

缓冲字节流

缓冲字节流(高效流)
BufferedOutputStream 缓冲输出字节流

构造方法:BufferedOutputStream(OutputStream out)
    参数:字节输出流的父类 使用FileOutputStream(想对哪个流高效就把哪个流传进去)

BufferedInputStream  缓冲输入字节流
构造方法:BufferedInputStream(InputStream in)
    参数:字节输入流的父类
    使用FileInputStream

高效流写入:
    public static void fun1() throws IOException {
        FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/level/ppp.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("helloworld".getBytes());
        bos.close();
    }

高效流读取:
    public static void fun2() throws IOException {
        FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/level/ppp.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] bs = new byte[1024];
        int len = 0;
        while ((len = bis.read(bs)) != -1) {
            System.out.println(new String(bs, 0, len));
        }
        bis.close();
    }

测试高效流的复制文件快慢

使用模板设计模式:
public class Demo02 {
    public static void main(String[] args) throws IOException {
        //new MyCopy1().printTime();
        new MyCopy2().printTime();
    }
}

abstract class TestTime{
    // 源文件路径
    public String src = "/Users/lanou/Desktop/level/dp.png";
    // 目的文件路径
    public String dest = "/Users/lanou/Desktop/test/dp1.png";
    public void printTime() throws IOException {
        long start = System.currentTimeMillis();
        // 调用方法
        copyFile();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
    // 子类要抛异常 父类就必须有这个异常
    public abstract void copyFile() throws IOException;
}
// 使用字节流复制
class MyCopy1 extends TestTime{

    @Override
    public void copyFile() throws IOException{
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(dest);
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = fis.read(b)) != -1) {
            fos.write(b, 0, len);
        }
        fis.close();
        fos.close();
    }
}
// 使用高效流复制
class MyCopy2 extends TestTime{

    @Override
    public void copyFile() throws IOException {
        FileInputStream fis = new FileInputStream(src);
        BufferedInputStream bis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream(dest);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = bis.read(b)) != -1) {
            bos.write(b, 0, len);
        }
        bis.close();
        bos.close();
    }   
}

缓冲字符流

缓冲字符流

BufferedWriter
构造方法:BufferedWriter(Writer out) 
    参数:Writer(父类)
    可传: OutputStreamWriter FileWriter
    特有方法:newLine() (换行) 无关平台性
                    Mac: \n
                    Windows: /r/n

BufferedReader
构造方法:BufferedReader(Reader in)
    参数:Reader(父类)
    可传: nputStreamReader FileReader

缓冲字符流写入:
    public static void fun1() throws IOException {
        FileWriter fw = new FileWriter("/Users/lanou/Desktop/test/ppp.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("123456789");
        bw.newLine();
        bw.flush();
        bw.close();
    }

缓冲字符流读取:
        FileReader fr = new FileReader("/Users/lanou/Desktop/test/ppp.txt");
        BufferedReader br = new BufferedReader(fr);
        String string = "";
        while ((string = br.readLine()) != null) {
            System.out.println(string);
        }
        br.close();
注意:按行读取是不能把换行读出来的,因此要跟原文本一样 需要自己加上换行来打印

字符缓冲流 文件复制

        FileReader fr = new FileReader("/Users/lanou/Desktop/test/ppp.txt");
        BufferedReader br = new BufferedReader(fr);
        FileWriter fw = new FileWriter("/Users/lanou/Desktop/level/ppp.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        String string = "";
        while ((string = br.readLine()) != null) {
            bw.write(string);
            // 读不出来换行 需要自己加
            bw.newLine();
            bw.flush();
        }
        br.close();
        bw.close();

使用流的总结

流的总结:
    1.明确要做什么操作 
    读数据源  InputStream Reader
    写数据目的地 OutputStream Writer
    2.明确要操作的是什么内容
    文本 音频 图片等 要使用字节流(全能流)
    只文本(按什么编码格式书写)  使用字符流
    3.明确流要在什么设备上使用
    文本
    网络 通过字节流进行数据交互
    4.是否需要提高效率
    使用Buffered 缓冲流

Properties集合

Properties是双列集合,其父类是Hashtable
作用:Properties是集合中唯一一个能和IO流配合的类
读取和写入时,参数是字符流或字节流都可以

添加方法:
    public static void fun1() {
        Properties properties = new Properties();
        // 注意:该集合最好使用的是key和Value都是字符串
        properties.setProperty("gender", "女");

        // 遍历集合
        Set<String> set = properties.stringPropertyNames();
        for (String key : set) {
            System.out.println(key + "=" + properties.getProperty(key));
        }
    }

利用Properties读取:
    public static void fun2() throws IOException {
        Properties properties = new Properties();
        FileReader fr = new FileReader("/Users/lanou/Desktop/test/ppp.txt");
        properties.load(fr);
        System.out.println(properties);
        fr.close();
    }

利用Properties写入:
    public static void fun3() throws IOException {
        Properties properties = new Properties();
        properties.setProperty("a", "hh");
        properties.setProperty("b", "hhh");
        properties.setProperty("c", "hhhh");
        // 一般后缀名给什么都行
        // 但是一般写法使用.properties当做文件后缀名来标识该文件可以使用Properties类读取
        FileWriter fw = new FileWriter("/Users/lanou/Desktop/test/xzb.properties");
        // 利用Properties类中方法写入 
        // 参数2:相当于写入文件的注释 一般什么都不写
        // 在properties文件中可以使用#来写注释
        properties.store(fw, "哈哈");
        fw.close();
    }

序列化与反序列化

序列化流与反序列化流
    序列化是把对象写进文件中 ObjectOutputStream
    反序列化是从文件中把对象读取出来 ObjectInputStream

序列化相当于是把对象进行持久化文件

注意:静态成员变量是不能进行序列化的,序列化序列的是对象,静态成员变量是属于类的

代码示例:

    public static void writeObject() throws IOException {
        // 注意: 如果要对对象进行实例化 必须要实现Serializable(序列化接口)
        // 特点:Serializable 该接口是 标记型接口
        // 写对象都使用字节流去操作
        FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/test/person.txt");
        // 创建对象输出流(序列化流)
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        // 使用写对象的方法
        oos.writeObject(new Person("SC", 30));
        oos.close();
    }

    public static void readObject() throws IOException, ClassNotFoundException {
        // 读取序列化文件(反序列化)
        // 在进行反序列化(读取)的时候需要依赖你的编译文件.class文件来进行读取的
        FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/test/person.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        // 读文件
        Object object = ois.readObject();
        System.out.println(object);
        ois.close();
    }

public class Person implements Serializable{
    /**
     * 序列化使用的***
     * 只要写了这个***在编译时系统就不会重新计算***
     */
    private static final long serialVersionUID = 1L;
    //关键字:transient 瞬态关键字
    // 作用:可以阻止成员变量序列化
    private transient String name;
}
输出:[name=null, age=30]

InvalidClassException异常原因

Java之缓冲流、Properties集合以及序列化与反序列化详解