本次记录IO流,方便我们从各个方面存取数据。
IO流往简单学习就是输入流和输出流。再细分就是字节流还是字符流。常常都说,IO学五大类。而这些很多方法都是类似的,字符输入流有什么,那么字符输入流也有什么。相应的输出流也都有相对应的方法。所以也没那么难。
File
FIle文件操作的类,它不属于IO的四大类,但它是IO流的基础。怎么找文件,怎么判断是否为文件,才能方便我们后面的学习,怎么在文件上存和取。
在写代码前,我们先了解路径分隔符。
在win上分隔符是’\‘。如”D:\Test”。而’\‘在java中有特殊含义,如果要使用’\‘,需要再加’\‘转译’\‘,如”D:\\Test”。
而在linux上,分隔符是’/‘。”D:/Test”。不同系统有不同的分隔符。不过win也支持’/‘。所以我们在写路径可以采用linux的方法。
但java可能不止在win和linux上运行,所以我们可以用File里的方法separator来获取系统的分隔符。
如String path = “D:”+File.separator+”Test”;这段代码,如果路径比较长,还是挺麻烦的。但不会出错。
1 | import java.io.File; //记得引入File包 |
上面也有很多注意点,在获取文件夹的大小上,得到一个4096?百度查了一下,这可能是缓存的锅,按道理文件夹应该为0。只有文件才能获取大小。
要区别创建文件(createNewFile)还是文件夹(mkdirs)。创建文件夹推荐使用mkdirs。
这是最后运行后在我硬盘的内容。
而我们的循环只能获取一层,如果要获取全部文件,可以试试以下方法。
1 | import java.io.File; |
编码
在记录四大IO类前,先解决一个问题——编码。我们常用的编码有GBK、utf-8、utf-16、ISO-8859-1、GB2312。每种编码格式不一样,如果编码和解码不统一,那么在操作上会出现乱码。
GBK:字母占一个字节,汉字占两个字节。
ISO-8859-1:字节编码。
GB2312:汉字编码,分成94个区,每个区有94位,每位对应一个字。
utf-8:变长unicode编码,字母占一字节,汉字占两字节。
utf-16:定长unicod编码,都占两个字节。还分大端(高字节在低地址)小端(低字节在低地址)。
1 | import java.io.UnsupportedEncodingException; //会抛出异常 |
节点流
从特点的节点来获取与读写数据,而这个节点可能是内存或硬盘等其他地方。
它以字节流和字符流两类。
字节流是一个字节或多个字节传输。一个字节占8bit。
字符流是一个字符或多个字符传输,一个字符占1~3字节,看编码格式。
字符流主要做文本的操作,而字节流还能做图片、音频、视频等等。字符流能做的字节流也能做。
字节流
我们可以从文件中获取内容,但是字节流是一个字节一个字节获取的。下面是读取文件里的内容。
1 | import java.io.FileInputStream; |
把内容写入到文件中。
1 | public class OutputStreamTest { |
而网络中,数据都是以字节获取。而不是文件。所以我们通常是把文件转换成字节,在把字节转换成我们看得懂的字符。
1 | import java.io.ByteArrayInputStream; |
因为直接在网络或其他内存上使用,可以不用close()关闭流。
我们还有数据类型流,和对象流,这里就以数据类做例子,对象流类似。
1 | public class DateType { |
在这里,可不是乱码,是程序把我们写的内容序列化,给程序看的,但不影响我们的使用。而且,取数据,一定要按照存的顺序取。
字符流
用法和FileInputStream与FileOutputStream类似,但字符流传输的是一个或多个字符。
1 | import java.io.FileReader; |
缓冲流
缓冲流是提高效率的,上面的方法,每一次取,都要去原文件里拿。就好比一个加工厂,我每次只拿我本次用的材料,下次还用又从仓库里取下次够用的材料。所以每次取都要跑到仓库里。而缓冲流的效果就是每次从仓库拿一堆材料,每次用都在旁边取,如果不够了,再从仓库拿一堆。这提高了运行效率。
字节流
1 | public class Buffered_IO { |
字符流
字符流中的缓冲流,本身有很多新的方法,所以建议不要多态。
1 | import java.io.BufferedReader; |
转换流
因为网络中都是字节传输,而我们实际可能是想要字符操作,所以我们可以把字节流转换成字符流。
1 | import java.io.BufferedReader; |
但是在指定编码,一定要与自己写的代码编码一致,我这是GBK,所以才写GBK,如果是utf8就写utf8。
还有很多类和方法,都是大同小异。