Java IO操作——System类对IO的支持(System.out、System.err、System.in)

来源:互联网 发布:windows 10系统备份 编辑:程序博客网 时间:2024/05/06 04:57

学习目标

 掌握System对IO的三种支持:
    System.out
    System.err
    System.in
掌握System.out及System.err的区别
掌握输入、输出重定向

System类的常量
System表示系统类,实际上在JAVA中也对IO给予了一定的支持
1、public static final PrintStream out  常量  对应系统标准输出,一般是显示器
2、public static final PrintStream err   常量 错误信息输出
3、public static final InputStream in    常量 对应标准输出,一般是键盘
使用static final关键字声明的变量是全局常量,只要是常量,则所有的单词字母必须全部大写,按照现在的标准:System.OUT —> System.out

System.out

使用System.out输出的时候就是将输出的位置定义在了显示器之中。
FileOutputStream是定位在文件里,而System.out是定位在屏幕上输出
 PrintStream就是OutputStream的子类
import java.io.OutputStream ;import java.io.IOException ;public class SystemDemo01{public static void main(String args[]){OutputStream out = System.out ;// 此时的输出流是向屏幕上输出try{out.write("hello world!!!".getBytes()) ;// 向屏幕上输出}catch(IOException e){e.printStackTrace() ;// 打印异常}try{out.close() ;// 关闭输出流}catch(IOException e){e.printStackTrace() ;}}};


很明显就是对象多态性的体现,根据实现的子类不同,完成的功能也不相同。

System.err

System.err 表示的是错误的标准输出,如果程序中出现了错误的话,则直接使用System.err进行输出即可。程序如下:
public class SystemDemo02{public static void main(String args[]){String str = "hello" ;// 声明一个非数字的字符串try{System.out.println(Integer.parseInt(str)) ;// 转型}catch(Exception e){System.err.println(e) ;}}};


使用System.out输出错误 如下:
public class SystemDemo03{public static void main(String args[]){String str = "hello" ;// 声明一个非数字的字符串try{System.out.println(Integer.parseInt(str)) ;// 转型}catch(Exception e){System.out.println(e) ;}}};


System.out 和System.err 的区别:
System.out和System.err都是PrintStream的实例化对象,而且通过代码可以发现,两者都可以输出错误信息,但是一般来讲System.out是将信息显示给用户看,是正常的信息显示,而System.err的正好相反是不希望用户看到的,会直接在后台打印,是专门显示错误的。
一般来讲,如果要输出错误信息的时候最好不要使用System.out而是直接使用System.err 这一点只能从其概念上划分。

以上的代码也可以使用System.out输出,只能从概念上划分。
切记:System.out是希望用户看到的,而System.err是不希望用户看到的。

System.in

System.in实际上是一个键盘的输入流,其本身是InputStream类型的对象。那么,此时就可以利用此方式完成从键盘读取数据的功能。
InputStream对应的是输入流,输入流的话肯定是从指定位置读取的,之前使用的是FileInputStream,是从文件中读取的。
import java.io.InputStream ;public class SystemDemo04{public static void main(String args[]) throws Exception {// 所有异常抛出InputStream input = System.in ;// 从键盘接收数据byte b[] = new byte[1024] ;// 开辟空间,接收数据System.out.print("请输入内容:") ;// 提示信息int len = input.read(b) ;// 接收数据System.out.println("输入的内容为:" + new String(b,0,len)) ;input.close() ;// 关闭输入流}};

所有的数据输入进去了,但是以上的操作存在如下问题:
问题一:指定了输入数据的长度,如果现在输入的数据超过了长度范围,只能输入部分的数据。
问题二:如果byte数组是奇数的话,则还可能出现中文乱码的情况,因为一个字符是两个字节。示例如下:
import java.io.InputStream ;public class SystemDemo04{public static void main(String args[]) throws Exception {// 所有异常抛出InputStream input = System.in ;// 从键盘接收数据byte b[] = new byte[3] ;// 开辟空间,接收数据System.out.print("请输入内容:") ;// 提示信息int len = input.read(b) ;// 接收数据System.out.println("输入的内容为:" + new String(b,0,len)) ;input.close() ;// 关闭输入流}};


可以发现,开辟了三个字节的空间,但是两个字符需要四个字节的数组长度,所以剩下的一个字节就等于读到了半个字符,所以会出现乱码。
那么如果此时不指定byte数组的长度呢?是否可以完成输入的要求?
这样的话只能通过标志位的方式进行完成。实例如下:
import java.io.InputStream ;public class SystemDemo05{public static void main(String args[]) throws Exception {// 所有异常抛出InputStream input = System.in ;// 从键盘接收数据StringBuffer buf = new StringBuffer() ;// 使用StringBuffer接收数据System.out.print("请输入内容:") ;// 提示信息int temp = 0 ;// 接收内容while((temp=input.read())!=-1){char c = (char) temp ;// 将数据变为字符if(c=='\n'){// 退出循环,输入回车表示输入完成break ;}buf.append(c) ;// 保存内容}System.out.println("输入的内容为:" + buf) ;input.close() ;// 关闭输入流}};


但是输入中文就会乱码。

这是因为每读取一个字节就将其转为字符,字母和数字都是占1个字节 可以正常显示。但是如果是中文的话,就相当于每读取到一个字节就是半个字符就进行转化,所以导致乱码的错误。
最好的输出方式:
最好的输出方式是将全部输入的数据暂时存放在一块内存之上,之后一次性的从内存中读取数据,这样所有数据就整体只读了一次,则不会造成乱码,而且也不会受到长度的限制。

如果要想实现以上的功能,则只能通过IO中的下一个类 BufferedReader类完成。

输入输出重定向

从之前的操作中知道System.out、System.err、System.in三个常量的作用,但是通过System类也可以改变System.in的输入流来源,以及System.out和System.err两个输出流的输出位置。
1、public static void setOut(PrintStream out)普通方法 重定向“标准”输出流
2、public static void setErr(PrintStream err) 普通方法 重定向 “标准”错误输出流
3、public static void setIn(InputStream in)     普通方法 重定向“标准” 输入流

为System.out输出重定向

使用setOut()方法完成
import java.io.File ;import java.io.FileOutputStream ;import java.io.PrintStream ;public class SystemDemo06{public static void main(String args[]) throws Exception {System.setOut(new PrintStream(new FileOutputStream("d:" + File.separator + "red.txt"))) ;// System.out输出重定向System.out.print("刘勋") ;// 输出时,不再向屏幕上输出System.out.println(",黄淮学院") ;}};

此时将输出的位置重定向,所以所有的内容都向指定的文件中打印。
实际上通过此操作就可以完成错误的重定向。
System.out是希望用户看得到信息,一旦有错误,最好保存起来。
import java.io.File ;import java.io.FileOutputStream ;import java.io.PrintStream ;public class SystemDemo07{public static void main(String args[]){String str = "hello" ;// 声明一个非数字的字符串try{System.out.println(Integer.parseInt(str)) ;// 转型}catch(Exception e){try{System.setOut(new PrintStream(new FileOutputStream("d:"+ File.separator + "err.log"))) ;// 输出重定向}catch(Exception e1){}System.out.println(e) ;}}};

为System.err重定向

利用System.err向屏幕上输出信息,此时,为了方便起见,使用内存操作流。
import java.io.ByteArrayOutputStream ;import java.io.PrintStream ;public class SystemDemo08{public static void main(String args[]) throws Exception{// 所有异常抛出ByteArrayOutputStream bos = null ;// 声明内存输出流bos = new ByteArrayOutputStream() ;// 实例化System.setErr(new PrintStream(bos)) ;// 输出重定向System.err.print("刘勋") ;// 错误输出,不再向屏幕上输出System.err.println("是好人") ;// 向内存中输出System.out.println(bos) ;// 输出内存中的数据}};

一般不建议去修改System.err的输出位置,因为这样的信息都不太希望用户可以看见。

为System.in重定向

默认情况下System.in是指屏幕的建瓯按输入,也可以通过setIn()方法,将其输入流的位置改变,例如,现在从文件中读取。
有如下文件:demo.txt

使用System.in将数据读取进来
import java.io.FileInputStream ;import java.io.InputStream ;import java.io.File ;public class SystemDemo09{public static void main(String args[]) throws Exception{// 所有异常抛出System.setIn(new FileInputStream("d:"+ File.separator + "demo.txt")) ;// 设置输入重定向InputStream input = System.in ;// 从文件中接收数据byte b[] = new byte[1024];// 开辟空间,接收数据int len = input.read(b) ;//接收System.out.println("输入的内容为:" + new String(b,0,len)) ;input.close() ;// 关闭输入流}};

总结:

三个常量的使用:
  •  System.out是希望用户可以看见的信息。用IDE(Eclipse)的话错误信息使用黑颜色显示的。
  • System.err 是不希望用户可以看见的信息。则在IDE中将以红色的文字显示错误信息。
  • System.in  对应键盘输入
  • 以上三个常量的输入、输出都可以重定向,但是一般建议只修改setOut的重定向。
  • System.in读取的时候会出现中文乱码的问题,则可以通过BufferedReader完成读取功能。
0 0