1. 流的分類
在java.io包中流分爲兩類:
字節流(byte):
InputStream OutputStream
字符流(char):
Reader Writer
從下面的圖我們來看看字節流與字符流的區別:
字節流與字符流的區別:
字節流是原生操作無需轉換,字符流是處理後的操作。
字節流可以處理文本文件、圖像、音樂、視頻等資源
一般使用字節流(無論是網絡傳輸還是磁盤數據保存均以字節爲單位)
只有處理中文文本時纔會用到字符流。
2. 流操作流程
無論是字節流還是字符流,操作流程幾乎一樣
1.取得終端對象
2.根據終端對象取得輸入輸出流
3.根據輸入輸出流進行數據讀取與寫入
4.關閉流
IO操作屬於資源處理,所有的資源操作在使用後一定要關閉
3. 字節輸出流
字節輸出流有三個核心輸出方法:
- 將指定的字節數組全部輸出
public void write(byte[ ] b) throws IOException; - 將部分字節數組輸出
public void write(byte[ ] b,int offset, int len) throws IOException - 輸出單個字節
public abstract void write(int b) throws IOException;
在IO操作這裏,要想使用某個終端,這個終端一定有一個類實現了Outputstream這個類(Outputstream是抽象類)。
- 文件內容覆蓋
public FileOutputStream(File file) throws FilenotFoundException - 文件內容追加(boolean返回是否允許追加文件內容)
public FileOutputStream(File file, boolean append)
當使用FileOutputStream進行文件輸出時,只要文件的父路徑存在,FileOutputStream會自動創建文件。
看一個例子:
public class IO1{
public static void main(String[] args) {
//1.取得終端對象
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"Test.txt"); //在桌面創建Test.txt的文件夾
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//2.取得終端對象的輸出流
try {
//多次運行內容不變,覆蓋上次運行結果
OutputStream out = new FileOutputStream(file); //向上轉型
//允許文件內容的追加OutputStream out = new FileOutputStream(file,"true");
// 3. 進行數據的輸出
String msg = "java\n"; //所創建文件夾內容爲"java"
out.write(msg.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
{
//4.關閉流
out.close();
}
}
}
}
4.字節輸入流
輸入方法 read :
a. 讀取數據到字節數組b中
public int read(byte[ ] b) throws IOException
返回值三種情況(喝稀飯,開始稀飯多,勺子一勺只能喝一勺的量,後來只剩下不足一勺子的量,再後來吃完了):
- 返回b的長度 : 當讀取的數據大小 > 字節數組大小,返回字節數組大小
- 返回一個大於0的數,但是小於b長度 : 讀取數據大小 < 字節數組大小,返回真正讀取個數
- 返回 -1 :數據讀取完畢
b. public int read( ) throws IOException:讀取單個字節
栗子:
public class IO1{
public static void main(String[] args) {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文檔.txt"); //從桌面中的新建文本文檔讀取文件內容
try {
InputStream in = new FileInputStream(file);
byte[] data = new byte[1024];
int resylt = in.read(data);
System.out.println(new String(data));
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.字符流
字符輸出流Writer-適用於處理中文文本
除了參數爲字符數組外,多了一個傳入String對象的方法
可以直接支持字符串的輸出
public void write (String str) throws IOException
字符流若爲關閉,數據在緩衝區存放,不會輸出目標終端。要想將數據輸出,要麼將輸出流關閉,要麼使用flush強制刷新緩衝區。
public class IO1{
public static void main(String[] args) throws IOException {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文檔.txt");
Writer writer = new FileWriter(file);
String str = "hello";
writer.write(str);
writer.close();
}
}
字符輸入流Reader
Reader類中沒有方法可以直接讀取字符串,只能通過字符數組來讀取
public int read(char cbuf[]) throws IOException
public class IO1{
public static void main(String[] args) throws IOException {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文檔.txt");
Reader reader = new FileReader(file);
char[] data = new char[1024];
int result = reader.read(data); //此時文件內容小於數組開闢大小,返回文件內容
System.out.println(result);
System.out.println(new String(data,0,result)); //文件內容
}
}
6 轉換流:字節流 -> 字符流
轉換流用於將底層的字節流轉爲字符流供子類使用,單向操作
OutputStreamWriter : 字節輸出流 -> 字符輸出流
InputStreamReader : 字節輸入流 -> 字符輸入流
字符流的具體子類大都是通過轉換流將字節流轉爲字符流的(FileWriter繼承轉換流)
public class fileTes{
public static void main(String[] args) throws IOException {
//1.取得終端對象
File file = new File("C:"+File.separator+"Users"+File.separator+
"Administrator"+File.separator+"Desktop"+File.separator+"Test.txt");
//2.取得終端輸出流
OutputStream outputStream = new FileOutputStream(file);
//3.進行數據的輸入輸出
OutputStreamWriter out = new OutputStreamWriter(outputStream);
out.write("你好");
//4. 關閉流
out.close();
}
}