System类对IO的支持
System表示系统类,此类在之前讲解Java常用类库时己经介绍过,实际上在Java中System类也对IO给 予 了 一 定 的 支 持 , 在 S y s t e m 类 中 定 义 了 如 表 1 2 - 1 1 所 示的3个常量,这3个常量在IO操作中有着非常大的作用。
12.8.1 System.out
System.out
是 PrintStream
的对象,在 PrintStream
中定义了一系列的 print()
和 println()
方法,所以前面使用的“System.out.print()
”或“System.out.println()
”语句调用的实际上就是PrintStream
类的方法。
既然此对象表示的是向显示器上输出,而PrintStream
又是OutputStream
的子类。所以,可以直接利用此对象向屏幕上输出信息.
【例12.37】使用Outputstream向屏幕上输出
package jiaqi;
import java.io.OutputStream;
public class demo406_1
{
public static void main(String[] args)throws Exception
{
OutputStream out = System.out;
out.write("hello!!".getBytes());
out.close();
}
}
以上的信息是直接使用Outputstream
向屏幕上进行输出的,也就是说,OutputStream
的哪个子类为其实例化,就具备了向哪里输出的能力如果是使用FileOutputStream
则表示向文件输出,如果使用了System.out
则表示向显示器输出,这里完全显示出了 Java的多态性的好处,即根据子类的不同完成的功能也不同。
12.8.2 System.err
System.err表示的是错误信息输出,如果程序出现错误,则可以直接使用System.err进行打印,代码如下所示。
【例12.3】 错误信息输出
package jiaqi;
public class demo406_2 {
public static void main(String[] args)
{
String str = "hello";
try {
System.out.println(Integer.parseInt(str));
} catch (Exception e)
{
System.err.println(e);
}
}
}
程序执行结果:
java.Ianq.NumberFormatException: For input string: ”hello"
上面的程序要把字符串“hello”变为整型数据,这样肯定会引发“NumberFormatException”异常信息,所以,当捕捉到异常之后,直接在catch中使用System.err进行信息的输出。
System.out
和System.err
都是PrintStream
的实例化对象,而且通过实例代码可以发现,两者都可以输出错误信息,但是System.out
一般是将信息显示给用户看,是正常的信息显示,而System.err
的信息正好相反,是不希望用户看到的,会直接在后台打印,是专门显示错误的,
12.8.3 System.in
System.in实际上是一个键盘的输入流,其本身是InputStream类型的对象。那么此时就可以利用此方法完成从键盘读取数据的功能。
【例12.39】从键盘上读取数据
package jiaqi;
import java.io.InputStream;
public class demo407_1
{
public static void main(String[] args) throws Exception
{
InputStream input = System.in;
byte b[] = new byte[1024];
System.out.println("请输入:");
int len = input.read(b);
System.out.println("输入内容是:" + new String(b,0,len));
}
}
可 以 发 现 , 上 面 的 代 码 己 经 实 现 了 从 键 盘 中 输 入 数 据 的 功 能 , 但 这 个 程 序 是 否 可 以 正 常 使用呢?
实际上本程序有两个极大的问题
:
(1) 指定了输入数据的长度,如果现在输入的数据超出了其长度范围,则只能输入部分的数据。
(2) 如果指定的byte数组长度是奇数的话,则还有可能出现中文乱码;
既 然 担 心 指 定 的 数 组 长 度 不 够 , 那 么 , 如 果 此
时 不 指 定 b y t e 数 组 长 度 呢 ? 是 否 可 以 完 成 输 入 的 要 求 呢 ? 下 面 通 过 一 段 代 码 来 观 察 不 指 定 b y t e 数 组 长 度接收数据的情况。
【例12.40】不指定大小
package jiaqi;
import java.io.InputStream;
public class demo408_1
{
public static void main(String[] args) throws Exception
{
InputStream input = System.in;
StringBuffer buf = new StringBuffer();
System.out.println("输入:");
int temp = 0;
while((temp = input.read()) != -1)
{
char c = (char)temp;
buf.append(c);
if(c == '\n')break;//遇到回车,退出循环
}
System.out.println("内容:" + buf);
input.close();
}
}
上 面 的 程 序 如 果 输 入 的 是 英 文 字 母 , 没 有 任 何 的 问 题 ,
而 如 果 输 入 的 是 中 文 , 则 同 样 会 产 生 乱 码 ,
这 是 因 为 数 据 是 以 一 个 一 个 字 节 的 方 式 读 进 来 的 , 一 个 中 国 字 是 分 两 次 读 取 的 , 所 以造成了乱码问题。
指 定 大 小 会 出 现 空 间 限 制 , 不 指 定 大 小 输 入 中 文 则 会 产 生 乱 码 , 那 么 怎 样 的 输 入 数 据 形 式才是最合理的呢?
最好的输入方式是将全部输入的数据暂时放到一块内存中,然后一次性从内存中读取出数据,这样所有数据只读一次,则不会造成乱码,而且也不会受长度的限制,如果要完成这样的操作则可以使用12.9节中的BufferedReader
类完成。
12.8.4输入/输出重定向
【例12.41】为System.out输出重定向
package jiaqi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class demo409_1
{
public static void main(String[] args) throws Exception
{
String path = "d:" + File.separator + "test.txt";
File f= new File(path);
OutputStream os = new FileOutputStream(f);
PrintStream ps = new PrintStream(os);
System.setOut(ps);
ps.println("ccccccccccccc");
ps.print("yyyyyyy");
}
}
结果:
【例12.42】为用户保存错误信息
package jiaqi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class demo410_1
{
public static void main(String[] args)throws Exception
{
try
{
int a=10/0;
}
catch (Exception e)
{
try
{
String path = "d:" + File.separator + "err.log";
File f = new File(path);
OutputStream os = new FileOutputStream(f);
PrintStream ps = new PrintStream(os);
System.setOut(ps);
}
catch (Exception e2)
{
e.printStackTrace();
}
System.out.println(e);
}
}
}
因为程序中使用了 setOut()方法将其输出重定向到了d:\err.log文件,所以所有的错误信息将直接在err.log文件中保存。
【例12.43】为System.err输出重定向
package jiaqi;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class demo410_2 {
public static void main(String[] args)throws Exception
{
// TODO 自动生成的方法存根
//重定向Err
OutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
System.setErr(ps);
//错误输入到内存里面了
System.err.println("err_err");
System.err.println("错误!");
//输出Err
System.out.println(os);
}
}
不要修改System.err的输出重定向。
虽然在System类中提供了 setErr()这个错误输出的重定向方法,但是一般情况下,读者不要去使用这个方法修改System.err的重定向,因为从概念上讲System.err的错误信息是不希望用户看到的
【例12.44】设置System.in的输入重定向
package jiaqi;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class demo411_1 {
public static void main(String[] args) throws Exception
{
// String path = "d:" + File.separator + "test.txt";
// File f = new File(path);
// InputStream input = new FileInputStream(f);
// System.setIn(input);
System.setIn(new FileInputStream(new File("d:" + File.separator + "test.txt")));
byte b[] = new byte[1024];
InputStream is = System.in;
int len = is.read(b);
System.out.println("len:"+len);
System.out.println(new String(b,0,len));
is.close();
}
}
上面代码修改了 System.in的输入位置,将其输入重定向到从文件中读取,所以读取的时候会将文件中的内容读取进来