1
java IO流包括字节流和字符流。字节流包括输入流、输出流。字符流也同样包括输入流和输出流。本节介绍字节流。
2
字节流最重要的,也是最常用的2个基类:
InputStream:抽象了应用程序读取数据的方式;
OutputStream:抽象了应用程序写出数据的方式。
另,当读取文件读到EOF,或者-1,就代表读取结束。
3
输入流基本方法是读,所以输入流的类基本都有以下几种方法:
int i = in.read();读取一个字节无符号填充到int的低8位,高8位补零,读取到-1结束;
in.read(byte[] buf)读取数据填充到字节数组buf中,可以一次性读取多个字节;
in.read(Byte[] buf,int start,int size)读取数据到字节数组buf中,从buf的start位置开始存放size长度的数据
4
输出流基本方法是写,所以输出流的类基本都有以下几种方法:
out.write(int b):写出一个byte到文件中,写的是b的低8位;
out.write(byte[] buf),将buf字节数组都写入到文件;
out.write(bute[] buf,int start,int size);字节数组buf从start开始,写入size长度的字节到流
5
但是InputStream和OutputStream都是抽象类,如下图所示,会提示无法实例化。
6
InputStream有许多子类,比如FileInputStream,实现了具体在文件中读取数据的各种方法。同理,OutputStream还有一个子类FileInputStream,实现了向文件中写入数据的各种方法。
当然,还有很多其他的子类。
7
这里的重点是,字节流操纵的是字节,不是字符。举个例子:
使用字节流,我们从一个文件中读取数据,然后写入到另一个文件的过程。
首先,这个文件中存放的是字符,并且是某一个种编码格式,比如UTF-8格式。那么,这个文件中的字符在电脑中存放的二进制文件就是以UTF-8格式存放的,所以字节流读取的数据就是这些以UTF-8格式存放的二进制;然后,字节流再将这些二进制文件写入到另一个文本中,写入的就是以UTF-8格式存放的二进制文件,然后文本文档自己判断这些二进制文件是UTF-8格式,就会用这种格式将字节转变为字符,我们人就可以看得懂了。
8
看了例子:我们创建一个文本,写入一个字“你”,然后保存为UTF-8格式。
9
然后,我们使用字节流从这个文本读取数据。代码如下:
File file = new File("D:/alsp/hello.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int b;
int i = 1;
while((b = fileInputStream.read()) != -1){
System.out.print(Integer.toHexString(b) + " ");
}
System.out.print("\n");
fileInputStream.close();
10
运行下程序,看下结果,总共6个字节,前面3个字节不管,只的是本文档是UTF-8格式,后面3个字节是“你”,在UTF-8,一个中文一般占3个字节。这也就验证了之前说的,文本中存放的是字符,这个字符在电脑中存放的二进制文件就是UTF-8格式,然后我们的字节流读取的就是3个字节。
11
现在,我们再把刚才的文本改为ANSI格式,其实也就是GBK格式。
12
再运行下上述代码,发现是2个字节,因为GBK格式的汉字,一个就占2个字节。
13
下面我们再看输出流。比如:就往一个文件中写入一个字符。代码如下:
File file = new File("D:/alsp/world.txt");
FileOutputStream out = new FileOutputStream(file);
out.write('A');
14
然后我们看一下D:/alsp/world.txt中的内容,发现有了一个字符A了。
15
不要以为到这里结束了,其实是有玄机的。首先,java的一个字符其实是占2个字节的,因为java使用的是UTF-16BE,一个字符是2个字节。但是,out.write()其实只能写一个字节过去,这里是如何处理的呢?其实out.write('A');只写出了‘A’的低8位而已。而我们的文本文档,无论是ANSI格式还是UTF-8等格式,都是可以正确识别这一个字节的,所以没有问题。
16
看如下代码:
Character a = 'A';
System.out.println(a.SIZE);
打印的结果为16,所以是16位,2个字节。也证明了java中一个字符为2个字节
17
下面,我们再将之前读取的文件内容,再写入到另一个文件中。但是,我们做一点小改变。
首先,将hello.txt文件的编码格式改为:utf-8,将内容改为“你好呀”
18
再将world.txt的编码格式改为:ANSI
19
运行如下程序,
File file1 = new File("D:/alsp/hello.txt");
File file = new File("D:/alsp/world.txt");
FileInputStream fileInputStream = new FileInputStream(file1);
FileOutputStream out = new FileOutputStream(file);
int b;
int i = 1;
while((b = fileInputStream.read()) != -1){
System.out.print(Integer.toHexString(b) + " ");
out.write(b);
}
20
再打开world.txt,发现正确写入了“你好呀”。再看world.txt格式,已经被改为了UTF-8格式了。
21
这也就证明我们之前所说的,将二进制格式写入到文件中,文本文档会自己识别出这些二进制到底是什么格式的,然后以这种格式将二进制变成我们认识的字符。而我们日常生活中有时候遇到的乱码,就是格式不对。比如,以UTF-8格式写的字符,偏偏要以ANSI格式打开,那肯定是乱码的。
END