input output
1. 流,从大的方向说包括输入输出流,从传输的方式说,包括字节流,字符流
2. 什么时候用字节流,什么时候用字符流
当读取二进制文件或者说是网络上的资源的时候就用字节流
当读取纯文本文件的时候,就用字符流
字节流:只要是XXXStream的类,代表的就是字节流,XXXReader或XXXWriter的是字符流。字节流包括输入字节流,输出字节流,其中输入字节流的祖先是InputStream,输出字节流的祖先是OutputStream,这两个类都是抽象类,我们看的是他们的子类。主要是 FileInputStream 、ByteArrayInputStream、ObjectStream、DataIputStream、等。。
一 FileInputStream 对文件的读取操作
public class TT {
public static void main(String[] args) throws Exception {
FileInputStream fis=new FileInputStream("c:\\1.txt");
int hasRead=0;
while((hasRead=fis.read())!=-1){
System.out.println((char)hasRead);
}
}
}
在这个类里面有一个read()方法,返回类型是一个int,当读取到文件的末尾的时候返回的是-1,这个read()方法每次读取一个byte,如果文件中有中文的话就会出现乱码,一个中文占两个byte,这个read()方法读取过来之后不会自动将字节组合,这时候我们看到read()方法被重载了,里面可以放一个byte类型的数组,这个数组我们可以理解为是一个舀水的工具,我们可以将要读取的文件想象成为一个水缸,每次我都去水缸里取我定义大小的字节数组去取水,具体代码如下
public static void main(String[] args) throws Exception {
FileInputStream fis=new FileInputStream("c:\\1.txt");
int hasRead=0;
byte [] buffer=new byte[1024];
while((hasRead=fis.read(buffer))!=-1){
String s=new String (buffer);
System.out.println(s);
}
Fis.close();
}
这个时候,一次就读取buffer数组里面这么大的字节数据,但是,又会出现问题,当我每次读取文件之后,剩下的部分不足以填充整个数组,但是数组中那些剩下的空的字节也会读取过来构成新的东西,这时候我们看到当new一个String类型时候,后面的括号中还可以放入参数,我实际读了多少长度就构建多少长度。While中的代码就变成了如下:
while((hasRead=fis.read(buffer))!=-1){
String s=new String (buffer,0,hasRead);//其中第一个参数是读取的字节数组,
// 第二个参数是从哪个位置开始读取,最后
// 一个参数是实际读取了多少长度
System.out.println(s);
}
那么这个时候我们就要开始想,这个数组的定义是怎样规定的呢,是不是越大越好?
当然肯定不是的,这个地方要考根据操作系统和文件系统去断定,文件系统的block问题,和操作系统的内存页问题,操作系统的内存页一般是8192byte这时候一般规定为8192byte的大小,这样操作系统读取一次就可以翻一页,文件系统一般是4k一个block,所以如果考虑文件系统的话一般设置为1024就可以。
二FileOutputStream 对文件的写操作
FileOutputStream fos=new FileOutputStream("c:\\1.txt",true);
String ss="庄生晓梦迷蝴蝶,望帝春心托杜鹃";
fos.write(ss.getBytes());
fos.flush();
fos.close();
代码解释:其中搭建了一个输出流的管道,想1.txt文件中写东西。用的是输出字节流,写的时候要将String类型转换为字节数组。其中flush方法是不需要利用系统的写缓存,必须等到将要写的东西写入到文件中去才能关闭这个流。最后close方法就是关闭。