`
xlcai
  • 浏览: 19873 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

详细整理Java 从命令控制台输入数据读取输入流System.in的几种常用方法

 
阅读更多

一、System.in(最笨的方法)

首先看jdk的API.

System的静态方法in返回的是一个InputStream类型的对象,则我们可以用读取输入流的方式对其进行读取。

按API的说法“此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。”键盘上按下的任何一个键都会被当做是输入值。

如何回显输入值?

我们就用读取输入流的方式进行读取,还是看API

InputStream包含方法read();read(byte[] b);read(byte[] b, int off, int len) ;

1、read();

看API从输入流中读取数据的下一个字节。返回 0255 范围内的 int 字节值。

返回一个整型字节数据,该数据表示的是字节因此是Unicode的第一个字节或是字符的ASCII码值。该方法是从一个流中一个一个的读取数据,因此是一个迭代的过程。

如果到达流的末尾,则返回 -1

重复调用System.in.read()实际上是在遍历该流中的每一个字节数据。最常见的流是键盘输入流。以下为例:

import java.io.IOException;
public class Test1 {
	public static void main(String[] args) throws IOException {
		System.out.println("请输入:");
		int i = 0;
		while(i!=-1){//读取输入流中的字节直到流的末尾返回1
			i = System.in.read();
			System.out.println(i);
		}
	}
}

如图我们输入ABCD则返回了其ASCII值 如果System.out.println(i);改为System.out.println((char)i);强制转换为char字符,则输出ABCD

这里的13和10是读取的键盘的回车,我们在键盘上按一下回车键,实际上读取到的是两个字符,即“\r”(13)和“\n”(10)。字符“\r”表示回车,即光标回到当前行的行首而不换行;字符“\n”表示换行,即光标移到当前行的下一行行首。

(这里还要PS下回车的来历:

回车 \r 本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return
换行 \n 本义是光标往下一行(不一定到下一行行首),n的英文newline,控制字符可以写成LF,即Line Feed
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。

后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。
/*======================================*/
\n:  UNIX 系统行末结束符
\n\r: window 系统行末结束符
\r:  MAC OS 系统行末结束符
/*======================================*/
一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号
有兴趣可以去查看相关资料
)

这里还有一个小情况,看下面的小例子

import java.io.IOException;
public class Test2 {
	public static void main(String[] args) throws IOException {
		System.out.println("请输入:");
		char ch = (char)System.in.read();
		System.out.println("hello" + ch + "AB");
		}
	}
很明显这是只读取一个字符,然后插入到字符串“hello”和“AB”之间,我们无论输入1个字符还是多个字符都是只读取第一个字符,如输入“UFO”
打印出“helloUAB”但我们不输入任何值只按一个回车时,在cmd命令窗口与IDE工具(eclipse)输出就不一样了,如下图:

cmd命令行,编译运行结果 eclipse运行结果输入“UFO” 和只按回车两种情况

我们可以注意到输入其它字符的运行结果一样,直接按回车的话,cmd下打印出的是"ABllo",也就是说cmd回车(获得两个字符“\r”和“\n”),只读取了第一个字符“\r”,即将光标放到行首不换行,所以导致了覆盖hello,那为什么在IDE工具(eclipse)下也是只读取了回车,却换行了呢,这应该是eclipse将回车与换行是连用的,无论是System.out.print("a\rb");System.out.print("a\nb");还是System.out.print("a\r\nb");输出都是a回车b.此句系本人杜撰,大家可以亲试核实。好了read()就说这些了

2、read(byte[] b)

API里InputStream的read(byte[] b)同样是返回一个int值,但此处的用法跟read()完全不一样。此处是从输入流中读取一定数量的字节,并将其存储在缓冲区数组b 中。以整数形式返回实际读取的字节数

如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值-1;否则,至少读取一个字节并将其存储在b 中。

将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于 b 的长度。设 k 为实际读取的字节数;这些字节将存储在 b[0]b[k-1] 的元素中,不影响b[k]b[b.length-1] 的元素。


此时我们有了byte数组,有了返回的字节数,就可以用String的构造方法String(byte[]bytes, intoffset, intlength): 通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的String。即可返回键盘的输入
示例如下
public class TestInput1 {
 
         public static void main(String[] args) {
 
                   try{
 
                            //提示信息
 
                            System.out.println("请输入:");
 
                            //数组缓冲
 
                            byte[] b = new byte[1024];
 
                            //读取数据
 
                            int n = System.in.read(b);
 
                            //转换为字符串
 
                            String s = new String(b,0,n);
 
                            //回显内容
 
                            System.out.println("输入内容为:" + s);
 
                   }catch(Exception e){}
 
         }
 
}

这里斟酌通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的String这句话,我亲自核实,此TestInput1.Java的编码格式为utf-8非本地默认编码格式时(我们国内的电脑默认编码GB2312),输出到控制台会是乱码,而改为GB2312时则正确输出,已证实。

还有一句...不影响b[k]b[b.length-1]的元素。我们也可以试试,将以上代码略作改动如下:

public class TestInput1 {
 
         public static void main(String[] args) {
                   try{
                            //提示信息
                            System.out.println("请输入:");
 
                            //数组缓冲
                            byte[] b = new byte[1024];
                            
                            //假设我们已知道键盘输入的是ABCD加回车是6个字符,我们将b[0]到b[9]分别提前赋值
                            for (int i = 0; i < 10; i++) {//这里b[0]-b[9]分别赋值a-j
                    			b[i] = (byte)(97+i);//a的ascii值为97
                    		}
 
                            //读取数据
 
                            int n = System.in.read(b);
                            //转换为字符串
                            //这次我们构造String为了输出byte数组的所有值,所以不再用返回的值n而用我们预知的10个
                            String s = new String(b,0,10);
                            //回显内容
                            System.out.println("输入内容为:" + s);
 
                   }catch(Exception e){}
         }
}

这次我们打印到控制台的是:
很明显原本应该输出的是abcdefghij经过读取键盘输入后,影响了n=6个字节,4个字母加回车的“\r”“\n”此句也证实了回车确实是两个字符。

3、read(byte[] b, intoff, intlen)

和上面类似但读取的长度,位置做了限定API如下:
将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数
将读取的第一个字节存储在元素 b[off] 中,下一个存储在 b[off+1] 中,依次类推。读取的字节数最多等于len。设k 为实际读取的字节数;这些字节将存储在 b[off]b[off+k-1] 的元素中,不影响b[off+k]b[off+len-1] 的元素。
同样拿上面的abcdefghij做个例子仅仅将上一个例子的int n = System.in.read(b);改为int n = System.in.read(b,3,4);则意思的,将读取的第一个字节存储在b[3]依次最多存储4个,这时我们再次运行,还是输入ABCD,刚好4个,错还有回车两个,输出的控制台是:

很明显b[3],b[4],b[5],b[6]处的字符defg被读入的4个字符覆盖,而且是只读取了4个,没有回车。
本来是要说JAVA从控制台输入数据的方法,结果扯了这么多,现在说说第二个方法:

二、java.util.Scanner

从 JDK 5.0 开始,基本类库中增加了java.util.Scanner类,使用它的Scanner(InputStream source)构造方法,可以传入系统的输入流System.in而从控制台中读取数据。当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象。如果要获取输入的内容,则只需要调用Scanner的nextLine()方法即可。
import java.util.Scanner;
public class TestSc {
	public static void main(String[] args) {
		System.out.println("请输入:");
		Scanner sc = new Scanner(System.in); 
		System.out.println(sc.nextLine());
	}
}
输出到控制台即是你键入的字符串,这里不做演示,关键说下Scanner的next(),nextLine();

1、nextLine();

API此扫描器执行当前行,并返回跳过的输入信息。 此方法返回当前行的其余部分,不包括结尾处的行分隔符。意思就是读出当前下标的一行,对它来讲每行就是他的分隔符。如上例子中的末尾
System.out.println(sc.nextLine());改为
System.out.println("hello"+sc.nextLine()+"ufo");

输入“ABCD”打印到控制台为“helloABCDufo”回车并没有被输出。比较来说此方法更简洁实用,其实是Scanner对System.in做了封装处理。


2、next();

查找并返回来自此扫描器的下一个完整标记。完整标记的前后是与分隔模式匹配的输入信息,Scanner默认使用空格作为分割符来分隔文本,但允许你指定新的分隔符如下例:

import java.util.Scanner;
public class TestSc {
	public static void main(String[] args) {
		Scanner sc = new Scanner("aa bb cc,dd,ee");
		//sc.useDelimiter(",");
		 while (sc.hasNext()) { 
             System.out.println(sc.next()); 
		 }
	}
}
将空格做分隔符输出结果为: 将注释去掉,试用逗号做分隔符输出为:

Scanner的更多方法资料可以自己去查阅学习。
继续JAVA从控制台输入数据的方法

三、java.io.Console

从 JDK 6.0 开始,基本类库中增加了java.io.Console类,用于获得与当前 Java 虚拟机关联的基于字符的控制台设备。在纯字符的控制台界面下,可以更加方便地读取数据
import java.io.Console;
public class TestSc {
	public static void main(String[] args) {
		System.out.println("请输入");
		Console cs = System.console();
		if (cs == null) { 
            throw new IllegalStateException("不能使用控制台"); 
        } 
        System.out.println(cs.readLine()); 
	}
}
值得一提的是此方法只是在cmd命令窗口可以得到Console实例顺利运行,在IDE工具下如eclipse下得不到Console实例的,cs==null无法实现输入。
API中解释:

虚拟机是否具有控制台取决于底层平台,还取决于调用虚拟机的方式。如果虚拟机从一个交互式命令行开始启动,且没有重定向标准输入和输出流,那么其控制台将存在,并且通常连接到键盘并从虚拟机启动的地方显示。如果虚拟机是自动启动的(例如,由后台作业调度程序启动),那么它通常没有控制台。

如果此虚拟机具有控制台,那么它将由此类唯一的实例(可通过调用 System.console() 方法获得)表示。如果没有可用的控制台设备,那么对该方法的调用将返回null

所以在 IDE 的环境下,重新定向了标准输入和输出流,也是就是将系统控制台上的输入输出重定向到了 IDE 的控制台中。因此,在 IDE 中不能使用这个程序。

继续正题,JAVA从控制台输入数据的方法

四、BufferedReader

其实也是用的IO流这个就不多解释了,就这样吧。
try {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	String s = br.readLine();		
} catch (IOException e) {
	e.printStackTrace();
}

readLine():读取一个文本行。


Java学习交流群: 2177712






分享到:
评论

相关推荐

    引用 Java中从命令控制台输入数据的几种常用方法.doc

    System.in 是 Java 中的一个标准输入流对象,它可以用来读取从命令控制台输入的数据。使用 System.in.read() 方法可以读取一个字节的数据,但这对于读取字符串或一组数字来说是不够的。为了读取更多的数据,可以使用...

    Java中从命令控制台输入数据的几种常用方法

    本文将详细介绍几种常用的在Java中从命令控制台输入数据的方法,包括直接使用`System.in`、使用`java.util.Scanner`类、使用`java.io.BufferedReader`类以及利用图形用户界面(GUI)组件进行输入。 ### 1. 使用`...

    在Java中从命令控制台输入数据的一些常用方法.doc

    在Java中,`System.in`是一个标准输入流对象,它允许程序从键盘或其他输入设备读取数据。然而,`System.in.read()`方法每次只能读取一个字节的数据,这在大多数情况下并不实用。因此,我们需要使用更高级的方法来...

    Java I/O 标准输入输出流System.in

    这篇博客将深入探讨Java中的标准输入流System.in,以及如何使用它进行数据的读取。 `System.in` 是一个`InputStream`类型的对象,它代表了程序的默认标准输入,通常是从键盘获取用户输入。当我们在控制台运行Java...

    Java各版本从控制台读取数据的方法

    在JDK 1.4及更早版本中,从控制台读取数据主要依赖于`System.in`获取系统输入流,然后通过`BufferedReader`与`InputStreamReader`组合来读取文本数据。这种方法虽然功能强大,但实现起来相对复杂且容易出错。例如: ...

    Java中从控制台读取输入的方法.docx

    总结来说,Java 中从控制台读取输入的方法有多种选择,可以根据具体需求和环境选择合适的方法。`BufferedReader` 更适合简单的文本输入,`Scanner` 更加灵活,支持多种数据类型的解析,而 `Console` 则适用于需要...

    java的数据输入:从控制台输入数据分享.pdf

    在Java早期版本(JDK 1.4及之前)中,程序员常通过标准输入流System.in来获取控制台输入。如示例7-22所示,首先创建一个BufferedReader对象,将System.in作为其InputStreamReader的参数。这样,可以使用readLine()...

    java的数据输入:从控制台输入数据定义.pdf

    标准输入流是在 7.6.2 中已经讨论过的,例如 7-13 和 7-14 的数据就是从控制台(键盘)输入的,方法很简单,即使用标准输入流 System.in 获得。也可以将 System.in 桥接至字符流,从字符流中读入数据。 例如 7-22 ...

    Java从控制台读入数据的几种方法

    Java从控制台读入数据的几种方法 Java从控制台读入数据是Java编程中的一种基本操作,通过控制台输入,可以实现用户交互、数据输入等功能。在Java中,有多种方法可以实现控制台输入,本文将分别介绍使用...

    java的数据输入:从控制台输入数据借鉴.pdf

    本文将深入探讨Java如何从控制台接收数据,并介绍三种主要方法:标准输入流、Scanner类以及Console类。 1. **使用标准输入流的方式** 标准输入流(System.in)是Java程序默认的数据输入源,它通常连接到键盘,允许...

    常用技巧 Java开发 从控制台读入数据

    在早期的Java版本中,如JDK1.4,开发者需要通过`System.in`获取标准输入流,并将其转换为字符输入流`InputStreamReader`,然后进一步使用`BufferedReader`来读取整行的数据。这种方法的步骤相对繁琐,需要处理可能...

    java的数据输入:从控制台输入数据.pdf

    标准输入流`System.in`是Java获取控制台输入数据的主要方式。例如,程序可以创建一个`BufferedReader`对象,通过`readLine()`方法读取用户输入的整行文本。在例7-22中,程序首先创建一个`BufferedReader`实例,将`...

    java的数据输入:从控制台输入数据[借鉴].pdf

    在Java中,标准输入流(System.in)是一个InputStream对象,用于读取来自控制台的数据。在JDK 1.4及其以前版本,这是主要的输入方式。例如,我们可以通过`BufferedReader`与`InputStreamReader`组合来读取用户的...

    Java程序设计基础:控制台输入输出.pptx

    System.in 表示Java标准输入流,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。 Scanner in =new Scanner(System.in); 从控制台获取输入 创建输入流对象in 必须先导入Scanner类 import java.util....

    Java控制台数据获取方法及比较.pdf

    在JDK 1.4 及以下版本中,从控制台获取数据的唯一方法是使用System.in类。System.in是一个InputStream对象,表示标准输入流。可以使用BufferedReader类来读取数据。示例代码如下: ```java import java.io....

    JAVA数据输入方式(命令行输入和控制台输入)

    它允许用户从控制台或其他输入设备读取数据,并支持多种数据格式。 ##### 直接使用`System.in.read()`方法 这种方法较为直接,但只适用于简单的字符读取。 **示例代码:** ```java public class ReadChar { ...

    Java控制台数据获取方法及比较

    在JDK 1.4及更早的版本中,从控制台读取数据主要依赖于`System.in`类,它提供了一个标准的输入流。通过桥接到字符流,如`BufferedReader`,可以从控制台读取整行数据。虽然这种方法能够满足基本的输入需求,但其代码...

    java中读取数据的几种方法.doc

    使用`Scanner(InputStream source)`构造函数传入`System.in`,即可轻松地从控制台读取数据。例如: ```java import java.util.Scanner; public class Test3 { public static void main(String[] args) { Scanner...

    SystemIn:用于从 Java 控制台读取的 Java API (System.in)

    Java API中的`System.in`是Java标准库提供的一种机制,允许程序员从控制台接收用户输入。这个特性在很多场合都非常有用,比如简单的命令行应用程序、测试或者教学示例。在这个`SystemIn`项目中,开发者可能创建了一...

    Java万年历(从控制台输入)

    - `Scanner`类:Java提供的标准输入流工具,可以读取用户的键盘输入。在本例中,我们需要使用`Scanner.nextInt()`来获取用户输入的年份和月份。 通过完成这个项目,新手不仅能熟悉Java的基本语法,还能掌握日期...

Global site tag (gtag.js) - Google Analytics