Java中的字節流之輸出、輸入流

    什麼是輸出流?
    程序能向其中寫入數據的流
    程序 -> 文件
    稱爲輸出(output 寫文件)
    舉個例子,就像學生寫作業 交給老師

    什麼叫輸入流?
    程序可以從中讀取數據的流
    文件 -> 程序
    稱爲輸入(input 讀文件)
    一樣的例子 就像老師改完的作業 拿去給學生閱讀

字節輸出流

    OutputStream
    是一個抽象類,是所有輸出字節流的父類
    因爲是抽象類,所以不能直接實例化對象
    需要子類來重寫
    這裏我們用FileOutputStream這個子類來操作文件
    /*
     * 構造方法:
       參數: 1.文件(被寫入的文件)
             2.文件的路徑(被寫入的路徑)

        寫入文件的流程:
            1.綁定要寫入的文件 或 文件路徑
            2.使用write方法寫入
            3.關閉資源
     */
    public class Demo {
        public static void main(String[] args) throws IOException {

     //綁定數據的目的地(綁定要寫入的文件)
     //該路徑下 沒有該文件 會幫你創建這個文件
     // 如果已經有了蓋文件 文件會被覆蓋
     File file = new File("/Users/s/Desktop/Test/su.txt");
        // 打印出這段代碼時 可能會出現編譯時異常
        // 先將這個異常拋出
        FileOutputStream oStream = new FileOutputStream(file);

        //寫入數據
        // 打印出來的值爲對應的ASCII上的值
        oStream.write(49);
        oStream.write(48);

        //用字節數組寫入
        byte[] b = {65,66,67};
        oStream.write(b);

        // 按字節數組的索引和長度寫入
        oStream.write(b, 0, 3);

        // 簡單寫法
        oStream.write("hello".getBytes());
        oStream.write("world".getBytes());

        // 關閉資源
        oStream.close();
        }
    }

    //打開這個路徑的文件 看看其中的變化

文件的續寫

     public class Demo {
        public static void main(String[] args) throws IOException {
            File file = new File("/Users/s/Desktop/Test/sudie.txt");
            FileOutputStream oStream = new FileOutputStream(file, true);
            oStream.write("hello\n".getBytes());
            oStream.close();
        }
     }   

異常處理

     public class Demo {
        public static void main(String[] args) {
            // 異常處理
            // IO發生了異常 都需要停止程序 修改代碼
            // 拋出運行時異常
            File file = new File("/Users/s/Desktop/Test/sudie.txt");
            // 增加作用域
            FileOutputStream oStream = null;
            try{
                // 創建一個流
                // 只要是你手動創建的流 你就需要手動關閉它
                oStream = new FileOutputStream(file);
                //寫入
                o.Stream.write("hello".getBytes());
            } catch (FileNotFoundException e){
                // 拋出一個運行時異常(直接停止掉 程序)
                throw new RuntimeException("文件找不到");
            } catch(IOException e){
                // 文件編寫失敗 直接停止程序
                throw new RuntimeException("文件編寫失敗");
            } finally{
                // 關閉資源
                try{
                    //非空判斷
                    // 如果是空的 說明流創建失敗 就不用關閉
                    if(oStream != null) {
                        oStream.close();
                    }
                } catch (IOException e){
                    // 關閉資源失敗 直接停止程序
                    throw new RuntimeException("關閉失敗")
                }
            }
        }
     }       

字節輸入流

    InputStream 是所有輸入流的父類
    注意: 字節流寫入的時候 是一個字節一個字節的寫
        : 讀取也是一個字節一個字節的讀

    讀取文件流程
    1.綁定數據源文件(要讀哪個文件)
    2.使用read方法讀文件
    3.關閉資源
    在你想要讀的路徑下創建一個txt文件 這裏我取名爲 su.txt
    在裏面輸入 abcde保存一下
public class Demo {
    public static void main(String[] args) throws IOException {

    File file = new File("/Users/s/Desktop/Test/su.txt");
        FileInputStream iStream = new FileInputStream(file);
        // 讀取
        int i1 = iStream.read();
        //這裏打印的時候強轉成了char類型
        //如果不強轉 輸出的就是對應的ASCII表上的值
        System.out.println((char)i1);

        i1 = iStream.read();
        System.out.println((char)i1);
        i1 = iStream.read();
        System.out.println((char)i1);
        i1 = iStream.read();
        System.out.println((char)i1);
        i1 = iStream.read();
        System.out.println((char)i1);
        // 當讀取到文件末尾的時候 會返回 -1
        // 相當於 你讀到-1 文件就讀完了
        i1 = iStream.read();
        System.out.println(i1);
        //關閉資源
        iStream.close();
        }
    }   
    如果要讀取的文件中元素有很多,像上面一樣打,需要大量時間,所以可以使用循環

public class Demo {
    public static void main(String[] args) throws IOException {

    File file = new File("/Users/s/Desktop/Test/su.txt");
        FileInputStream iStream = new FileInputStream(file);
        // read方法 沒調用一次 就讀取一個字節
        // 循環的時候 read方法只能出現一次
        // 聲明一個變量 保存讀出來的結果
        int num = 0;
        while ((num = iStream.read()) != -1) {
             //num = iStream.read();
             //char c = (char)num;
             System.out.println(num);
        }
    }

文件的複製

    /*
    * 使用字節的輸入輸出流 進行文件的複製
    * (字節流 不但可以寫文本 還可以寫圖片 音頻 視頻 等等...)
    */
    public class Demo {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        // 異常處理的 複製文件
        // 讀
        FileInputStream fis = null;
        // 寫
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("/Users/lanou/Desktop/Test/taytay.jpg");
            fos = new FileOutputStream("/Users/lanou/Desktop/Test/Taylor.jpg");

            //開始讀 讀一個字節 寫一個字節
//          int len = 0;
//          while ((len = fis.read()) != -1) {
//              // 直接把讀出來的 寫進文件
//              fos.write(len);
//          }


             //用字節數組的方式 讀寫 利用緩衝數組讀寫 效率較高
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = fis.read(b)) != -1) {
                fos.write(b, 0, len);
            }

        } catch (FileNotFoundException e) {
            throw new RuntimeException("文件未找到");
        } catch (IOException e) {
            throw new RuntimeException("文件複製失敗");
        } finally {
            // 這時讀取和寫入都結束了 先關哪個都行
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("關閉資源失敗");
            } finally {
                // 寫一起的話 如果第一個報了異常
                // 第二個流會無法關閉
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    throw new RuntimeException("關閉資源失敗");
                }
            }
        }
        // 獲取結束時間
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

將一個文件夾 複製 另一個文件夾下

    public class Demo02 {
    public static void main(String[] args) throws IOException {
        // 測試
        File oldFile = new File("/Users/lanou/Desktop/Test");
        File newFile = new File("/Users/lanou/Desktop/XTest");
        copyFile(oldFile, newFile);

    }
    /*
     * 複製文件夾方法
     * 參數
     * oldFile 源文件夾(要被複制的)
     * newFile 目標文件夾(要把源文件夾複製進去)
     */
    public static void copyFile(File oldFile,File newFile) throws IOException {
        // 在目標文件夾下 創建 新的文件夾 名字和 源文件夾一樣
        File newDir = new File(newFile, oldFile.getName());
        newDir.mkdir();
        /*
         * 複製文件 -> 找到文件 -> 一邊讀 一邊寫
         *        -> 找到文件夾 -> 繼續調用本方法
         */
        // 遍歷源文件夾
        File[] listFiles = oldFile.listFiles();
        int len = 0;
        for (File subFile : listFiles) {
            // 判斷是文件
            if (subFile.isFile()) {
                // 進行讀寫
                FileInputStream fis = new FileInputStream(subFile);
                // 要在新建的文件夾下寫入 newDir + subFile.getName;
                File tempFile = new File(newDir, subFile.getName());
                FileOutputStream fos = new FileOutputStream(tempFile);
                // 循環寫入(寫入數組)
                byte[] b = new byte[1024];
                while ((len = fis.read(b)) != -1) {
                    fos.write(b, 0, len);
                }
                // 關閉資源
                fis.close();
                fos.close();
            }else {
                // 是文件夾 需要創建文件夾 繼續遍歷讀寫
                copyFile(subFile, newDir);
            }
        }
    }
}

將一個文件夾的所有txt文件 複製 到另一個文件夾下

    public class Demo03 {
    public static void main(String[] args) throws IOException {
        File oldFile = new File("/Users/lanou/Desktop/Test");
        File newFile = new File("/Users/lanou/Desktop/XTest");
        getOldFlieTxtToNewFile(oldFile, newFile);
    }

    public static void getOldFlieTxtToNewFile(File oldFile, File newFile) throws IOException {
        // 將過濾器直接傳到 文件數組中
        File[] listFiles = oldFile.listFiles(new TXTFiles());

        for (File subFile : listFiles) {
            // 創建 輸出 輸入流
            if (subFile.isFile()) {
                FileInputStream fis = new FileInputStream(subFile);
                File tempFile = new File(newFile, subFile.getName());
                FileOutputStream fos = new FileOutputStream(tempFile);
                byte[] b = new byte[1024];
                int len = 0;
                if ((len = fis.read(b)) != -1) {
                    fos.write(b, 0, len);
                }
                fis.close();
                fos.close();
            }else {
                getOldFlieTxtToNewFile(subFile, newFile);
            }
        }
    }
}

// 過濾器
class TXTFiles implements FileFilter{

    @Override
    public boolean accept(File pathname) {
        //是文件夾 則返回一個true
        if (pathname.isDirectory()) {
            return true;
        }
        // 如果後綴名是txt的 則 返回true
        return pathname.getName().endsWith("txt");
    }
}

                                        Day.24

http://blog.csdn.net/ssssssue

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