System 类对IO的支持(系统输入)
一、系统输入:in
System.in对应的类型是InputStream,而这种的输入流指的是由用户通过键盘进行输入(用户输入),Java本身并没有直接的用户输入处理,如果要实现这种输入处理必须用java.io的模式来完成。
范例:利用InputStream实现数据的输入
InputStream input= System.inl;这是为父类实例化,然后,byte data [ ]=new byte[ 1024];开辟一个空间,完成之后 int temp= input.read(data);这是数据读取到字节数组之中,
而在这里给一个提示:System.out.print(“请输入信息:”);之后,System.out.println(“【ECHO】输入内容为:“+new String(data,0,temp));
执行出现:
请输入信息:
现在发现当用户输入数据的时候程序需要暂停执行,也就是说程序要进行到阻塞状态。指导用户输入完成(按下回车),那么才能够继续向下执行。
在执行后输入于博是好学生,p!按下回车出现:
【ECHO】输入内容为:
于博是个好学生,p!这个时候信息正常输入了,
但是以上的程序本身有一个致命的问题,核心点在于:
要开辟的字节数组的长度是固定的,如果输入的内容超过了该长度。
比如开辟字节修改为10个:
byte data [ ]=new byte[ 10],现在执行输入于博是个好学生,p!
按下回车出现【ECHO】输入内容为:
于博是个好 五个中文字,两个字节一个字符(好可以拆分成女、子)所以超过长度那么只能够接收部分的数据。
这是由于一次读取不完所造成的问题,这个时候最好的做法是引入内存操作流来进行控制,这些数据暂时保存在内存流里面,而后通过内存流一次性取出。
范例:改进输入设计
这里用内存流的是方法是开辟一个ByteArrayOutputStream bos=new ByteArrayOutputStream();
之后需要写循环:
while(temp=input.read(data))然后把这个值不等于-1:while((temp=input.read(data))!=-1)。
不等于-1就会有数据,bos.write(data,0,temp);数据保存在内存输出流完成之后,内容就需要通过内存输出流取得
所以跟上bos.toByteArray(),
执行出现:请输入信息:
写入今天天气不错,下雨了,天晴了,没事跑跑!按下回车会发现没有反应,因为这里换行不是-1。
所以需要用户自己处理换行的问题,因为换行不属于文件结束,所以内容不是-1。
现在虽然实现了键盘输入数据的功能,但整体的实现逻辑有些过于混乱了,也就是说java本身提供的System.in该操作并不好用。
以上的操作是充分的考虑到了中文问题,所以处理起来很麻烦,而如果不考虑中文,只考虑英文问题,那么代码就可以按照如下的简化方式来实现。
现在不考虑中文,一个字节一个字节接收,而后所有的接收内容都在StringBuffer buf = new StringBuffer();
然后对每一个内容都进行接收:
buf.append((char)temp)这里把字节变为字符保存在
StringBuffer里。
而后 System.out.println(" 【ECHO]输入内容为: " +new String(bos.toByteArray()));这个地方直接改成
System.out.println(" 【ECHO]输入内容为: " +buf);这个地方不再需要内存流。
然后判断下if(temp==’\n’){break;}必须考虑结束条件,
执行出现:
请输入信息:输入helloworld
回车出现:【ECHO】
输入内容为:helloworld 现在实现了无长度输入,但这个代码在中文上不能用,
通过以上的比较可以感受到System.in的支持度原本不高,对于英文的操作还勉强可以使用,而如果是中文的操作,就必须结合内存流来玩成,所以复杂度很高,如果开发都这么写,就会非常麻烦。
二、总结
如果要想在IO中进行中文的处理,那么最好的做法是将所有输入的数据保存在一起再处理,这样才可以保证不出现乱码。而且需要用字符输入或字符输出流。
所以System.in只是Java中最基础的输入支持,本身功能有限。