-
基本讀取操作:
- InputStream();
- OutputStream(); // 直接寫入目的地中, 不需要 flush() 刷新
- write(byte[] b); // 參數為 byte 數組
-
字符流不能操作媒體文件, 因為字符流讀入文件后, 需要對照編碼表.
如果編碼表中沒有對應的數據, 這時, 碼表會用一些未知字符區的編碼替代,最終,會發生錯誤.
// 示例一: 寫入數據
// 1. 創建字節輸出流對象, 用於操作文件
FileOutputStream fos = new FileOutputStream("demo.js");
//2. 寫入數據, 注意寫入的為 byte 類型, 並且直接寫入到目的地中, 不需要 flush()
fos.write("abc".getBytes());
//3, 關閉資源
fos.close();
// 示例二: 讀取數據
// 1, 創建讀取流對象, 和指定文件關聯
FileInputStream fis = new FileInputStream("demo.js");
// 2. 讀取字節數組
byte[] buf = new byte[1024];
int len = 0;
while((ch=fis.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}
/*
* // 一次讀取一個字節
* int ch = 0;
* while((ch=fis.read()) != -1){
* System.out.println((char)ch);
* }
*/
// 3. 關閉流
fis.close();
// 備注: fis.available(); 可以獲取文件大小
// 示例三: 復制一個 mp3 媒體文件
public static void copyMp3() throws IOException {
FileInputStream fis = new FileInputStream("demo.mp3");
BufferedInputStream bufis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("my.mp3");
BufferedOutputStream bufos = new BufferedOutputStream(fos);
/*
* byte[] buf = new byte[1024];
*
* int len = 0;
* while((len=bufis.read(buf))!=-1){
* bufos.write(buf,0,len);
* bufos.flush(); // 使用緩沖區的讀, 每次讀完后, 需要刷新
* }
*/
// 緩沖區讀取單個字符
int ch = 0;
while((ch=bufis.read())!=-1){
bufos.write(ch);
}
bufos.close();
bufis.close();
}
// 示例四: 讀取一個鍵盤錄入的數據, 並將數據變成大寫顯示在控制台上,
// 如果用戶輸入的是 over, 結束鍵盤錄入
/* 分析:
* 鍵盤本身就是一個標准的輸入設備,
* 對於 java 而言, 對於這種輸入設備都有對應的對象.
* 鍵盤錄入對應的對象位於 java.lang 包中的 System 類
* "in" : 標准輸入
* "out" : 標准輸出
* 思路:
* 1. 因為鍵盤錄入只讀取一個字節, 要判斷是否是 over, 需要將讀取到的字節拼成字符串
* 2. 那就需要一個容器, StringBuilder
* 3. 在用戶回車之前, 將錄入的數據變成字符串判斷即可
*
* 步驟:
* 1. 創建容器
* 2. 獲取鍵盤讀取流
* 3. 定義變量記錄讀取到的字節, 並循環獲取
* 4. 將讀取到的字節存儲到 StringBuilder 中
* 5. 在存儲之前需要判斷是否是換行標記, 因為換行標記不存儲
*/
public static void readKey() throws IOException{
// 1. 創建容器
StringBulider sb = new StringBuilder();
// 2. 獲取鍵盤讀取流
InputStream in = System.in;
// 3. 定義變量記錄讀取到的字節, 並循環獲取
int ch = 0;
while((ch=in.read())!=-1){
// 在存儲之前需要判斷是否是換行標記, 因為換行標記不存儲
if(ch=='\r')
continue;
if(ch=='\n'){
String temp = sb.toString();
if("over".equals(temp))
break;
System.out.println(temp.toUpperCase());
sb.delete(0,sb.length()); // 每次輸出后,需要清空 StringBuilder 容器.
// 集合的清空用 clear
}
else{
sb.append((char)ch); // 需要變成字符存儲進容器
}
}
}
轉換流
- 將字節流轉換為字符流的橋梁:
InputStreamReader();
相當於解碼 - 將字符流轉換為字節流的橋梁:
OutputStreamWriter();
相當於編碼 - 轉換過程中,可以指定編碼表
// 示例四: 讀取一個鍵盤錄入的數據, 並將數據變成大寫顯示在控制台上,
// 如果用戶輸入的是 over, 結束鍵盤錄入
public static void readKey() throws IOException{
// 字節流
InputStream in = System.in;
// 將字節流轉換為字符流
InputStreamReader isr = new InputStreamReader(in);
// 緩沖區修飾字符流
BufferedReader bufr = new BufferedReader(isr);
// 獲取輸出流
OutputStream out = System.out;
// 將字符流轉換為字節流, 構造函數可以接收 字節流
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bufw = new BufferedWriter(osw);
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
// System.out.println(line.toUpperCase());
// 每次讀取到的 line 是字符, 將字符寫入到字節輸入流中, 需要用到 OutputStreamWriter
bufw.write(line.toUpperCase());
bufw.newLine(); // 換行
bufw.flush(); // 每次寫入后,需要刷新. 將流中的數據刷到控制台上
}
}
// 升級版本:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
參考資料