1. 程式人生 > >Java IO操作——System類對IO的支援(System.out、System.err、System.in)

Java IO操作——System類對IO的支援(System.out、System.err、System.in)

學習目標

 掌握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完成讀取功能。