前言:
为了进行内存和硬盘之间的操作,引入了一个两者之间的数据通道,称为:流
一:流的类型
1.分输入流和输出流:
输入:InputStream/Reader
输出:OutputStream/Writer
2.分字节流和字符流:
字节流:InputStream/OutputStream
字符流:Reader/Writer
3.分节点流和过滤流
节点流:有实际传输数据的读写功能的流:FileOutputStream
过滤流:在节点流上有了增强功能,如缓冲区之类:BufferedReader,PrintWriter
二:流的操作
public class Demo { /** * @author: Lzzy * @throws FileNotFoundException */ public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("e:/a.txt"))); char b[] = new char[1024]; br.read(b); String str = new String(b); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("f:/a.txt"))); bw.write(b); bw.flush(); br.close(); bw.close(); } }
上段代码操作为先打开文件与内存的流通道: 通过FileInputStream/FileOutputStream 打开文件输入输出流
然后把文件输入输出流封装进入InputStreamReader/OutputStreamWriter 将字节流转换成字符流
最后再最终通过过滤流进行操作
一般来讲读取数据都是:使用read() 将文件数据写入数组保存
然后写入数据都是:用write() 把数组里的数据写入文件
三:对象的序列化
为了将一些引用数据类型写入文件,都需要把该类实现序列化接口 Serializable 或 Externalizable接口
前一个接口内无方法,只是一个标志,告诉流这个类的实例可以进行序列化和反序列化在文件和内存之间进行读取和写入的操作
后一个接口继承了前一接口,可以自身控制序列化行为,因此有两个方法: writeExternal(Object out) / readExternal(Object in)
class SerializableDemo implements Serializable{ /** * */ private static final long serialVersionUID = 5444388055921617016L; }
其中ID为用于进行序列化和反序列化之间的比较,看是否为同一个类
当然有一些属性如果不想被序列化可以使用 transient 关键字修饰,然后对象在序列化和反序列化的时候被修饰的属性值都会被赋予一个默认值
特别的如果是实现Externalizable接口后使用里面的方法进行序列化则transient产生不了效果
四:Properties类
该类为一Key-Value映射储存数据的类,类似于Map,不过只是Key和Value都被规定成了String类型,且不可更改,语法如下:
public class Demo { /** * @author: Lzzy */ public static void main(String[] args) throws Exception { Properties p = new Properties(); p.getProperty(key); p.put(key, value); p.entrySet(); p.contains(value); p.containsKey(key); p.load(inStream); p.store(out, comments); } }
其中的各种方法都类似于Map,只不过特别的多了一个 load()和store()方法
这两个方法从properties文件中读取和写入数据,也就是用通俗点的话说,可以把Map存入一个文件,然后通过特别的规则进行读取写入等各种方法把内存数据储存至文件内