IO流
- IO流
- 流的分類
-
- 輸入輸出流
- 位元組流和字元流
- 節點流和處理流
- InputStream和Reader
- OutputStream 和 Writer
- 處理流用法
- IO流
- 轉換流
- 推回輸入流
IO流
Java IO流是實作輸入/輸出的基礎。
Java把不同的輸入/輸出源(鍵盤,檔案,網絡連接配接等)抽象為"流",Stream。
通過流的方式使用相同的方式來通路不同的輸入/輸出源。
stream是從起源(source)到接收(sink)的有序資料。
傳統流類型都在 java.io 包中。
流的分類
輸入輸出流
按照流的流向分為輸入流和輸出流。是以記憶體的角度來劃分。
輸入流: 隻能讀取資料,不能寫入。由InputStream 和 Reader作為基類
輸出流: 隻能寫入資料,不能讀取。由OutputStream 和 Writer 作為基類
位元組流和字元流
位元組流: 操作資料單元為8位位元組,由 InputStream 和 OutputStream作為基類
字元流:操作資料單元為16位字元,由 Reader 和 Writer 作為基類
節點流和處理流
按角色分為節點流和處理流。
從一個特定的IO裝置(磁盤,或網絡)讀寫資料的流,稱為節點流,節點流也被稱為低級流(Low Level Stream)。
處理流是對節點流的封裝。稱為進階流,包裝流。
使用裝飾器設計模式。
InputStream和Reader
InputStream和Reader都是輸入流的抽象基類。
都實作了下面方法
- read(): 可以讀取單個字元或位元組,
- read(byte[] b): 讀取 b.length 個位元組
- read(byte[] b, int off, int len): 讀取 len 個位元組,從 off 位置開始讀
- mark(): 記錄指針目前位置記錄一個标記
- markSupported(): 是否支援 mark操作
- reset():将指針重新定位到上一次記錄mark的位置
- skip(): 指針向前移動 n個位元組/字元
FileInputStream 和 FileReader是兩個讀取檔案的輸入流。是 InputStream和 Reader的子類。
FileInputStream fis = new FileInputStream("ReadMe.txt");
byte[] fbuff = new byte[1024];
int hasRead = 0;
while ((hasRead = fis.read(fbuff)) > 0){
System.out.println(new String(fbuff, 0, hasRead));
}
fis.close();
程式裡打開的 IO資源不屬于記憶體裡的資源, 垃圾回收機制無法回收該資源, 是以要顯式的關閉IO資源,調用 fis.close()。
InputStream 和 Reader都實作了AutoCloseable 接口, 是以可以通過自動關閉資源的 try 語句來關閉IO流。
public abstract class InputStream implements Closeable {
}
public interface Closeable extends AutoCloseable {
}
OutputStream 和 Writer
OutputStream 和 Writer都是輸出流的抽象基類。
都提供了下面方法:
- write(int c): 指定字元/位元組輸出
- write(byte[] buf): 數組輸出
-
write(byte[] buf, int off, int len): 将數組中 off 開始, 長度為len 輸出
Writer還包括了支援 String 參數的 writer() 方法。
FileOutputStream 和 FileWriter 用來檔案輸出。
try (FileInputStream fis1 = new FileInputStream("ReadMe.txt");
FileOutputStream fos = new FileOutputStream("newFIle.txt")){
byte[] fbuff = new byte[32];
int hasRead = 0;
while ((hasRead = fis1.read(fbuff)) > 0){
fos.write(fbuff, 0, hasRead);
}
}
catch (IOException e){
e.printStackTrace();
}
關閉輸出流除了保證資源被回收之外,還可以将輸出緩沖區的資料flush到實體節點中。在執行close()之前,自動執行輸出流的flush()。
如果是字元串内容,可以直接使用Writer();
try (FileWriter fileWriter = new FileWriter("t.txt")){
fileWriter.write("a\r\n");
fileWriter.write("c test\r\n");
}
catch (IOException e){
e.printStackTrace();
}
處理流用法
使用處理流包裝節點流,對外提供更加友善的輸入/輸出。
節點流的構造器是以實體IO節點為參數的。
處理流的構造器不是實體IO節點,而是已經存在的流。
下面例子 PrintStream 就是處理流,輸出更加友善。
try(FileOutputStream fos = new FileOutputStream("abc.txt");
PrintStream ps = new PrintStream(fos)){
ps.println("test字元串");
ps.println(new FileTest());
}
catch (IOException e){
e.printStackTrace();
}
關閉資源時,隻需要關閉最上層處理流即可, 關閉處理流時,自動關閉該處理流包裝的節點流。
IO流
JAVA IO流體系提供了近40個類。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TSE9ENVR0T5FFVNdXVzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcugjM4ETOzcTM4AjMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
轉換流
IO展現提供了兩個轉換流, 将位元組流轉換為字元流。
InputStreamReader 将位元組輸入流轉為字元輸入流
OutputStreamWriter 将位元組輸出流轉為字元輸出流
try (InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(reader)
){
String line = null;
while ((line = bufferedReader.readLine()) != null){
if(line.equals("exit")){
System.exit(1);
}
System.out.println(line);
}
}
catch (IOException e){
e.printStackTrace();
}
System.in 代表标準輸入,即鍵盤輸入,這個輸入流是 InputStream 類的執行個體, 使用 InputStreamReader 轉為字元輸入流。
将 Reader 包裝為 BufferedReader, 使用它的 readLine() 方法一次讀一行。
推回輸入流
PushbackInputStream, PushbackReader 這兩個是推回輸入流。
提供了 unread () 方法。
這兩個輸入流都帶一個推回緩沖區, 将指定數組内容推回到該緩沖區。
調用 read()時, 先從推回緩沖區讀取, 未裝滿時,再從原緩沖區讀取。
需要指定推回緩沖區的大小, 預設為1。
下面例子找到 test 字元串, 輸出之前的内容
try (PushbackReader pushbackReader = new PushbackReader(new FileReader("abc.txt"), 32)){
char[] buf = new char[32];
String lastConntent = "";
int hasRead = 0;
while ((hasRead = pushbackReader.read(buf)) > 0){
String content = new String(buf, 0, hasRead);
int lastIndex = (lastConntent + content).indexOf("test");
if(lastIndex > 0){
pushbackReader.unread((lastConntent + content).toCharArray());
if(lastIndex > 32){
buf = new char[lastIndex];
}
pushbackReader.read(buf, 0, lastIndex);
System.out.println(new String(buf, 0, lastIndex));
System.exit(0);
}
else {
System.out.println(lastConntent);
lastConntent = content;
}
}
}
catch (IOException e){
e.printStackTrace();
}
位址:https://blog.csdn.net/yonggang7/article/details/86776449