一 System类
System类中有三个常量在IO操作中有很大的作用
public static final PrintStream out/err/in
print和println方法是在PrintStream中定义的方法。out err in都是PrintStream的类属性。所以可直接调用类方法。
PrintStream是OutputStream的子类。
(一)System.out
System.out向屏幕输出:
利用OutputStream向屏幕输出
import java.io.IOException;
import java.io.OutputStream;
class Demo{
public static void main(String[] args){
OutputStream out = System.out;
try{
//because the target of write() is byte[] type
out.write("Hello!".getBytes());
}catch(IOException e){
e.printStackTrace();
}
try{
out.close();
}catch(IOException e){
e.printStackTrace();
}
}//main
}//Demo
output:Hello!
以上例子使用System.out对OutputStream进行实例化,并用OutputStream的实例化对象对屏幕进行输出。
也就是说,OutputStream被哪个子类实例化,就具备了向该位置输出的能力。
如果被FileOutputStream子类实例化,就具备了向文件输出的能力。
被System.out实例化,就具备了向屏幕输出的能力。
(二)System.err
如英文所示,输出错误信息。
System.out是显示信息给用户看。System.err是不希望用户看到的信息,直接在后台打印,专门显示错误的。
希望看见->out->重定向->输出位置
不希望看见->err->后台输出->用户无法看见
(三)System.in
键盘输入流,本身是InputStream类的对象。
import java.io.InputStream;
class Demo{
public static void main(String[] args) throws Exception{
InputStream in = System.in;
byte[] b = new byte[1024];
System.out.println("Input:");
int length = in.read(b);
System.out.println("The string you inputed is :"+new String(b,0,length));
in.close();
}//main
}//Demo
Input:
Hello World!
The string you inputed is :Hello World!
如果通过FileInputStream实例化InputStream,就从文件往程序进行输入。
通过键盘对象System.in实例化了输入流,就从键盘往程序进行输入。
不过上述例子限定了长度。而且byte如果是基数长度,对于部分编码(如GBK)可能会造成乱码。
不定长输入:
import java.io.InputStream;
public class Demo{
public static void main(String[] args) throws Exception{
InputStream in = System.in;
StringBuffer buf = new StringBuffer();
System.out.println("Input:");
int temp = 0;
while((temp = in.read())!=-1){
char cT = (char)temp;
if(cT == '\n'){
break;
}
buf.append(cT);
}//while
System.out.println("Content:"+buf);
in.close();
}//main
}//Demo
Input:
Hello Wrold
Content:Hello Wrold
一样可以实现功能,而且不限长度。不过如果输入中文等多字节字符,会出现乱码
最好的输入方式是将全部输入的数据暂时存放到一块内存中,然后一次性从内存中读取数据。
让所有数据只读一次,而且不会造成乱码,也不会造成长度的限制。(参考BufferedReader)
(四)输入输出重定向
通过System类也可以改变(System.int的输入流来源)以及(System.out和System.err的输出流的输出位置)
方法:public static void setOut(PrintStream out)
public static void setErr(PrintStream err)
public static void setIn(InputStream in)
setOut setErr setIn 对应的参数都是PrintStream的实例化对象
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
public class Demo{
public static void main(String[] args) throws Exception{
final String FSP = File.separator;
OutputStream outSet = new FileOutputStream(new File("C:"+FSP+"JavaStudy"+
FSP+"JavaIO"+FSP+"test01.txt"));
PrintStream pst = new PrintStream(outSet);
System.setOut(pst);
System.out.println("Hello World!2");
pst.close();
outSet.close();
}//main
}//Demo
output:
在test01文档中输出:
Hello World!2
经jdk文档查阅File.separator为static string类型,通过赋值可以用短一点的变量代替。
上例中可以看出,只要经过setOut对OutputStream进行重定向,就算打印System.out.println()也会输出到文本中。
同理也可以把错误信息记录在文本中。
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class Demo{
public static void main(String[] args) throws Exception{
ByteArrayOutputStream bao = new ByteArrayOutputStream();
PrintStream pts = new PrintStream(bao);
System.setErr(pts);//setErr can only receive PrintStream type
System.err.println("Hello World!");
System.out.println(bao+"K");
}//main
}//Demo
output:
Hello World!
K
上例中,将err定位到内存输出流,再用PirntStream对ByteArrayOutputStream进行装饰,通过setErr重定向到PrintStream对象中。
再通过out将内存中的打印流输出到屏幕。
当然也可以对System.in进行重定向。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Demo{
public static final String FSP = File.separator;
public static void main(String[] args) throws Exception{
System.setIn(new FileInputStream(new File(("C:"+FSP+"JavaStudy"
+FSP+"JavaIO"+FSP+"test05.txt"))));
InputStream is = System.in;
byte[] b = new byte[1024];
int length = is.read(b);
System.out.println("Content:"+new String(b,0,length));
is.close();
}//main
}//Demo
output:
Content:Hello World!
2+2=4
Name:FangXy,Age:24,Score:65.000000,Gender:M
本例将System.in转向了文本test05.txt,所以不从键盘输入,而从文本输入。
static常量不能定义在main方法内,毕竟main方法也是static方法。
而且,有没有new File貌似都能正常输出,这是怎么回事?