黑馬程序員-IO流

------- android培訓java培訓、期待與您交流! ----------

一.IO流
1.概念
IO流用來處理設備之間的數據傳輸
Java對數據的操作是通過流的方式
Java用於操作流的類都在IO包中
流按流向分爲兩種:輸入流,輸出流。
流按操作類型分爲兩種:
字節流 : 字節流可以操作任何數據,因爲在計算機中任何數據都是以字節的形式存儲的
字符流 : 字符流只能操作純字符數據,比較方便。
2.IO流常用父類
字節流的抽象父類:
InputStream
OutputStream
字符流的抽象父類:
Reader
Writer
3.IO程序書寫
使用前,導入IO包中的類
使用時,進行IO異常處理
使用後,釋放資源
二.字節流

1.常用方法
InputStream:
read() 讀取一個字節
read(byte[]) 讀取若干(數組長度)字節
available() 獲取可讀的字節數
close() 關閉流, 釋放資源
OutputStream:
write(int) 寫出一個字節
write(byte[]) 寫出數組中的所有字節
write(byte[],start,len);
close() 關閉流, 釋放資源
2.讀取文件
創建FileInputStream對象, 指定一個文件. 文件必須存在, 不存在則會拋出FileNotFoundException
使用read()方法可以從文件中讀取一個字節. 如果讀取到文件末尾會讀到-1
讀取結束後需要釋放資源, 調用close()方法關閉輸入流

輸入流代碼
FileInputStream fis = new FileInputStream("xxx.txt");       //創建流對象,關聯xxx.txt文件
int b;
while((b = fis.read()) != -1) {                             //將每次讀到的結果賦值給b
    System.out.println(b);
}
fis.close();

爲什麼read方法返回是int而不是byte類型呢?
因爲如果讀取的是視頻文件或音頻文件或圖片文件等,在讀取過程中很有可能會遇到11111111,也就是byte類型的-1,那麼遇到-1程序就會停止讀取,會漏掉文件,爲了防止這種情況出現,把byte類型提升爲int類型,在這個字節前補上24個0,把遇到的-1變成255,這樣可以保證將整個文件讀完
3.寫出文件
創建FileOutputStream對象, 指定一個文件. 文件不存在會創建新文件, 存在則清空原內容. 如果需要追加, 在構造函數中傳入true.
使用write()方法可以向文件寫出一個字節.
寫出結束後同樣需要調用close()

輸出流代碼
FileOutputStream fos = new FileOutputStream("aaa.txt"); //創建流對象,關聯aaa.txt
fos.write(100);                                         //寫出數據的時候會將前面24個0去掉,寫出的是一個字節
fos.write(98);
fos.write(99);
fos.close();                                            //關閉流,釋放資源
4.拷貝文件
可以從文件中逐個字節讀取, 逐個字節寫出, 但這樣做效率非常低
我們可以定義一個數組作爲緩衝區, 一次讀取多個字節裝入數組, 然後再一次性把數組中的字節寫出1byte = 8bit
1,逐個字節拷貝
FileInputStream fis = new FileInputStream("致青春.mp3");       //創建輸入流對象,關聯致青春.mp3
FileOutputStream fos = new FileOutputStream("copy.mp3");    //創建輸出流對象,關聯copy.mp3

int b;
while((b = fis.read()) != -1) {                             //將每次讀到的賦值給b
    fos.write(b);                                           //將b中的字節寫出去
}
fis.close();                                                //關流,釋放資源
fos.close();  

2,自定義數組拷貝

FileInputStream fis = new FileInputStream("致青春.mp3");       //創建輸入流對象,關聯致青春.mp3
FileOutputStream fos = new FileOutputStream("copy.mp3");    //創建輸出流對象,關聯copy.mp3
byte[] arr = new byte[1024 * 8];                            //自定義數組
int len;
while((len = fis.read(arr)) != -1) {                            //將數據讀到字節數組中
    fos.write(arr, 0, len);                                 //從字節數組中將數據寫到文件上
    //fos.write(arr);
}

fis.close();                                                //關流,釋放資源
fos.close();

int len = read(arr);如果文件上有數據返回的就是讀到有效的字節個數,如果文件上沒有數據返回的就是-1

3,定義一個大數組拷貝,數組和文件的字節個數一樣大

//fis.available();一次獲取讀的文件的大小
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();
4,帶緩衝區的拷貝
FileInputStream fis = new FileInputStream("致青春.mp3");       //創建輸入流對象,關聯致青春.mp3
BufferedInputStream bis = new BufferedInputStream(fis);     //對fis進行包裝,內置一個8192大小的字節數組      
FileOutputStream fos = new FileOutputStream("copy.mp3");    //創建輸出流對象,關聯copy.mp3
BufferedOutputStream bos = new BufferedOutputStream(fos);   //對fos進行包裝,內置一個8192大小的字節數組

int b;
while((b = bis.read()) != -1) {                             //read一次會先將文件上的數據讀到緩衝區中,再從緩衝區一個一個的賦值給b
    bos.write(b);                                           //write一次,是將b中的字節數據寫到緩衝區,緩衝區寫滿再一次寫到文件上
}

bis.close();                                                //只需要關掉包裝後的即可
bos.close();

5.BufferedInputStream
BufferedInputStream內置了一個緩衝區(數組)
從BufferedInputStream中讀取一個字節時
BufferedInputStream會一次性從文件中讀取8192個, 存在緩衝區中, 返回給程序一個
程序再次讀取時, 就不用找文件了, 直接從緩衝區中獲取
直到緩衝區中所有的都被使用過, 才重新從文件中讀取8192個
6.BufferedOutputStream
BufferedOutputStream也內置了一個緩衝區(數組)
程序向流中寫出字節時, 不會直接寫到文件, 先寫到緩衝區中
直到緩衝區寫滿, BufferedOutputStream纔會把緩衝區中的數據一次性寫到文件裏
7.讀中文
字節流只讀中文有弊端,可能會出現半個中文
解決辦法
1,用字符流只讀
2,將文件上的所有的字節數據都讀到緩衝區中,然後在轉換成字符串ByteArrayOutputStream

FileInputStream fis = new FileInputStream("bbb.txt");
byte[] arr = new byte[4];
int len;
while((len = fis.read(arr)) != -1) {
    System.out.println(new String(arr,0,len));
}
fis.close(); 

8.寫中文
字節流是可以寫字符串的
但是必須將字符串轉換成字節數組寫出去

FileOutputStream fos = new FileOutputStream("bbb.txt");
fos.write("你要減肥,造嗎".getBytes());
fos.close();
9.finally嵌套
1.6版本及以前的標準的異常處理代碼

FileInputStream fis = null; 
FileOutputStream fos = null; 
try {
    fis = new FileInputStream("aaa.txt");
    fos = new FileOutputStream("bbb.txt");

    int b;
    while((b = fis.read()) != -1) {
        fos.write(b);
    }
}finally {
    try {
        if(fis != null) 
            fis.close();
    } finally {
        if(fos != null)
            fos.close();
    }
}

10.try close
1.7版本的標準的異常處理代碼
try(
    FileInputStream fis = new FileInputStream("aaa.txt");
    FileOutputStream fos = new FileOutputStream("bbb.txt");
    MyClose mc = new MyClose();
){
    int b;
    while((b = fis.read()) != -1) {
        fos.write(b);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章