Java I/O系統

編程語言的[b]I/O類庫[/b],常使用流這個抽象概念,它代表任何有能力產出數據的數據源對象,或者有能力接收數據的接收端對象。

[b]InputStream[/b]的作用是用來表示那些從不同數據源產生輸入的類,這些數據源包括
1 字節數組 ByteArrayInputStream 將內存的緩衝去當作InputStream使用
2 String對象 StringBufferInputStream (已棄用)
3 文件 FileInputStream
4 管道 PipedInputStream
5 一個有其他種類的流組成的序列,以便我們可以將它們收集合併到一個流內 SequenceInputStream
6 其他數據源,網絡連接
7 FilterInputStream 所有“裝飾器”類的基類

[b]OutputStream[/b]決定了輸出所要去往的目標:
1 字節數組(但不是String,不過可以根據字節數組創建String) ByteArrayOutputStream
2 文件 FileOutputStream
3 管道 PipedOutputStream
4 FilterOutputStream


[b]FilterInputStream[/b]類型
1 DataInputStream 可以從流讀取基本數據類型(int char long等)
2 BufferedInputStream 使用緩衝區
3 LineNumberInputStream 跟蹤輸入流的行號 (已棄用)
4 PushbackInputStream

[b]FilterOutputStream[/b]類型
1 DataOutputStream
2 PringStream 用於產生格式化輸出,不要用於網絡編程,因爲格式化與本地系統類型有關
3 BufferedOutputStream

Stream是面向字節形式的I/O (8位字節流),Reader和Writer是面向字符、提供兼容Unicode的I/O (16位的Unicode字符),我們應該優先嚐試使用Reader和Writer,在不得不使用時,纔想到面向字節的類庫。(比如java.util.zip)。爲了實現字節和字符的轉換,要用到“適配器”類InputStreamReader 和 OutputStreamWriter


[img]http://dl.iteye.com/upload/attachment/271094/ca6a88c4-bf63-351d-8106-ee2c792f9b0a.png[/img]

[img]http://dl.iteye.com/upload/attachment/271096/040766e6-3014-3370-8298-c5df01c1b033.png[/img]


從文件數據源緩衝輸入
public class BufferedInputFile {
public static String read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while ((s = in.readLine()) != null)
sb.append(s + "\n");
in.close();
return sb.toString();
}
}


從內存輸入
public class MemoryInput {
public static void main(String[] args) throws IOException {
StringReader in = new StringReader("this is a StringReader");
int temp;
while ((temp = in.read()) != -1)
System.out.print((char) temp);
in.close();
}
}


格式化內存輸入
public class FormattedMemoryInput {
public static void main(String[] args) throws IOException {
DataInputStream in = new DataInputStream(
new ByteArrayInputStream("this is a ByteArrayInputStream".getBytes()));
// 讀到任何字節的值都是合法的,不能通過返回值來檢測輸入是否結束
// avaliable()方法查看還有多少可供存取的字符
while (in.available() != 0)
System.out.print((char) in.readByte());
}
}


基本文件輸出
public class BasicFileOutput {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("temp"));
PrintWriter out = new PrintWriter("temp2");
String s;
int lineNum = 0;
while ((s = in.readLine()) != null)
out.println("line " + lineNum++ + " is " + s);
out.flush();
}
}


[b]存儲和和恢復數據[/b]
爲了輸出可供另一個“流”恢復的數據,我們需要用DataOutputStream,並用DataInputStream恢復數據。
隨機訪問文件RandomAccessFile和DataOutputStream、DataInputStream同樣實現了DataOutput、DataInput接口,使用同樣的方式操作
public class StroingAndRecoveringDate {
public static void main(String[] args) throws IOException {
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("data")));
out.writeUTF("pi is: ");
out.writeDouble(3.1415926);
out.flush();
DataInputStream in = new DataInputStream(
new BufferedInputStream(new FileInputStream("data")));
System.out.println(in.readUTF());
System.out.println(in.readDouble());
}
}



[b]標準I/O[/b]
程序的所有輸入可以來自於標準輸入,所有輸出都可以發送到標準輸出,所有錯誤信息都可以發送到標準錯誤。標準I/O的意義在於:我們可以把程序串聯起來。
System.in是未包裝的InputStream,System.out、System.err是PrintoStream。
[b]標準I/O重定向[/b]
如果突然在顯示器上有大量輸出,輸出滾動太快而無法閱讀,重定向輸出就顯得極爲有用。爲了向重複測試某個用戶的輸入命令行程序,重定向輸入就很有價值。
I/O重定向操縱的是字節流,不是字符流!
public class Redirecting {
public static void main(String[] args) throws IOException {
PrintStream consoleOut = System.out;
InputStream consoleIn = System.in;
BufferedInputStream in =
new BufferedInputStream(new FileInputStream("temp"));
PrintStream out =
new PrintStream(new BufferedOutputStream(new FileOutputStream("temp2")));
// 標準輸入改爲文件temp,不是console
System.setIn(in);
// 標準輸出已經改到文件temp2上
System.setOut(out);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
// 標準錯誤仍然輸出到控制檯
System.err.println(s);
}
out.close();
// 恢復
System.setOut(consoleOut);
System.setIn(consoleIn);
}
}



可能你會需要Java內部執行其他操作系統的程序,並且要控制這些程序的輸入和輸出。
public class OSExecute {
public static void command(String command) {
boolean err = false;
try {
Process process =
new ProcessBuilder(command.split(" ")).start();
BufferedReader results = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String s;
while((s = results.readLine())!= null)
System.out.println(s);
BufferedReader errors = new BufferedReader(
new InputStreamReader(process.getErrorStream()));

while((s = errors.readLine())!= null) {
System.err.println(s);
err = true;
}
} catch(Exception e) {
// Compensate for Windows 2000, which throws an
// exception for the default command line:
if(!command.startsWith("CMD /C"))
command("CMD /C " + command);
else
throw new RuntimeException(e);
}
if(err)
throw new OSExecuteException("Errors executing " + command);
}
public static void main(String[] args) {
new OSExecute().command("explorer d:\\新建文本文檔.txt")
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章