Java中BufferedReader与Scanner读入的区别详解
java.util.scanner
类是一个简单的文本扫描类,它可以解析基本数据类型和字符串。它本质上是使用正则表达式去读取不同的数据类型。
java.io.bufferedreader
类为了能够高效的读取字符序列,从字符输入流和字符缓冲区读取文本。
在java中,我们都知道java的标准输入串是system.in。但是我们却很少在java中看到谁使用它,这是因为我们平时输入的都是一个字符串或者是一个数字等等。而system.in提供的read方法是通过字节来读取数据的,所以对我们来说不方便处理!
scanner
在java se6提供了一个非常方便的输入数据的类scanner,位于java.util包中,这个scanner的具体用法为scanner in = new scanner(system.in)。
通过new创建一个scanner对象,scanner需要传入一个system.in作为参数,这个我们可以看作是scanner通过其内部机制将system.in包装起来而实现数据的读取工作的。
scanner对象通过一系列的in.nextxxx();方法来读取相应的基本类型的数据,通过in.hasnextxxx();方法来判断是否还有下一个数据。
然而,scanner读取数据是按空格符(这其中包括空格键,tab键,enter键)来分割数据的。
只要遇到其中之一,scanner的方法就会返回下一个输入(当然nextline()方法的结束符为换行符,它会返回换行符之前的数据),这也就是我们会面临的另一个问题,当我们的输入数据中有空格时,我们就不会得到我们想要的数据,这样我们就要考虑到bufferreader来读取数据!
bufferreader
bufferreader位于java.io包中,使用bufferreader就相对来说没有那么多方法来让你选择!读取数据比较固定,这样格式也就相对来说比较单一,只要记住就这一读取数据的方法。
bufferedreader br = new bufferedreader (newinputstreamreader(system.in));
这个bufferreader对象通过readline();方法来读取数据,readline()是按enter回车来读取一行数据的,只要在回车键之前的都会被readline()方法返回。
readline()方法返回的是字符串,因此要使用bufferreader输入一些字符之外的类型的数据,就要相对比较麻烦,需要通过一些xxxx.parsexxx();来转换相应的数据类型,(例如:int类型的用integer.parseint(需要转换的字符串))。
虽然麻烦一些,但通过bufferreader读入的效率要比scanner高一倍,这个差距可想而知,而且读取的数据越多,效果就越明显。
需要注意的是使用bufferedreader对象的readline()方法必须处理java.io.ioexception异常。
两者的对比
1、scanner提供了一系列nextxxx()方法,当我们确定输入的数据类型时,使用scanner更加方便。也正是因为这个bufferedreader相对于scanner来说要快一点,因为scanner对输入数据进行类解析,而bufferedreader只是简单地读取字符序列。
2、scanner和bufferedreader都设置了缓冲区,scanner有很少的缓冲区(1kb字符缓冲)相对于bufferedreader(8kb字节缓冲),但是这是绰绰有余的。
3、bufferedreader是支持同步的,而scanner不支持。如果我们处理多线程程序,bufferedreader应当使用。
4、scanner输入的一个问题:在scanner类中如果我们在任何7个nextxxx()方法之后调用nextline()方法,这nextline()方法不能够从控制台读取任何内容,并且,这游标不会进入控制台,它将跳过这一步。nextxxx()方法包括nextint(),nextfloat(), nextbyte(),nextshort(),nextdouble(),nextlong(),next()。
在bufferreader类中就没有那种问题。这种问题仅仅出现在scanner类中,由于nextxxx()方法忽略换行符,但是nextline()并不忽略它。如果我们在nextxxx()方法和nextline()方法之间使用超过一个以上的nextline()方法,这个问题将不会出现了;因为nextline()把换行符消耗了。
程序示例
package com.zxt.base; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; import java.util.scanner; public classsystemintest { private static scanner sc; public static void main(string[] args) { // 使用scanner输入 sc = new scanner(system.in); int num1 = sc.nextint(); int num2 = sc.nextint(); system.out.println("num1 + num2 = "+ (num1+ num2)); // 使用bufferreader输入 inputstreamreaderisr = newinputstreamreader(system.in); bufferedreaderbr = new bufferedreader(isr); try { int num3 = integer.parseint(br.readline()); int num4 = integer.parseint(br.readline()); system.out.println("num3 + num4 = "+ (num3+ num4)); }catch(numberformatexception | ioexception e) { e.printstacktrace(); } // 使用scanner输入会遇到的问题 system.out.println(); system.out.print("enter an integer:"); int intvalue = sc.nextint(); system.out.print("enter a string:"); stringstrvalue = sc.nextline(); system.out.printf("you have entered intvalue is " + intvalue+ " and strvalue is " + strvalue); // 问题原因:由于nextxxx()方法忽略换行符,但是nextline()并不忽略它。所以如果我们在nextxxx()方法后面使用nextline()将会出现问题 // 解决方案是:在使用nextxxx()方法后,在使用nextline()读取下一行数据前,多使用一个nextline()用来消耗换行符 // int intvalue = sc.nextint(); // sc.nextline(); // string strvalue = sc.nextline(); // 或者使用bufferreader不会出现该问题 system.out.println(); try { system.out.print("enter an integer:"); int intvalue1 = integer.parseint(br.readline()); system.out.print("enter a string:"); stringstrvalue1 = br.readline(); system.out.printf("you have entered intvalue1 is " + intvalue1+ " and strvalue1 is " + strvalue1); }catch(numberformatexception | ioexception e) { e.printstacktrace(); } } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。