Java IO操作——System类对IO的支持(System.out、System.err、System.in)
2016-07-21 20:45
791 查看
学习目标
掌握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完成读取功能。
相关文章推荐
- LeetCode-JAVA-Binary Search Tree Iterator1.
- java 关于对“是否可以从一个static方法内部发出对非static方法的调用”问题的理解
- [6]访问控制权限 0X01(隐藏具体实现)
- 顺序表java实现
- SpringMVC + mybatis结合
- Java实现满天星
- Java之详解坦克大战游戏(六)
- Spring主要核心
- JAVA CAS原理深度分析
- java 从String中匹配数字,并提取数字
- java设计模式之适配器模式
- 从入门到精通:让人又爱又恨的注解(一)
- 两个大的整数的运算(java)
- 告诉你一个java对象占用的内存大小的方法
- spring配置文件中classpath路径解析
- spring、spring mvc以及IOC的阅读
- myeclipse search查找打开第二个文件时第一个文件被关闭关闭
- 链队列java实现
- Java 自带的加密类MessageDigest类(加密MD5和SHA)
- 使用 Arrays 类操作 Java 中的数组