小结一:流与文件

一、流

从文件、网络、内存块中 读入一个字节序列(输入流),写入一个字节序列(输出流)。抽象类 InputStream和 OutputStream构成了输入和输出类层次结构的基础。

字符和字节的区别:字符有自己的编码规则,一个字符可能由很多个字节组成。

流是面向字节的,所以不太适合处理以字符形式存储的信息。Java从Reader和Writer抽象类中派生出了一个单独的类层次结构,专门用于处理Unicode码元。

Java拥有一个庞大的流家族,InputStream和 OutputStream可以进行 字节或者字节数组的读写。如果想要进行例如文件读写之类的操作,就需要依赖于其 实现了更多功能的子类:FileInputStream、FileOutputStream可以对文件进行读写,DataInputStream和DataOutputStream可以以 二进制的形式读写所有的基本Java类型。

二、流的组合

Java中流的功能是很单一的,当我们使用FileInputStream时,就只能从 文件中获取二进制流,而此时 如果我们还希望从中读取数值类型的话,需要将文件流继续传递给 DataInputStream,来进行 数值类型的读取。

在Java中,可以通过组合几种 Stream来 达到我们想要的功能。例如:流在默认情况下,是不被缓冲区缓存的,也就是说,每次read操作,都需要操作系统分发一个字节,相比之下,一次请求一个数据块,然后将其缓存起来会高效很多。此时,就需要先使用 FileInputStream先从文件中读取流,然后将其 传入 BufferedInputStream中,以使用缓冲机制,最后 将其传入DataInputStream中,以读取其中的数值结果。

三、文本输入、输出

可以使用 PrintWriter类进行文本输出,这个类拥有 以文本方式打印字符串和数字的方法,甚至还有一个输出到文件的快捷方式。

可以使用 Scanner类以文本格式读入数据。

四、对象流和序列化

Java支持一种通用的机制:对象序列化。使用ObjectOutputStream将对象写入流中,然后再 使用 ObjectOuputStream读取出来。当然,需要进行序列化的类 应当 实现 Serializable接口,此为标记接口,表示这个类可以进行序列化。

对象序列化的基本算法:

1、每个对象引用都关联一个序列号 2、对于每个对象,当 第一次遇到时,将其保存到流中 3、如果某个对象之前已经遇到过,则只保存其序列号

可以使用 序列化机制来 实现深拷贝:

public class SerialCloneable implements Serializable, Cloneable{

    @Override
    public Object clone(){
        try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(bout);
            objectOutputStream.writeObject(this);
            objectOutputStream.close();

            ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray()));
            Object object = objectInputStream.readObject();
            objectInputStream.close();
            return object;
        }catch (Exception e){
            return null;
        }
    }
}

任意类只要继承自这个类 便可以实现深拷贝。可以通过 打印对象的内存地址发现克隆前后的是 不同的对象。


猜你喜欢

转载自blog.csdn.net/weixin_37882382/article/details/80222410