其他分享
首页 > 其他分享> > 文件

文件

作者:互联网

文件流

文件在程序中是以流的形式来操作的。

流:数据在数据源文件(位于磁盘)和程序(位于内存)之间传输时经过的路径

流分为输入和输出流,这个输入输出是相对于内存而言的,即如下图

 

 

 

①FileWriter一定要关闭流或者flush才能真正把数据写入到文件,因为看源码可以知道把数据写入到文件的关键方法是writebytes,而不管是flush还是close都会调用这个方法

 PrintWriter则是close才是真正刷新流并写入

 

 

节点流和处理流

节点流:直接对一个特定的数据源(存放数据的地方)进行操作得流,如FileReader、FileWriter

处理流(又称包装流):是连接在已有的流(节点流或处理流)之上的,能提供更为强大的读写功能,并且比节点流更灵活,比如BufferReader、BuffeWriter

 

 

 

 节点流与处理流的区别与联系

①节点流是底层流/低级流,

 

②处理流可以包装节点流,比如BufferedReader里面有一个Buffer类型的属性,也就是任何的Reader的子类都可以赋值给他,即封装一个节点流,

 

这种设计模式叫做修饰器模式,负责包装的处理流不会直接与数据相连,而这样做的好处是,既可以消除不同节点流的实现差异,也可以通过更方便的方法来输入输出。

 

③处理流带来的好处主要两点

1.性能的提高:主要以增加缓冲的方式来提升输入和输出效率

2.操作的便捷:处理流可能提供了一系列的用于一次性输出输入大批量数据的方法,让数据输出输入更方便

 

 

对象流(比如ObjectInputStream/ObjectOutputStream)

当我们想把某个值以及这个值的数据类型都保存到文件中或者把这个值取出来并匹配其数据类型时,我们用到如下两个

 

序列化:在保存数据到文件时,保存数据类型和数据的值

反序列化:在恢复数据时,能把数据类型和值都恢复出来

 

如果某个类想实现序列化和反序列化,该类必须实现以下两个接口之一:

Serializable  //这是个标记接口,即声明性质,里面没有任何方法,推荐用这个

Externalizable

 

举个例子

序列化

public class Test1 {
    public static void main(String[] args) throws Exception {
        //序列化后,不是以文本来保存,它会以自己的方式保存
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\appicon\\1.txt"));
        //基本类型自动装箱,包装类是实现了序列化
        objectOutputStream.writeInt(100);
        objectOutputStream.writeChar('h');
        objectOutputStream.writeObject(new A("1"));
        objectOutputStream.close();
    }
}

class A implements Serializable {
    private String name;

    public A(String name) {
        this.name = name;
    }
}

 

运行后结果

 

①反序列化的顺序要和序列化一致

public class Test1 {
    public static void main(String[] args) throws Exception {
        //反序列化必须和序列化的顺序一致,不然很可能造成读取类型不匹配,导致抛出异常
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\appicon\\1.txt"));
        System.out.println(objectInputStream.readInt());
        System.out.println(objectInputStream.readChar());
        System.out.println(objectInputStream.readObject());
       objectInputStream.close();

    }
}

class A implements Serializable {
    private String name;

    public A(String name) {
        this.name = name;
    }
}

运行结果

 

 

②序列化的类建议添加serializableUID,以提高版本兼容性,比如你创建的某一个类序列化后,你在其中又加了一个属性,这时,并不会被认为这是一个全新的类,而是认为这是对原先的类的升级

 

③序列化对象时,会默认将所有属性都进行序列化(除了static和transient修饰的成员,这些成员序列化时会略过,不报错),所以,这也要求,序列化的类,其属性的类型也必须要是实现了序列化接口的,否则会报错

 

④序列化具备继承性,当某类实现了序列化时,其子类也实现了序列化

 

标准输出和标准输入

System.in:标准输入,代表键盘,其编译类型是InputStream,运行类型是BufferStream

System.out:标准输出,代表显示器,其编译类型和运行类型都是PrintStream

 

 

转换流

当处理纯文本数据时,用字符流比字节流更快,所以建议用转换流把字节流包装(也叫转换)成字符流,同时转换流的构造器还允许你指定字符集,以下介绍两个转换流

InputStreamReader:Reader的子类,可以将InputStream包装成Reader字符流

OutputStreamWriter:Writer的子类,可以将OutputStream包装成Writer字符流

 

 

Properties

Properties是专门用于读写配置文件的集合类,要求配置文件格式为:键=值

注意,这里的格式,等号左右都不能有空格,值不需要双引号,它默认为String

 

①properties的setProperty方法,内部调用的是hashtable类的put(hashtable是properties的直接父类)

当key的hash相同以及equals为true时,视为key重复,不会新建进去

标签:文件,objectOutputStream,name,节点,序列化,public,String
来源: https://www.cnblogs.com/codemelo/p/16078834.html