import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStreamReader;
import
java.util.Scanner;
// System.in和System.out方法
//缺点一: 该方法能获取从键盘输入的字符,但只能针对一个字符的获取
//缺点二: 获取的只是char类型的。如果想获得int,float等类型的输入,比较麻烦。
public
static
void
CharTest(){
try{
System.out.print(
"Enter a Char:");
char
i = (
char)System.in.read();
System.out.println(
"Yout Enter Char is:"
+ i);
}
catch(IOException e){
e.printStackTrace();
}
}
System是一个类属于java.lang包它
表示系统类
,定义如下:public final class
System
extends
Object
//此类为最终类,不能被继承。它有以下两个重要的成员变量:
(1)in:它是一种输入流对像,它的源是键盘,可以读取用户从键盘输入的数据,在读取数据时会引起堵塞,直到用户按下Enter键,读取方法:public int read(char c[],int off,int len)和public int read(char c[])。
(2)out:它是一种输出流对象,它的目的地是命令行窗口,写入方法:public void write(char c[],int off,int len)和public void write(char c[])
in和out为System类的属性:
(1)public static final
InputStream
in
//静态方法,用类名称直接调用,返回InputStream类,也就是说可以为InputStream实例化,
System.in 是 InputStream类型,字节流,程序使用它可读取键盘输入的数据。“标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。
(2)public static final
PrintStream
out
//静态方法,用类名称直接调用,返回PrintStream类,也就是说可以为
Output
Stream实例化
,System.out 是 PrintStream类型(是OutputStream的子类),字节流,程序使用它可将数据输出到显示屏上。“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。
实际上在JAVA中也对IO给予了一定的支持,
System.in, System.out, System.err这3个流同样是常见的数据来源和数据流目的地。使用最多的可能是在控制台程序里利用System.out将输出打印到控制台上。JVM启动的时候通过Java运行时初始化这3个流,所以你不需要初始化它们(尽管你可以在运行时替换掉它们)。
System.in
System.in是一个典型的连接控制台程序和键盘输入的InputStream流。通常当数据通过命令行参数或者配置文件传递给命令行Java程序的时候,System.in并不是很常用。图形界面程序通过界面传递参数给程序,这是一块单独的Java IO输入机制。
System.in作为InputStream类的对象实现标准输入,可以调用它的read方法来读取键盘数据。read方法的参数有:进行
读入数据的缓冲区
、向
数组中将写入数据的初始偏移量、
和
要读取的最大字节数。
System.out
System.out是一个PrintStream流。System.out一般会把你写到其中的数据输出到控制台上。System.out通常仅用在类似命令行工具的控制台程序上。System.out也经常用于打印程序的调试信息(尽管它可能并不是获取程序调试信息的最佳方式)。
System.out作为PrintStream打印流类的的对象实现标准输出,可以调用它的print、println或write方法来输出各种类型的数据。print和println的参数完全一样,不同之处在于println输出后换行而print不换行。write方法用来输出字节数组,在输出时不换行。其中对于
write
(byte[] b, int off, int len)方法参数说明:b
- 数据。
off
- 数据中的初始偏移量。
len
- 要写入的字节数。
然而在PrintStream中重写了write方法,其对于重写后write方法参数的说明:buf
- byte 数组
off
- 相对于开始写入字节处的偏移量
len
- 要写入的字节数
替换系统流
尽管System.in, System.out这2个流是java.lang.System类中的静态成员(这2个变量均为final static常量),并且已经预先在JVM启动的时候初始化完成,你依然可以更改它们。只需要把一个新的InputStream设置给System.in或者一个新的OutputStream设置给System.out,之后的数据都将会在新的流中进行读取、写入。可以使用System.setIn(), System.setOut()方法设置新的系统流(这二个方法均为静态方法,内部调用了本地native方法重新设置系统流)。
请记住,务必在JVM关闭之前冲刷System.out(调用flush()),确保System.out把数据输出到了文件中。
// InputStreamReader和BufferedReader方法
// 优点: 可以获取键盘输入的字符串
// 缺点: 如何要获取的是int,float等类型的仍然需要转换
public
static
void
ReadTest(){
System.out.println(
"ReadTest, Please Enter Data:");
InputStreamReader is =
new
InputStreamReader(System.in);
//new构造InputStreamReader对象
BufferedReader br =
new
BufferedReader(is);
//拿构造的方法传到BufferedReader中,
此时获取到的就是整个缓存流
try{
//该方法中有个IOExcepiton需要捕获
String name = br.readLine();
System.out.println(
"ReadTest Output:"
+ name);
}
catch(IOException e){
e.printStackTrace();
}
}
InputStreamReader : 是字节流与字符流之间的桥梁,能将字节流输出为字符流并且能为字节流指定字符集
如果不指定的话将采用底层操作系统的默认编码方式
,可输出一个个的字符
,它封裝了InputStream在里头,以较高级的方式一次读取一个一个字符。
BufferedReader :
它则是比InputStreamReader更高级,它封裝了StreamReader类,一次读取取一行的字符
提供通用的缓冲方式文本读取,readLine读取一个文本行, 从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。
java.io下面有两个抽象类:InputStream和Reader也就是分别表示字节流和字符流,
InputStream是表示字节输入流的所有类的超类,提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。Reader是用于读取字符流的抽象类,
通常Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求,如果没有缓冲则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
即用Reader读取出来的是char数组或者String ,使用InputStream读取出来的是byte数组。
那为什么需要InputStreamReader和
BufferedReader互相配合,
因为InputStreamReader是字节输出(汉字会被分为两个字节),而BufferedReader是它的“包装”(整行读取),效率更高,所以配合使用更好。可以通过BufferedReader 流的形式进行流缓存,之后通过readLine方法获取到缓存的内容。
//Scanner类中的方法
//优点一: 可以获取键盘输入的字符串
//优点二: 有现成的获取int,float等类型数据,非常强大,也非常方便;
public
static
void
ScannerTest(){
Scanner sc =
new
Scanner(System.in);
System.out.println(
"ScannerTest, Please Enter Name:");
String name = sc.nextLine();
//读取字符串型输入
System.out.println(
"ScannerTest, Please Enter Age:");
int
age = sc.nextInt();
//读取整型输入
System.out.println(
"ScannerTest, Please Enter Salary:");
float
salary = sc.nextFloat();
//读取float型输入
System.out.println(
"Your Information is as below:");
System.out.println(
"Name:"
+ name +
"\n"
+
"Age:"+age +
"\n"+
"Salary:"+salary);
}
Scanner是Java5的新特征,主要功能是简化文本扫描。
Scanner的中文意思就是扫描仪,也就是将一份数据从一个地方扫描并显示到另外一个地方
。
一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
Scanner
使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的
next
方法将得到的标记转换为不同类型的值。当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象。而且
Scanner类有一个假设,在输入结束时会抛出IOException,而Scanner类会把这个异常吞掉。
经常有人说使用Scanner的原因是因为
它使用简便,不如说Scanner的构造器支持多种方式,构建Scanner的对象很方便。可以从
字符串(
Readable
)、输入流、文件等等来直接构建Scanner对象
,
有了Scanner了,就可以逐段(根据正则分隔式)来扫描整个文本,并对扫描后的结果做想要的处理。
scanner好比一个带游标或者指针的扫描仪,调用其hasNextLine()好比将游标向前探索直到遇到一个换行符,如果这个过程中遇到字符串对象则返回true并且游标复位。调用其nextLine()方法其实就是游标向前探索直到遇到一个换行符,此时并不复位,而是游标直接定位到目标数据的下一行,并返回探索过程中检测到的数据包括空格。
java里常使用的方法next() 与 nextLine() 区别
next():
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- next() 不能得到带有空格的字符串。
nextLine():
- 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
- 2、可以获得空白。