InputStreamReader和BufferedReader用法及实例讲解
一、BufferedReader类
.所属类库:
java.lang.Object
java.io.Reader
java.io.BufferedReader
.基本概念:
publicclassBufferedReader extendsReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值足够大。
通常,Reader所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用BufferedReader包装所有其read()操作可能开销很高的Reader(如FileReader和InputStreamReader)。
BufferedReader流能够读取文本行,通过向BufferedReader传递一个Reader对象,来创建一个BufferedReader对象,之所以这样做是因为FileReader没有提供读取文本行的功能.
.Demo:
通过Bufferedreader捕获所输入的语句:
importjava.io.*; classBufferedReaderDemo{ publicstaticvoidmain(String[]args)throwsIOException{ BufferedReaderbufferedReader=newBufferedReader( newInputStreamReader(System.in)); System.out.print("请输入一系列文字,可包括空格:"); Stringtext=bufferedReader.readLine(); System.out.println("请输入文字:"+text); } }
注解:
throwsIOException 抛出异常
InputStreamReader是字节流通向字符流的桥梁
二、InputStreamReader类
InputStreamReader将字节流转换为字符流。是字节流通向字符流的桥梁。如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:GBK。
构造方法:
InputStreamReaderisr=newInputStreamReader(InputStreamin);//构造一个默认编码集的InputStreamReader类
InputStreamReaderisr=newInputStreamReader(InputStreamin,StringcharsetName);//构造一个指定编码集的
InputStreamReader类。
参数in对象通过InputStreamin=System.in;获得。//读取键盘上的数据。
或者InputStreamin=newFileInputStream(StringfileName);//读取文件中的数据。可以看出FileInputStream为InputStream的子类。
主要方法:intread();//读取单个字符。
intread(char[]cbuf);//将读取到的字符存到数组中。返回读取的字符数。
.Demo:
importjava.io.*; classInputStreamReaderDemo{ publicstaticvoidtransReadNoBuf()throwsIOException{ /** *没有缓冲区,只能使用read()方法。 */ //读取字节流 //InputStreamin=System.in;//读取键盘的输入。 InputStreamin=newFileInputStream("D:\\demo.txt");//读取文件的数据。 //将字节流向字符流的转换。要启用从字节到字符的有效转换, //可以提前从底层流读取更多的字节. InputStreamReaderisr=newInputStreamReader(in);//读取 //综合到一句。 //InputStreamReaderisr=newInputStreamReader( //newFileInputStream("D:\\demo.txt")); char[]cha=newchar[1024]; intlen=isr.read(cha); System.out.println(newString(cha,0,len)); isr.close(); } publicstaticvoidtransReadByBuf()throwsIOException{ /** *使用缓冲区可以使用缓冲区对象的read()和readLine()方法。 */ //读取字节流 //InputStreamin=System.in;//读取键盘上的数据 InputStreamin=newFileInputStream("D:\\demo.txt");//读取文件上的数据。 //将字节流向字符流的转换。 InputStreamReaderisr=newInputStreamReader(in);//读取 //创建字符流缓冲区 BufferedReaderbufr=newBufferedReader(isr);//缓冲 //BufferedReaderbufr=newBufferedReader( //newInputStreamReader(newFileInputStream("D:\\demo.txt")));可以综合到一句。 /*intch=0; ch=bufr.read(); System.out.println((char)ch); */ Stringline; while((line=bufr.readLine())!=null){ System.out.println(line); } isr.close(); } }
三、InputStreamReader、BufferedReader真实案例(非编码集)
importjava.io.*; classUtilResource{ privatevoidinitializeResource(){ try{ //读取文件,并且以utf-8的形式写出去 BufferedReaderbufread; Stringread; bufread=newBufferedReader(newInputStreamReader(ResourceHelper .getResourceInputStream("pinyin.txt"))); while((read=bufread.readLine())!=null){ System.out.println(read); } bufread.close(); }catch(FileNotFoundExceptionex){ ex.printStackTrace(); }catch(IOExceptionex){ ex.printStackTrace(); } } }
注:其中pinyin.txt放于项目的根目录下
importjava.io.BufferedInputStream; importjava.io.FileInputStream; importjava.io.FileNotFoundException; classResourceHelper{ /** *@paramresourceName *@return *@return */ staticBufferedInputStreamgetResourceInputStream(StringresourceName){ try{ returnnewBufferedInputStream(newFileInputStream(resourceName)); }catch(FileNotFoundExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } returnnull; } }
总结:
InputStreamReader类
是字节流通向字符流的桥梁,封裝了InputStream在里头,它以较高级的方式,一次读取一个一个字符,以文本格式输入/输出,可以指定编码格式;
BufferedReader类
BufferedReader由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取一个文本行,从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
ps:InputStream、InputStreamReader和Reader的关系
InputStream:得到的是字节输入流,InputStream.read("filename")之后,得到字节流
Reader:读取的是字符流
InputStreamReader:从字节到字符的桥梁。InputStreamReader(InputStream.read("filename"));
reader.read(InputStreamReader(InputStreamin));便可从字节变为字符,打印显示了。
java.io.Reader和java.io.InputStream组成了Java输入类。
Reader用于读入16位字符,也就是Unicode编码的字符;而InputStream用于读入ASCII字符和二进制数据。
Reader支持16位的Unicode字符输出,InputStream支持8位的字符输出。
Reader和InputStream分别是I/O库提供的两套平行独立的等级机构,1byte=8bits InputStream、OutputStream是用来处理8位元的流,Reader、Writer是用来处理16位元的流。
而在JAVA语言中,byte类型是8位的,char类型是16位的,所以在处理中文的时候需要用Reader和Writer。
值得说明的是,在这两种等级机构下,还有一道桥梁InputStreamReader、OutputStreamWriter负责进行InputStream到Reader的适配和由OutputStream到Writer的适配。
在Java中,有不同类型的Reader输入流对应于不同的数据源:
FileReader用于从文件输入;CharArrayReader用于从程序中的字符数组输入;StringReader用于从程序中的字符串输入;PipedReader用于读取从另一个线程中的PipedWriter写入管道的数据。
相应的也有不同类型的InputStream输入流对应于不同的数据源:FileInputStream,ByteArrayInputStream,StringBufferInputStream,PipedInputStream。
另外,还有两种没有对应Reader类型的InputStream输入流:Socket用于套接字;URLConnection用于URL连接。这两个类使用getInputStream()来读取数据。
相应的,java.io.Writer和java.io.OutputStream也有类似的区别。
关于InputStream.read(byte[]b)和InputStream.read(byte[]b,intoff,intlen)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅读Java的API说明就发现了,这个方法并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。因此,如果要让程序读取count个字节,最好用以下代码:
byte[]b=newbyte[count]; intreadCount=0;//已经成功读取的字节的个数 while(readCount<count){ readCount+=in.read(bytes,readCount,count-readCount); }
用这段代码可以保证读取count个字节,除非中途遇到IO异常或者到了数据流的结尾(EOFException)