Java编程--IO流(System类对IO的支持)
System类中定义有三个操作的常量:
1. 两个常量:out和error所表示的都是PrintStream类的对象。
2. 区别:out输出的是希望用户可以看见的内容,err是希望输出用户不能看见的内容。
3. 这两种输出在实际开发中都没有。
一.系统输出:out
public class Test1 {
public static void main(String[] args) {
String str = "hello 123";
try {
System.out.println(Integer.parseInt(str));
} catch (Exception e) {
System.err.println(e);
System.out.println(e);
}
}
}
运行结果:
【附】System.out和System.err区别图解:
System.out属于PrintStream类的实例化对象,而PrintStream又属于OutputStream类的子类,故可以直接用System.out为OutputStream实例化,则这个时候的OutputStream输出的位置将变为我们的屏幕。
【范例】使用System.out为OutputStream实例化。
import java.io.IOException;
import java.io.OutputStream;
public class Test1 {
public static void main(String[] args) throws IOException {
OutputStream out = System.out; // 子类实例向上转型
out.write("Hello world".getBytes());
}
}
运行结果:
抽象类不同的子类针对同一方法有不同的实现,而用户调用的核心参考就是OutputStream。
二.系统输入:in
【范例】使用InputStream实现数据的读取。
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) throws Exception {
InputStream in = System.in;
byte[] bys = new byte[1024 * 1];
System.out.println("请输入内容:");
int len = in.read(bys);
System.out.println("您输入的内容是:");
System.out.println(new String(bys, 0, len));
in.close();
}
}
运行结果:
以上程序有个致命的问题,当输入的内容超过了开辟的数组的长度。这个时候由于我们一次读取不完产生的问题。
最好的做法是引入内存操作流来解决问题。也就是说这些数据先保存在内存流里,而后通过内存流一次性取出。
【案例】引入内存操作流。
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) throws Exception {
InputStream in = System.in; // 为父类实例化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
System.out.println("请输入内容:");
byte[] bys = new byte[10]; // 开辟一个空间
int tmp = 0;
while ((tmp = in.read(bys)) != -1) { // 数据读取到字节数组之中
bos.write(bys, 0, tmp); // 保存在内存输出流
}
System.out.println("您输入的内容是:");
System.out.println(new String(bos.toByteArray()));
in.close();
}
}
运行结果:输入数据发现并没有输出。
原因:换行不属于文件结束,所以内容不是-1。
【案例】修改以上的程序。
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) throws Exception {
InputStream in = System.in; // 为父类实例化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
System.out.println("请输入内容:");
byte[] bys = new byte[10]; // 开辟一个空间
int tmp = 0;
while ((tmp = in.read(bys)) != -1) { // 数据读取到字节数组之中
bos.write(bys, 0, tmp); // 保存在内存输出流
if (tmp < bys.length) {
break;
}
}
System.out.println("您输入的内容是:");
System.out.println(new String(bos.toByteArray()));
in.close();
}
}
运行结果:
发现:虽然改进的程序实现了键盘录入数据的功能,但是整体的逻辑过于混乱了,Java本身提供的System.in并不好用。
以上的操作是充分考虑到了中文问题,处理起来很麻烦。假设你现在不考虑中文,这个代码就可以考虑如下简化方式实现:
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) throws Exception {
InputStream in = System.in; // 为父类实例化
StringBuffer buf = new StringBuffer();
System.out.println("请输入内容:");
int tmp = 0;
while ((tmp = in.read()) != -1) {
if (tmp == '\n') { // 考虑结束条件
break;
}
buf.append((char) tmp); // 把字节变为字符保存在StringBuffer中
}
System.out.println("您输入的内容是:");
System.out.println(buf);
in.close();
}
}
运行结果:
以上代码实现了对英文字符的操作,但是中文下不能使用。
总结:
若想在IO中进行中文的处理,最好的做法是将所有的数据保存在一起再处理,这样才可以保证不出现乱码。