IO流之----字節流(InputStream和OutputStream)

字節流(InputStream和OutputStream)

輸入流(InputStream):

  • 概述:
    • 此抽象類是表示字節輸入流的所有類的超類, 因爲是抽象類,不能直接實例化,所以必須使用其子類進行實例化(常用實現類:FileInputStream)。
  • 常用方法:

    • read(); 從輸入流中讀取數據的下一個字節。
    • read(byte[] b); 從輸入流中讀取一定數量的字節,並將其存儲在緩衝區數組 b 中。
    • read(byte[] b, int off, int len); 將輸入流中最多 len 個數據字節讀入 byte 數組。
    • close(); 關閉此輸入流並釋放與該流關聯的所有系統資源。
  • 基本字節流操作(僞代碼演示):

//創建輸入流對象
InputStream fis = new FileInputStream("b.txt");
//方式1
int by = 0; //定義變量,記錄每次讀到的字節
while ((by = fis.read()) != -1) {   //將每次讀到的字節賦值給b並判斷是否是-1
    System.out.println(by);
}

//方式2
byte[] bys = new byte[1024];    //自定義數組
int len = 0;
while ((len = fis.read(bys)) != -1) {
    System.out.print(new String(bys, 0, len));//寫出有效的字節個數
}
//釋放資源
fis.close();
  • 注意:
    • 1):read():讀一個,光標就在下一行等着讀下一個,讀完後光標就放到了最後,再讀就沒了,這時會返回 -1,和集合裏面迭代器的next() 有點相似。
    • 2);當用字節流讀漢字並打印到控制檯上,有時候會出現 “??” 問題,是因爲漢字是由兩個字節組成的,每次讀一個字節,所以就會出現”??”的現象,但是此問題用字節流複製文本文件時不會出現。

輸出流(OutPutStream):

  • 基本字節流操作

    • 基本字節輸出流的操作

      A:創建字節輸出流對象
      FileOutputStream fos = new FileOutputStream(“a.txt”);
      注意:輸出流輸出數據在創建輸出流對象的時候,如果文件不存在,就創建一個如果存在就清空該文件數據,然後寫入數據。

      B:調用寫數據的方法
      fos.write(97);

      C:釋放資源
      fos.close();

      注意:寫數據的方法有
      write(byte b)
      write(byte[] bys);
      write(byte[] bys, int start,int lenth);
      追加寫入用兩個參數構造
      FileOutputStream fos = new FileOutputStream(“a.txt”,true);

字節流複製文件的幾種方法:

  • 普通字節流複製文件 一次一個字節數據:
FileInputStream fis = new FileInputStream("123.jpg");   //創建輸入流對象,關聯123.jpg
FileOutputStream fos = new FileOutputStream("copy.jpg");//創建輸出流對象,關聯copy.jpg            
int b;
while((b = fis.read()) != -1) {     //在不斷的讀取每一個字節
    fos.write(b);           //將每一個字節寫出
}
//關流釋放資源
fis.close();                
fos.close();
  • 普通字節流複製文件 一次性拷貝一整個文件:
FileInputStream fis = new FileInputStream("致青春.mp3");
FileOutputStream fos = new FileOutputStream("copy.mp3");

byte[] arr = new byte[fis.available()];         //創建與文件一樣大小的字節數組(如果文件過大,會造成內存溢出)
fis.read(arr);                      //將文件上的字節讀取到內存中
fos.write(arr);                     //將字節數組中的字節數據寫到文件上

fis.close();
fos.close();
  • 普通字節流複製文件 一次一個字節數組:
FileInputStream fis = new FileInputStream("致青春.mp3");
FileOutputStream fos = new FileOutputStream("copy.mp3");

byte[] arr = new byte[1024 * 8];    //一般就定義成8kb的大小
int len;                //len是讀到的有效字節個數
while((len = fis.read(arr)) != -1) {    //寫arr是將文件上的字節讀取到字節數組中,
                    //如果忘記加arr,返回的就不是讀取的字節個數,而是字節的碼錶值
    fos.write(arr,0,len);       //0表示是從數組的0索引開始 len表示寫入數組的0-len長度的數據
}

fis.close();
fos.close();
  • 高效字節流複製文件:
//高效字節流就是包裝了一下普通字節流,內置了一個緩衝區(數組,大小是8kb)
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("致青春.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp3"));
int b;
while((b = bis.read()) != -1) {
    bos.write(b);
}
bis.close();
bos.close();

close()和flush()方法的區別:

close():關閉流 並且在關閉流之前刷新一次緩存區 而且關閉了之後就不能再使用流了。
flush(): 只刷新緩充區 不關閉流 流還可以繼續使用。

字節流注意問題:

  • 字節流讀取中文的問題:
    • 字節流在讀中文並打印到控制檯的時候有可能會讀到半個中文,造成亂碼。
  • 字節流寫出中文的問題:
    • 字節流直接操作的字節,所以寫出中文必須將字符串轉換成字節數組 fos.write(“我讀書少,你不要騙我”.getBytes());
    • 寫出回車換行 write(“\r\n”.getBytes());

JDK1.6複製文件加入標準異常處理代碼:

FileInputStream fis = null;
FileOutputStream fos = null;
try{
    fis = new FileInputStream("xxx.txt");
    fos = new FileOutputStream("copy.txt");
    int len;
    while((len = fis.read()) != -1) {
        fos.write(len);
    }
}finally {
    try {                   //try fianlly的嵌套目的是能關一個儘量關一個
    if(fis != null)
        fis.close();
} finally{
        if(fos != null)
        fos.close();
    }
}

JDK1.7複製文件加入標準異常處理代碼:

try(
        FileInputStream fis = new FileInputStream("xxx.txt");
        FileOutputStream fos = new FileOutputStream("copy2.txt");

        ){
            int len;
            while((len = fis.read()) != -1) {
                fos.write(len);
            }
        }
發佈了28 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章