1.系统输入
系统输出一共有两个常量:out、err,并且这两个常量表示的都是PrintStream类的对象。
- out输出的是希望用户能看到的内容
- err输出的是不希望用户看到的内容
System.err只是作为一个保留的属性而存在,现在几乎用不到。唯一可能用到的就是System.out。
eg:
public class Test {
public static void main(String[] args) throws Exception {
try {
Integer.parseInt("abc") ;
} catch (Exception e) {
System.out.println(e) ;
System.err.println(e) ;
}
}
}
由于System.out是PrintStream的实例化对象,而PrintStream又是OutputStream的子类,所以可以直接使用 System.out直接为OutputStream实例化,这个时候的OutputStream输出的位置将变为屏幕。
eg:使用System.out为OutputStream实例化
import java.io.OutputStream;
public class Test {
public static void main(String[] args) throws Exception {
OutputStream out = System.out ;
out.write("大家好".getBytes());
}
}
抽象类不同的子类针对于同一方法有不同的实现,而用户调用的时候核心参考的是抽象类。
2.系统输入
System.in对应的类型是InputStream,而这种输入流指的是由用户通过键盘进行输入(用户输入)。java本身并没有 直接的用户输入处理,如果要想实现这种操作,必须使用java.io的模式来完成。
eg:利用InputStream实现数据输入
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws Exception {
InputStream in = System.in ;
byte[] data = new byte[1024] ;
System.out.print("请输入信息:");
int temp = in.read(data) ;
// 数据读取到字节数组中
System.out.println("输出内容为 :" +new String(data,0,temp)) ;
}
}
现在发现当用户输入数据的时候程序需要暂停执行,也就是程序进入了阻塞状态。直到用户输入完成(按下回车), 程序才能继续向下执行。
以上的程序本身有一个致命的问题,核心点在于:
开辟的字节数组长度固定,如果现在输入的长度超过了字节数组长 度,那么只能够接收部分数据。
这个时候是由于一次读取不完所造成的问题,所以此时好的做法是引入内存操作流来进行控制,这些数据先保存在内存流中而后一次取出。
eg:引入内存流。
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws Exception {
InputStream in = System.in ;
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
byte[] data = new byte[10] ;
System.out.print("请输入信息:");
int temp = 0 ;
while((temp = in.read(data)) != -1) {
bos.write(data,0,temp) ;
// 保存数据到内存输出流中
// 这里面需要用户判断是否输入结束
if (temp < data.length) {
break ;
}
}
in.close() ;
bos.close() ;
System.out.println("输出内容为 :" +new String(bos.toByteArray())) ;
}
}
如果要想在IO中进行中文的处理,最好的做法是将所有输入的数据保存在一起再处理,这样才可以保证不出现乱码。