先总结一下用法,后面是详细介绍:
- System.in 读取单个byte,可以读取ASCII码中的字符
- InputStreamReader 读取单个\一串字符,这个字符可以是任意编码(并且可以指定编码方式)
- BufferedReader 读取一行字符。
- Scanner :最强最通用的方法,可以读取指定类型的字符。
一、System.in
这是一个标准输入流,并且可以通过它从键盘中获取字节流。
官方描述: The "standard" input stream. This stream is already open and ready to supply input data. Typically this stream corresponds to keyboard input or another input source specified by the host environment or user.
System.in.read():返回从键盘输入的字节流。
键盘输入的信息是用UTF-8编码的,而read()每次返回一个字节。也就是说假如输入是ASCII中的编码,刚好可以返回一个完整字符。
可以将read()的返回值强制转换为char。 (注: char类型实际是utf16存储的,但是对于ASCII码,utf-8和utf-16对应的数字都是一样的)
while(true){
char c = (char)System.in.read();
System.out.println(c);
}
运行效果:(绿字为输入,白字为输出)
但是假如输入的是汉字,就比较麻烦了。汉字的UTF-8是3字节。也就是说会返回3个byte
while(true){
System.out.println(System.in.read());
}
230 177 137刚好是"汉"的utf-8编码
总结:System.in.read()是按字节读取,可以用来读取ASCII码中的字符,不适合读取UTF-8中占多位的字符。
二、使用InputStreamReader将字节流转换为字符流读取
InputStreamReader ir = new InputStreamReader(System.in);
while(true){
char c = (char)ir.read();
System.out.println(c);
}
以上代码的效果是: 每次读取一个字符(而不是字节),也就是说,现在可以直接读取汉字了。
什么是InputStreamReader? 他是一个将字节流转换为字符流的“桥”。默认情况下,它可以将字节按UTF-8解码,并编码成char类型(即utf16),以在java中显示。
源码中的解释如下:
public InputStreamReader(InputStream in) {
super(in);
sd = StreamDecoder.forInputStreamReader(in, this,
Charset.defaultCharset());
}
InputStreamReader还可以选定解码方式。比如:
InputStreamReader ir = new InputStreamReader(System.in,"UTF-16");
不过这样解析出来是乱码。因为键盘输入是UTF-8编码。
三、使用BufferedReader,利用缓存实现整行读取
如何读取一串字符呢?首先想到可以把字符全缓存到一个char[] 数组中 实际上,InputStreamReader的read方法就能实现这样的效果。
InputStreamReader ir = new InputStreamReader(System.in);
char[] buffer = new char[10];
while(true){
ir.read(buffer);
System.out.println(buffer);
}
buffer存储的内容是:
假如我们想仅读取一行数据怎么办?可以遍历查找到’\n’,再用’\n’前面的字符中构造字符串。方法这里就不写了。
这样,我们通过自定义一个缓存区,实现了一串字符的读取。 java中提供了BufferedReader类,该类内置了缓存区,我们就可以实现整行读取,不需要自己再设置缓存区。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
String str = br.readLine();
System.out.println(str);
}
四、Scanner:格式化读取
这应该是最常用的读取方式 首先可以做到前面的读取一行字符的功能:
Scanner in = new Scanner(System.in);
while(true){
if(in.hasNextLine())
System.out.println(in.nextLine());
}
效果:
Scanner可以说集成了前面的各种输入方法。
1、字符串解码:Scanner构造时的参数是字节流,肯定需要解码才能转为字符,默认使用UTF-8解码,但是也可以指定其他解码方式
Scanner in = new Scanner(inputStream,"UTF-16");
2、缓存输入字符。使用的是一个CharBuffer类作字符缓存,其内部是char[]存储的 3、将字符解析为基本类型。类似ParseInt等函数的作用。
nextInt()读取数字
Scanner in = new Scanner(System.in);
while(true){
if(in.hasNextLine())
System.out.println(in.nextInt()*10);
}
还可以指定进制:这里以20进制为例
Scanner in = new Scanner(System.in);
while(true){
if(in.hasNextLine())
System.out.println(in.nextInt(20));
}
(20进制中的j相当于10进制中的19)
另外还有其他的很多方法,不一一列举了,比较简单。
|