IO流的分类
按照不同的角度分类,概念上可能重叠。主要在于更好的理解。
1.输入流和输出流
以内存为依据,从内存中输出数据为输出流;往内存中输入数据为输入流。
2.字节流和字符流
以一个byte8个字节为单位输入输出数据的为字节流;以一个字符2个字节为单位输入输入数据的为字符流。
3.节点流和处理流
节点流就是直接与IO设备输入输出,它是低级流;处理流是包装了的节点流。它的包装使得不同类型的节点流在相同程序中被访问时,可以采用相同的代码。
java中的IO处理
在java中对字节流和字符流他们的处理方式是一样的,只是他们数据源的单位不一样,一个是一个字节为单位,一个是2个字节为单位。
java的API中,inputStream和Reader是两个抽象的基类,它们分别处理字节流和字符流。
有如下方法:
int read()每次自动读取一个byte/char的数据,返回该byte/char数据。
int read(byte[] buff)最多读取buff.length个byte/char的数据,返回实际读取的byte/char个数。
int read(byte[] buff,String off,String length)从off开始读取数组中的数据,最多读取length个byte/char的数据,返回实际读取的byte/char个数。
例1,通过读取文件原样打印到console。
public static void printString(String fileName){
/*采用了jdk1.7的新功能try-with-resources,只要实现AutoCloseable接口的类在
* try的括号内创建的对象就可以自动关闭.
*
*/
try(FileInputStream in = new FileInputStream(fileName)) {
byte[] b = new byte[1024];
int count = 0;
while((count = in.read(b))!=-1){
//采用默认的编码方式解码自己数组。构造一个性的String
System.out.println(new String(b, 0, count));
}
} catch (FileNotFoundException e) {//多个catch语句块必须,先写异常的最小子类。不然编译器会报错
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
例子2,将读取的数据以十六进制打印到console。有两种方式,一种是一个字节一个字节的读取输出,另一种是按字节数组的方式批处理数据读取输出。两种的效率是不同的,见代码。
代码1
public static void printHex(String fileName)throws IOException {
FileInputStream fis = new FileInputStream(fileName);
int b = 0;
int count = 0;
while((b=fis.read())!=-1){
System.out.print(Integer.toHexString(b)+" ");
count++;
if( count%10 == 0){
System.out.println();
}
}
fis.close();
}
代码2
public static void printHexByByteArray(String fileName)throws IOException{
FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[8 * 1024];
int bytes = 0;
int j = 1;
while((bytes = in.read(buf,0,buf.length))!=-1){
for(int i = 0 ; i < bytes;i++){
System.out.print(Integer.toHexString(buf[i]&0xff)+" ");
if(j++%10==0){
System.out.println();
}
}
}
in.close();
}
测试函数:
public static void main(String[] args)throws IOException{
String fileName = "D:\\corejava9.zip";
// long startTime01 = System.currentTimeMillis();
// IO_Util.printHex(fileName);
// long endTime01 = System.currentTimeMillis();
// System.out.println("按字节处理该文件的时间"+(endTime01-startTime01));//18558ms
long startTime02 = System.currentTimeMillis();
IO_Util.printHexByByteArray(fileName);
long endTime02 = System.currentTimeMillis();
System.out.println("批处理该文件的时间"+(endTime02-startTime02));//11386ms
可以看出批处理的速度还是快很多的。对文件的读取需要注意一些技巧。