IO流
一、字符流和字节流
-
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:
-
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。 -
结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。
二、流分类
1、文件流(File+抽象类型)
-
FileInputStream该流用于从文件读取数据
-
写法(FileOutputStream类似):
InputStream f = new FileInputStream("C:/java/hello"); 或者: File f = new File("C:/java/hello"); InputStream out = new FileInputStream(f);
-
常用方法(在使用完后一定记得close)
//这个方法从 InputStream 对象读取指定字节的数据。返回为整数值。返回下一字节数据,如果已经到结尾则返回-1。 public int read(int r)throws IOException{}//写对应:write //这个方法从输入流读取r.length长度的字节,并赋值到r中。返回读取的字节数。如果是文件结尾则返回-1(若文本最后剩的字节不足length,且字节>0,依旧不返回-1,要完全无字节才返回-1)。 public int read(byte[] r) throws IOException{}//写对应write //关闭此文件输入流并释放与此流有关的所有系统资源。抛出IOException异常 public void close() throws IOException{} public long skip(long n) // 从输入流中跳过并丢弃 n 个字节的数据。返回实际跳过的字节数。
-
注意:windows中txt默认编码为ANSI,所以读取时会乱码,可设置为UTF-8。
2、缓冲流(Buffered+抽象类型)
-
作用:如果不用缓冲流的话,程序是读一个数据,写一个数据。这样在数据量大的程序中非常影响效率。
缓冲流作用是把数据先写入缓冲区,等缓冲区满了,再把数据写到文件里。这样效率就大大提高了 -
基本的原始流InputStream 有read(byte[]) 一次性地读取多个字节.这个byte[] 字节数组实际上也是1个缓冲区.那么为何还需要缓冲流呢?答案就是 缓冲流有预读机制,比起使用缓冲数组的缓冲效果更加明显, 如果处理一些大数据文件, 或者网络传输, 使用缓冲流的效果会更加好!
-
常用方法:
//这个是缓冲输入流最常用的构造方法.后面参数为设置缓冲的大小 new BufferedInputStream(InputStream is, int bufferSize) //读取一个字节放入缓冲区, 用法与InputStream的read()基本一样的. int read() throws IOException //读取若干个字节放入字节数组bytArr, 返回实际读取的字节个数, 用法与InputStream的同名同参方法基本一样. int read(byte[] bytArr) throws IOException
-
注意:read(byte[] b)方法返回的是实际读取的字节数,若文件中字节数不足b.length ,读取的是剩下的字节。所以写的时候尽量用write(byte[]b,int off,long length)将length设置为read实际读取的字节数,从而保证文件的读取正常。
原理细节(System.in 、InputStreamReader、BufferedReader)
- 一个 InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。
- InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader
- 例如:
InputStreamReader in = new InputStreamReader(System.in);
// System.in为系统基本输入输出,即键盘输入.调用System.in方法获得输入字符串,并用该字符串作为参数生成一个InputStreamReader对象in
BufferedReader dr = new BufferedReader(in);
//用InputStreamReader对象in作为参数生成一个IBufferedReader对象dr.用BufferedReader 封装 InputStreamReader,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。