文件輸入輸出流
文件輸入輸出流 FileInputStream 和 FileOutputStream 負責完成對本地磁盤文件的順序輸入輸出操作。
【例】通過程序創建一個文件,從鍵盤輸入字符,當遇到字符“#”時結束,在屏幕上顯示該文件的所有內容
import java.io.*;class ep10_5{ public static void main(String args[]){ char ch; int data; try{ FileInputStream a=new FileInputStream(FileDescriptor.in); //創建文件輸入流對象 FileOutputStream b=new FileOutputStream("ep10_5"); //創建文件輸出流對象 System.out.println("請輸入字符,以#號結束:"); while((ch=(char)a.read())!='#'){ b.write(ch); } a.close(); b.close(); System.out.println(); FileInputStream c=new FileInputStream("ep10_5"); FileOutputStream d=new FileOutputStream(FileDescriptor.out); while(c.available()>0){ data=c.read(); d.write(data); } c.close();d.close(); } catch(FileNotFoundException e){ System.out.println("找不到該文件!"); } catch(IOException e){} }}
FileDescriptor 是 java.io 中的一個類,該類不能實例化,其中包含三個靜態成員:in、out 和err,分別對應于標準輸入流、標準輸出流和標準錯誤流,利用它們可以在標準輸入輸出流上建立文件輸入輸出流,實現鍵盤輸入或屏幕輸出操作。
【例】實現對二進制圖形文件(.gif)的備份
import java.io.*;class ep10_6{ public static void main(String args[]) throws IOException{ FileInputStream a=new FileInputStream("ep10_6.gif"); FileOutputStream b=new FileOutputStream("ep10_6_a.gif"); System.out.println("文件的大小為:"+a.available()); byte c[]=new byte[a.available()]; a.read(c); //將圖形文件讀入數組 b.write(c); //將數組中的數據寫入到新文件中 System.out.println("文件已經被更名復制!"); a.close(); b.close(); }}
過濾流
FilterInputStream 和 FileOutputStream 是 InputStream 和 OutputStream 的直接子類,分別實現了在數據的讀、寫操作的同時能對所傳輸的數據做指定類型或格式的轉換,即可實現對二進制字節數據的理解和編碼轉換。
常用的兩個過濾流是數據輸入流 DataInputStream 和數據輸出流 DataOutputStream。其構造方法為:
DataInputStream(InputStream in); //創建新輸入流,從指定的輸入流 in 讀數據 DataOutputStream(OutputStream out); //創建新輸出流,向指定的輸出流 out 寫數據
由于 DataInputStream 和 DataOutputStream 分別實現了 DataInput 和 DataOutput 兩個接口(這兩個接口規定了基本類型數據的輸入輸出方法)中定義的獨立于具體機器的帶格式的讀寫操作,從而實現了對不同類型數據的讀寫。由構造方法可以看出,輸入輸出流分別作為數據輸入輸出流的構造方法參數,即作為過濾流必須與相應的數據流相連。
DataInputStream 和 DataOutputStream 類提供了很多個針對不同類型數據的讀寫方法,具體內容讀者可參看 Java 的幫助文檔。
【例】將三個 int 型數字 100,0,-100 寫入數據文件 ep10_6.dat 中。
import java.io.*;class ep10_7{ public static void main(String args[]){ String fileName="ep10_7.dat"; int value1=100,value2=0,value3=-100; try{ //將 DataOutputStream 與 FileOutputStream 連接輸出不同類型的數據 DataOutputStream a=new DataOutputStream(new FileOutputStream(fileName)); a.writeInt(value1); a.writeInt(value2); a.writeInt(value3); a.close(); } catch(IOException i){ System.out.println("出現錯誤!"+fileName); } }}
運行后在程序目錄中生成數據文件 ep10_7.dat,用文本編輯器打開后發現內容為二進制的:
00 00 00 64 00 00 00 00 FF FF FF 9C。
【例】讀取數據文件 ep10_6.dat 中的三個 int 型數字,求和并顯示。
import java.io.*;class ep10_8{ public static void main(String args[]){ String fileName="D://myjava/ep10_7.dat"; int sum=0; try{ DataInputStream a=new DataInputStream(new BufferedInputStream(new FileInputStream(fileName))); sum+=a.readInt(); sum+=a.readInt(); sum+=a.readInt(); System.out.println("三個數的和為:"+sum); a.close(); } catch(IOException e){ System.out.println("出現錯誤!"+fileName); } }}
運行結果:
三個數的和為:0
readInt 方法可以從輸入輸出流中讀入 4 個字節并將其作為 int 型數據直接參與運算。由于已經知道文件中有 3 個數據,所以可以使用 3 個讀入語句,但若只知道文件中是 int 型數據而不知道數據的個數時該怎么辦呢?因為 DataInputStream 的讀入操作如遇到文件結尾就會拋出 EOFException 異常,所以可將讀操作放入 try 中。
try{ while(true) sum+=a.readInt();}catch(EOFException e){ System.out.pritnln("三個數的和為:"+sum); a.close();}
EOFException 是 IOException 的子類,只有文件結束異常時才會被捕捉到,但如果沒有讀到文件結尾,在讀取過程中出現異常就屬于 IOException。
【例】從鍵盤輸入一個整數,求該數的各位數字之和。
import java.io.*;class ep10_9{ public static void main(String args[]) throws IOException{ DataInputStream a=new DataInputStream(System.in); System.out.print("請輸入一個整數:"); int b=a.readInt(); int sum=0; int c=b; while(c>0){ int d=c%10; //取最低位 c=c/10; //去掉最低位 sum=sum+d; //累加各位之和 } System.out.println(b+"的各位數字之和="+sum); }}
運行結果:
請輸入一個整數:26842403082 的各位數字之和=31
需要注意的是,輸入的數據 26 為變成了 842403082,原因在于輸入數據不符合基本類型數據的格式,從鍵盤提供的數據是字符的字節碼表示方式,若輸入 26,只代表 2 和 6 兩個字符的字節數據,而不是代表整數 26 的字節碼。
若要從鍵盤得到整數需要先讀取字符串,再利用其他方法將字符串轉化為整數。
標準輸入輸出
System.in、System.out、System.err 這 3 個標準輸入輸流對象定義在 java.lang.System 包中,這 3 個對象在 Java 源程序編譯時會被自動加載。
標準輸入:標準輸入 System.in 是 BufferedInputStream 類的對象,當程序需要從鍵盤上讀入數據時,只需要調用 System.in 的 read()方法即可,該方法從鍵盤緩沖區讀入一個字節的二進制數據,返回以此字節為低位字節,高位字節為 0 的整型數據。
標準輸出:標準輸出 System.out 是打印輸出流 PrintStream 類的對象。PrintStream 類是過濾輸出流類 FilterOutputStream 的一個子類,其中定義了向屏幕輸出不同類型數據的方法print()和 println()。
標準錯誤輸出:System.err 用于為用戶顯示錯誤信息,也是由 PrintStream 類派生出來的錯誤流。Err 流的作用是使 print()和 println()將信息輸出到 err 流并顯示在屏幕上,以方便用戶使用和調試程序。
【例】輸入一串字符顯示出來,并顯示 System.in 和 System.out 所屬的類。
import java.io.*;class ep10_10{ public static void main(String args[]){ try{ byte a[]=new byte[128]; //設置輸入緩沖區 System.out.print("請輸入字符串:"); int count =System.in.read(a); //讀取標準輸入輸出流 System.out.println("輸入的是:"); for(int i=0;i<count;i++) System.out.print(a[i]+""); //輸出數組元素的 ASCII 值 System.out.println(); for(int i=0;i<count-2;i++) //不顯示回車和換行符 System.out.print((char)a[i]+""); //按字符方式輸出元素 System.out.println(); System.out.println("輸入的字符個數為:"+count); Class InClass=System.in.getClass(); Class OutClass=System.out.getClass(); System.out.println("in 所在的類為:"+InClass.toString()); System.out.println("out 所在的類為:"+OutClass.toString()); } catch(IOException e){} }}
運行結果如所示:
需要注意的是,輸入了 3 個字符按回車后,輸出的結果顯示為 5 個字符。這是由于 Java 中回車被當作兩個字符,一個是 ASCⅡ為 13 的回車符,一個是值為 10 的換行符。程序中 getClass()和 ToString()是 Object 類的方法,作用分別是返回當前對象所對應的類和返回當前對象的字符串表示。
新聞熱點
疑難解答