最近刚看完b站上高淇老师的java300集教程,中间IO流那趴尤其云里雾里,前前后后看了几遍又对比了代码,IO流这部分的知识点差不多在脑子里也形成了一个体系,下面就总结一下教程中166到193讲的IO流部分的内容,就是我对这部分知识的理解。
首先IO流有三种分类:第一,输入流,输出流。这就很好理解,就是从程序的角度看,获得信息就是输入,给出信息就是输出;第二,字节流,字符流。字节流就是二进制的存储方式,可以处理一切文件,而字符流就只能处理纯文本;第三,节点流,处理流。节点流就是直接代表信息的源头,而处理流只能起到增强功能,所以必须包裹节点流才行。
IO流中有两个重要的抽象类,InputStream和OutputStream,他们是字节流,也就是用byte处理数据。一种具体实现有FileInputStream和FileOutputStream,这里的File代表着一个源头或目的地的意思,就是从文件读或写入文件。举个栗子:
// 从文件读取
File src = new File("e:/a.txt");
InputStream is = new FileInputStream(src);
byte[] flush = new byte[1024];
int len = 0;
while(len=is.read(flush)!=-1){
String info = new String(flush, 0, len);
}
// 写入文件
OutputStream os = new FileOutputStream(f, true);
byte data = "some information".getBytes();
os.write(data);
os.flush();
os.close();
这里的FileInputStream和FileOutputStream是字节流,所以读取和写入都用了byte数组。另外,在读取时,采用了分段读取的方法,就是一部分一部分地读进flush中。
另外还有就是字符流,读纯文本的,Reader和Writer,实现类FileReader和FileWriter。具体方法找API吧,反正都是read write这种方法。
处理流,BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter。这些是要包在节点流外面的,起到一种提高性能的效果。还有另外一个处理流,转换流,起到解码,编码的作用,能字符流和字节流相互转换。InputStreamReader和OutputStreamWriter。
其他的一个节点流,ByteArrayInputStream和ByteArrayOutputStream。这里ByteArray和File那对的命名有一定区别,比如FileOutputStream是指输出到File上,而ByteArrayOutputStream是指把ByteArray写到OutputStream上,就是ByteArray是被操作的对象,而File是目的地,这里很容易搞晕。这个节点流和上面一样,用分段读取的方法来操作,举个栗子,分析这个题目,把文件中的一张图,写到byte数组中:从程序的角度看,首先我们要把图读到程序中,就是输入,从文件,那就是FileInputStream;接下来,把程序中的内容,写出去,就是输出,到byte数组,就是ByteArrayOutputStream,大致相关的代码如下,省略了异常还有声明等部分:
InputStream is = new FileInputStream(new File("..."));
OutputStream os = new ByteArrayOutputStream();
while(len=is.read(flush)!=-1){
os.write(flush, 0, len);
}
os.flush();
return os.toByteArray();
还有两种处理流,DataInputStream, DataOutputStream和ObjectInputStream, ObjectOutputStream。对命名的理解和ByteArray是一样的,就是被操作的对象是什么类型。其中一个很重要的应用就是序列化反序列化。把object写到流中再读出来,深克隆就用了这个操作。因为这俩是处理流,所以需要包裹节点流。举一个序列化反序列化的例子,把object写到流中,即输出,用ObjectOutputStream,因为要包裹OutputStream,所以还要用到ByteArrayOutputStream;之后,把流中的object读到程序里,即输入,用ObjectInputStream,要包裹InputStream,所以还要用到ByteArrayInputStream。代码:
// 写到流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
// 从流中读
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
网友评论