流:java流是Sun公司专门为文件操作,数据传输开发出来的一些类,但是取了个名字叫做流.所有打开的流都必须关闭,因为打开的流是很耗费资源的,并且很不安全.
流中的对象是针对当前操作的程序而言的,输入是指往程序中导入数据,输出是指将当前程序中的数据导出到外部
所有的流都实现了Closeable(意思是需要程序员去手动关闭的程序)接口,用于关闭流
所有的输出流在继承Closeable的同时也实现了Flushable,用于将缓存的数据强制刷入文件
16个常用流
原始流:(打开连接,读取数据)
FileInputStream
FileOutputStream
FileReader
FileWriter
包装流:(在原始的基础上进行强化)
缓存流,为了加快速度,多次读,一次写
BufferedReader
BufferedWriter
BufferedInputStream
BufferedOutputStream
转换流:将字节流转换成字符流
InputStreamReader
OutputStreamWriter
格式化输出流:要对数据输出前进行排版
PrintWriter
PrintStream:标准输出流,默认把数据输出到控制台
不同平台(操作系统)之间数据存储,读取方式不同,为了弥补这些差异性,形成统一,出现了下面两种流
DataOutputStream
DataInputStream
序列化:对象是数据封装的一种方式,并没有封装逻辑.对象在当前内存的范畴使用是没有问题的,但是如果超出了当前内存作用域范畴就需要逻辑,别的地方不一定有当前对象的逻辑,但里面的数据需要用特定的方式读取,所以我们会把对象对应的逻辑代码一起创建出来,这就叫对象的序列化
需要这个类实现java.io.Serializable接口
ObjectOutputStream 序列化java对象到硬盘或远程计算机
ObjectInputStream 将硬盘中的数据反序列化到jvm内存
序列化是通过两个类把对象中的数据保存到文件中,并不是把整个类复制到文件中,而是把类实例化后的对象中的数据序列化到文件中,原来的类结构文件还必须保存.为了保证序列化前后的类结构文件是一致的,所有实现了Serializable接口的类及其子类都会有一个隐含的成员属性 serialVersionUID:这个成员变量用于保存jvm生成的一个唯一的编码,当然,也可以显式的指定
序列化以后,进行反序列化,必须调用原来的类文件,如果原来的类文件不存在了,反序列化就会报错,这个时候,我们需要重新生成类文件,但是,如果类的内容改了,重新生成也会失败,实现了Serializable 接口的类文件的serialVersionUID 都是不同的,这个也已经序列化到了对象文件中,反序列化的时候会比对这个编码,不一致就会报错,serialVersionUID 编码是和内容绑定的,如果数据改了,编号也就变了.但是我们可以自己显式的指定serialVersionUID来规避这个问题(static final long serialVersionUID = 1L),我们在类原始编码文件中指定以后,jvm就不会再指定,这样原始编码文件,类文件,序列化文件中的编码就一直相同,即使我们删除了原始类文件,重新生成一个;甚至我们改变了类文件的内容,也能反序列化成功
常用的方法
所有的流中都有close()方法,流使用完以后关闭流
InputStream和Reader中
read( ) : 从输入流中读取数据,根据参数的不同有不同的读取方式
skip( ) : 跳过和丢弃输入流中的一些数据
OutputStream和Writer中
write( ) : 将指定的数据读入到此输出流中
flush( ) : 将所有缓冲的内容强制刷入此输出流中