Java IO操作——System類對IO的支援(System.out、System.err、System.in)
阿新 • • 發佈:2019-02-13
學習目標
掌握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 常量 對應標準輸出,一般是鍵盤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完成讀取功能。