Java 输入输出流简介和应用 (Java实现序列化工具类)

目录

简介

常用模板

实现序列化工具类

简介

应用场景

代码


简介

Java 流相关的类都封装在 java.io 包中,而且每个数据流都是一个对象。所有输入流类都是 InputStream 抽象类(字节输入流)和 Reader 抽象类(字符输入流)的子类,所有输出流类都是 OutputStream 抽象类(字节输出流)和 Writer 抽象类(字符输出流)的子类。

当你完成对流的读写时,应该通过调用close方法来关闭它,这个方法会释放掉十分有限
的操作系统资源。如果一个应用程序打开了过多的流而没有关闭它们,那么系统资源将被耗尽。
关闭一个输出流的同时也就是在清空用于该输出流的缓冲区,如果不关闭文件,那么写
出字节的最后一个包可能将永远也得不到传递。当然,我们还可以用flush方法来人为地清空
这些输出。

与C语言只有单一类型FILE*即可工作良好不同,Java拥有一个包含各种流类型的流家族,
其数量超过60个. 让我们把流类家族中的成员按照它们的使用方法来进行划分,这样就形成了处理字节和字符的两个单独的层次结构。

输入输出流的设计中用到了装饰者模式。

 

 

常用模板

Java读取文件方法大全_九阈的博客-CSDN博客_java读取文件

 

实现序列化工具类

简介

功能主要是

序列化:将一个实例对象序列化为字节数组并返回,或者将该字节数组保存在本地。

反序列化:将一个字节数组反序列化为对象并返回,或者将本地的文件读取到内存中并且转成对象返回。

应用场景

有时候通过比较耗时的操作生成了一个对象,而这个对象并不会经常性的发生改变,但程序中又会频繁的使用该对象,那么可以选择将这对象序列化并保存在本地,这样每次只需要将该对象从磁盘读取到内存并且反序列化为对象即可使用,耗时明显缩短。

代码

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * jdk序列化工厂类
 */
public class JdkSerializeFactory implements SerializeFactory {
    /**
     * 序列化
     *
     * @param t t
     * @return {@link byte[]}
     */
    @Override
    public <T> byte[] serialize(T t) {
        byte[] data = null;
        try {
//            字节数组输出流在内存中创建一个字节数组缓冲区,所有发送
//            到输出流的数据保存在该字节数组缓冲区中。
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ObjectOutputStream output = new ObjectOutputStream(os);
            output.writeObject(t);
            //bugfix 解决readObject时候出现的eof异常
            output.writeObject(null);
            output.flush();
            data = os.toByteArray();
            // 关闭
            output.close();
            os.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return data;
    }

    /**
     * 反序列化
     *
     * @param data  数据
     * @param clazz clazz
     * @return {@link T}
     */
    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream is = new ByteArrayInputStream(data);
        try {
            ObjectInputStream input = new ObjectInputStream(is);
            Object result = input.readObject();
            return ((T) result);
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 序列化并保存
     *
     * @param t    t
     * @param file 文件
     */
    @Override
    public <T> void serializeAndSave( T t, String file) {
        byte[] bytes = serialize(t);
        save2File(file, bytes);
    }

    /**
     * 得到文件并反序列化
     *
     * @param file 文件
     * @return {@link T}
     */
    @Override
    public <T> T getAndDeserialize(String file, Class<T> clazz) {
        byte[] data = getFromFile(file);
        T t = deserialize(data, clazz);
        return t;
    }

    /**
     * 从文件读取数据
     *
     * @param file 文件
     * @return {@link byte[]}
     */
    private byte[] getFromFile(String file) {
        Path path = Paths.get(file);
        byte[] data = null;
        try {
            data = Files.readAllBytes(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 保存数据到文件
     *
     * @param fname
     * @param msg
     * @return boolean
     */
    private boolean save2File(String fname, byte[] msg){
        OutputStream fos = null;
        try{
            File file = new File(fname);
            File parent = file.getParentFile();
            if ((!parent.exists()) &&
                    (!parent.mkdirs())) {
                return false;
            }
            fos = new FileOutputStream(file);  // 创建文件输出流对象
            fos.write(msg); // 写入数据
            fos.flush();
            return true;
        } catch (IOException e){
            return false;
        } finally{
            if (fos != null) {
                try{
                    fos.close();// 关闭流对象
                }catch (IOException e) {}
            }
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trigger333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值