10.輸入輸出

10.1 File(目錄和文件路徑名的抽象表達形式)

文件和目錄路徑名的抽象表示形式。java

用戶界面和操做系統使用與系統相關的路徑名字符串 來命名文件和目錄。此類呈現分層路徑名的一個抽象的、與系統無關的視圖。抽象路徑名 有兩個組件:面試

  1. 一個可選的與系統有關的前綴 字符串,好比盤符,"/" 表示 UNIX 中的根目錄,"\\\\" 表示 Microsoft Windows UNC 路徑名。
  2. 零個或更多字符串名稱 的序列。

抽象路徑名中的第一個名稱是目錄名,對於 Microsoft Windows UNC 路徑名則是主機名。抽象路徑名中第一個名稱以後的每一個名稱表示一個目錄;最後一個名稱既能夠表示目錄,也能夠表示文件。 抽象路徑名沒有前綴和名稱序列。 編程

FIle類中常見方法使用:數組

package file;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/*
 * File: 表明的是 文件與文件夾
 * 
 * 構造函數:
 *         public File(String pathname) : 根據路徑名稱建立一個File對象
 *         public File(String parent, String child) : 根據給定的父路徑 與 給定的子路徑或者文件, 建立一個File對象
 *         public File(File parent, String child) 根據給定的父File對象 與 給定的子路徑或者文件, 建立一個File對象
 */
public class FileDemo {

    public static void main(String[] args) throws IOException {
//        testConstructor();
//        filePractice();
//        testFileDelete();
//        testMethod();
//        testRenameTo();
//        testFileMethod();
        testFileFunction();

    }
    //構造函數練習,注意構造函數只會產生一個file對象,不會產生文件
    public static void testConstructor(){
        //根據路徑名稱建立一個File對象,只是對路徑下內容進行封裝成對象,並無對內容進行操做,不會產生文件
        File file = new File("F:\\IO\\a.txt");
        //根據給定的父路徑 與 給定的子路徑或者文件, 建立一個File對象
        File file1 = new File("F:\\IO", "b.txt");
        //根據給定的父File對象 與 給定的子路徑或者文件, 建立一個File對象
        File f = new File("F:\\IO");
        File file2 = new File(f, "c.txt");
    }
    /*
     * File類中建立功能
     * 
     *         建立文件
     *             public boolean createNewFile() 
     *             若是返回值爲true,原先文件不存在,建立文件
     *             若是返回值爲false,原先文件存在, 不建立文件
     *         建立文件夾
     *             public boolean mkdir()
     *             public boolean mkdirs()
     * 
     * 
     *     絕對目錄: 就是路徑帶盤符
     *     相對目錄:就是路徑不帶盤符,  這個相對目錄的起始位置是當前項目的根目錄
     * 
     *  騎白馬的不必定是王子, 也多是唐僧
     *  建立了File對象後, 具體建立文件仍是文件夾由調用的方法來決定的
     *  
     */
    public static void filePractice() throws IOException{
        File file = new File("F:\\IO\\a.txt");
        boolean b = file.createNewFile();//產生一個新文件,a.txt
        System.out.println("原目錄了中不存在文件返回true,產生一個新文件:"+b);
        File file1 = new File("F:\\IO\\a.txt");
        boolean b1 = file1.createNewFile();
        System.out.println("原目錄中存在文件返回false,不建立文件:"+b1);
        //建立文件夾
        File f1 = new File("F:\\IO\\aa");
        boolean m1 = f1.mkdir();
        System.out.println("原目錄了中不存在文件夾返回true,產生一個新文件:"+m1);
        File f2 = new File("F:\\IO\\aa");
        boolean m2 = f2.mkdir();
        System.out.println("原目錄了中不存在文件夾返回true,產生一個新文件:"+m2);
        //多層文件夾的建立
        //File ff = new File(F:\\IO\\aa\\bb);
        File ff = new File("F:\\IO\\aa");
        File fff = new File("F:\\IO\\aa\\bb");
        ff.mkdir();
        fff.mkdir();
        //上面咱們看到了多層文件夾的建立,那麼是否是有些麻煩呢,在這裏咱們引入另外一種建立方法,
        File fff1 = new File("F:\\IO\\aa\\bb");
        fff1.mkdirs();//此時發現呈現了一樣的效果
        File fi = new File("F:\\IO\\a.txt");
        boolean flag = fi.mkdir();
        //咱們發現建立成功了,只是文件夾的名稱是問價名稱
        System.out.println("調用建立文件夾的方法建立文件:"+flag);
    }
    /*
     * File類的刪除功能:
     *         public boolean delete() : 能夠刪除文件 或 刪除空文件夾
     *         經過java程序刪除的文件 不通過回收站
     */
    public static void testFileDelete() throws IOException{
        File file1 = new File("F:\\IO\\a.txt");
        boolean flag = file1.createNewFile();
        System.out.println("建立文件成功:"+flag);
        boolean flag1 = file1.delete();
        System.out.println("刪除文件是否成功:"+flag1);
        //刪除文件夾,刪除空文件夾,文件夾中若是存在東西,不能直接刪除
        File file2 = new File("F:\\IO\\a.txt");
        boolean flag2 = file2.mkdir();
        System.out.println("建立文件成功:"+flag2);
        boolean flag3 = file2.delete();
        System.out.println("刪除文件是否成功:"+flag3);
        //多層文件夾的刪除
        File fff1 = new File("F:\\IO\\aa\\bb");
        boolean boo = fff1.mkdirs();
        System.out.println("多層文件夾建立成功:"+boo);
        boolean boo1 = fff1.delete();
        //咱們發現刪除多層文件夾時,只能刪除最底層的文件夾
        System.out.println("多層文件夾刪除成功:"+boo1);
    }
    /*
     * File類中的判斷功能:
     *         判斷指定的File是否存在 
     *             public boolean exists()
     *         判斷File是不是文件
     *             public boolean isFile()
     *         判斷File是不是文件夾
     *             public boolean isDirectory()
     *         判斷File是否可讀
     *             public boolean canRead()
     *         判斷File是否可寫
     *             public boolean canWrite()
     *         判斷File是否隱藏
     *             public boolean isHidden()
     *  boolean isAbsolute() 
          測試此抽象路徑名是否爲絕對路徑名。 
     */
    public static void testMethod() throws IOException{
        File file = new File("F:\\IO");
        System.out.println("判斷指定的file是否存在:"+file.exists());
        System.out.println("判斷指定的file是不是文件夾:"+file.isDirectory());
        System.out.println("判斷指定的file是不是文件:"+file.isFile());
        System.out.println("判斷是否可讀:"+file.canRead());
        System.out.println("判斷是否可寫:"+file.canWrite());
        System.out.println("判斷是否可隱藏:"+file.isHidden());
        System.out.println("判斷此抽象路徑是否爲絕對路徑名:"+file.isAbsolute());
        File file2 = new File("F:\\IO\\a.txt");
        file2.createNewFile();
        System.out.println("判斷指定文件是否爲文件:"+file2.isFile());
    }
    /*
     * File類中重命名功能:
     *         public boolean renameTo(File dest)
     *         若是兩個File在同一文件夾下, 重命名功能
     *         若是兩個File再也不同一個文件夾下, 剪切功能而且重命名
     * 若是文件夾中已經存在此文件名文件,那麼更名不成功,
     */
    public static void testRenameTo(){
        File file = new File("F:\\IO\\a.txt");
        File fi = new File("b.txt");
        File fil = new File("F:\\IO\\b.txt");
        boolean b = file.renameTo(fi);
        boolean bb = file.renameTo(fil);
        System.out.println("改文件名字,不在同一文件夾,剪切重命名:"+b);
        System.out.println("改文件名字,在同一文件夾,重命名:"+bb);
    }
    /*
     * File類中獲取功能的基本方法:
     *         獲取文件的絕對目錄:  
     *             public String getAbsolutePath()
     *         獲取文件的相對目錄:
     *             public String getPath()
     *         獲取文件的名字:
     *             public String getName()
     *         獲取文件的大小:
     *             public long length()
     *         獲取文件的最後修改時間:         
     *             public long lastModified()
     * getParent() 
          返回此抽象路徑名父目錄的路徑名字符串;若是此路徑名沒有指定父目錄,則返回 null。
     */
    public static void testFileMethod() throws IOException{
        File file = new File("F:\\IO\\aa.txt");
        file.createNewFile();
        System.out.println("獲取文件的絕對路徑:"+file.getAbsoluteFile());
        System.out.println("獲取文件的相對目錄:"+file.getPath());
        System.out.println("獲取此抽象路徑父目錄的路徑名字字符串,若是此路徑沒有指定父目錄,則返回null:"+file.getParent());
        System.out.println("獲取文件的名字:"+file.getName());
        System.out.println("獲取文件的大小:"+file.length());
        System.out.println("獲取文件的最後修改時間:"+file.lastModified());
        Date date = new Date(1495566380509L);
        System.out.println(date);
    }
    /*
     * File類中獲取功能的高級方法
     *         返回指定目錄下的文件與文件夾
     *             public String[] list()  結果不帶盤符, 返回的數據是String類型
     *             public File[] listFiles() 結果帶盤符, 返回的數據是File類型
     *         列出當前電腦上全部盤符
     *         public static File[] listRoots()
     * 
     */
    public static void testFileFunction(){
        File file = new File("F:");
        //獲取指定目錄下的文件和文件夾,返回字符串數組,結果不帶盤符
        String[] str = file.list();
        for (String string : str) {
            System.out.println("結果不帶盤符:"+string);
        }
        //獲取指定目錄下的文件和文件夾,返回file對象數組,結果帶盤符
        File[] f = file.listFiles();
        for (File file2 : f) {
            System.out.println("結果帶盤符:"+file2);
        }
        //列出當前電腦的全部盤符
        File[] fil = file.listRoots();
        for (File file2 : fil) {
            System.out.println("盤符:"+file2);
        }
    }
}

結果不帶盤符:$RECYCLE.BIN
結果不帶盤符:360CloudUI
結果不帶盤符:360Downloads
結果不帶盤符:BaiduYunDownload
結果不帶盤符:IO
結果不帶盤符:KwDownload
結果不帶盤符:LETVdownload
結果不帶盤符:System Volume Information
結果不帶盤符:經常使用軟件
結果不帶盤符:迅雷下載
結果帶盤符:F:\$RECYCLE.BIN
結果帶盤符:F:\360CloudUI
結果帶盤符:F:\360Downloads
結果帶盤符:F:\BaiduYunDownload
結果帶盤符:F:\IO
結果帶盤符:F:\KwDownload
結果帶盤符:F:\LETVdownload
結果帶盤符:F:\System Volume Information
結果帶盤符:F:\經常使用軟件
結果帶盤符:F:\迅雷下載
盤符:C:\
盤符:D:\
盤符:E:\
盤符:F:\
盤符:T:\緩存

10.1.2 常見操做

過濾文件名

package file;
/*public interface FilenameFilter實現此接口的類實例可用於過濾器文件名。
 * Abstract Window Toolkit 的文件對話框組件使用這些實例過濾 File 類的 list 方法中的目錄清單。 


 * */
import java.io.File;
import java.io.FilenameFilter;

public class MyFileNameFilter implements FilenameFilter{
/*accept
boolean accept(File dir,
               String name)測試指定文件是否應該包含在某一文件列表中。 

參數:
dir - 被找到的文件所在的目錄。
name - 文件的名稱。 
返回:
當且僅當該名稱應該包含在文件列表中時返回 true;不然返回 false。
*/
    @Override
    public boolean accept(File dir, String name) {
        // TODO Auto-generated method stub
        return new File(dir, name).isFile()&&name.endsWith(".java");
    }

}

 

package file;

import java.io.File;
import java.io.FilenameFilter;

/*
 * 需求:輸出指定目錄下的全部.java文件的名稱
 * 
 * 思路:
 *         a: 封裝目錄
 *         b: 獲取全部File對象(包含文件和文件夾)
 *         c: 獲取到每個File對象
 *         d: 判斷該File對象 是不是 文件
 *             是:
 *                 判斷是不是.java結尾的文件
 *                    是: 輸出文件的名字
 *                    否: 無論
 *             否: 無論
 */
public class FileTest {

    public static void main(String[] args) {
        //方式1:
//        test();
        //自定義文件名過濾器
//        test2();
        //匿名內部類
        test3();

    }
    //方式一
    public static void test(){
        File file = new File("E:\\");
        File[] ff = file.listFiles();
        for (File file2 : ff) {
            if(file2.isFile()&&file2.getName().endsWith(".java")){
                System.out.println("指定目錄中後綴爲.java的文件名:"+file2);
            }
        }
    }
    //方式二:自定義文件名過濾器
    public static void test2(){
        File file = new File("E:\\");
        //咱們在這裏使用了自定義文件名過濾器
        File[] file1 = file.listFiles(new MyFileNameFilter());
        for (File file2 : file1) {
            System.out.println("符合規格的文件名:"+file2);
        }
    }
    //方式二:匿名內部類
    /*
    //封裝目錄
    File srcFile = new File("E:\\");
    // 獲取全部File對象(包含文件和文件夾)
    File[]  files = srcFile.listFiles(new MyFilenameFilter());
    
    //獲取到每個File對象
    for (File file : files) {
        //判斷條件不用寫了,由於條件在MyFilenameFilter器中寫好了,獲得的File數組 已是一個過濾後的.java文件結尾的數組了
        // 輸出文件的名字
        System.out.println(file.getName());
    }
    */
    public static void test3(){
        //封裝目錄
        File file = new File("E:\\");
        File[] file1 = file.listFiles(new FilenameFilter() {
            
            @Override
            public boolean accept(File dir, String name) {
                // TODO Auto-generated method stub
                return new File(dir, name).isFile()&&name.endsWith(".java");
            }
        });
        for (File file2 : file1) {
            System.out.println("符合規定的文件名:"+file2);
        }
    }
}
文件名稱的源代碼過濾器解析
//封裝目錄 File srcFile = new File("E:\\"); //獲取全部File對象(包含文件和文件夾) File[] files = srcFile.listFiles(new MyFilenameFilter()); public File[] listFiles(FilenameFilter filter) {// filter -- new MyFilenameFilter() String ss[] = list(); // -- this.list() -- srcFile.list() -- 返回的全部文件夾和文件名稱 if (ss == null) return null; ArrayList<File> files = new ArrayList<>(); for (String s : ss) // s -- 每個文件或者文件夾 if ((filter == null) || filter.accept(this, s)) files.add(new File(s, this)); return files.toArray(new File[files.size()]); } public class MyFilenameFilter implements FilenameFilter { //過濾方法 @Override public boolean accept(File dir, String name) { //dir -- srcFile -- E:\\ //name -- s -- 每個文件或者文件夾 -- Demo.java return new File(dir, name).isFile() && name.endsWith(".java"); } }

修改指定文件夾中文件名

 

package file;

import java.io.File;
import java.io.FilenameFilter;

/*
 * 需求:將指定目錄下全部文件的名稱 更名
 * [www-itcast-cn]專治各類疼痛01.mp4  -->  專治各類疼痛.mp4
 * 
 * 思路:
 *         a: 封裝目錄
 *         b: 找到全部的文件
 *         c: 獲得每個文件
 *         d: 更名 renameTo(File newfile)
 *             建立出新文件的名字
 *                 1: 獲取舊文件的名稱
 *                 2: 獲取新文件的名字
 *                 3: 封裝新文件對象
 *             用新名字 替代 舊名字
 * 
 */
public class FileTest2 {

    public static void main(String[] args) {
        //方式一
        test();

    }
    //方式一:
    public static void test(){
        File file = new File("E:\\");
        File[] str = file.listFiles();
        for (File file2 : str) {
            if(file2.isFile()){
                if(file2.getName().endsWith(".mp4")){
                    //獲取舊文件名字
                    String oldName = file2.getName();
                    //獲取新文件名字
                    String newName = oldName.substring(15, 21)+".mp4";
                    File f = new File(file, newName);
                    file2.renameTo(f);
                }
                
            }
        }
        method();
    }
    //尾綴爲.mp4
    public static void method(){
        File file = new File("E:\\");
        //獲取尾綴爲.mp4的文件
         File[] str = file.listFiles(new FilenameFilter() {
                    
            @Override
            public boolean accept(File dir, String name) {
                // TODO Auto-generated method stub
                return new File(dir, name).isFile()&&name.endsWith(".mp4");
            }
        });
        for (File file2 : str) {
                    System.out.println("符合規格文件名:"+file2);
        }
    }
}

遞歸

package file;
/*
 * 遞歸:方法內部調用本方法
 * 
 *         從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是:
 *             從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                 從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                     從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                         ...
 * 
 *         學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *             學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                 學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                     學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                         。。。
 * 
 * 遞歸使用的時候,可能出現 java.lang.StackOverflowError異常, 內存溢出
 * 使用遞歸的注意事項:
 *         a: 遞歸程序必需要有 出口
 */
public class RecursionDemo {
    private static int a = 3;
    public static void main(String[] args) {
        //沒有出口
//        show();
        //有出口
        show1();
        System.out.println(a);
    }
    public static void show(){
        System.out.println("show方法內部調用本方法,沒有出口!");
        show();
    }
    public static void show1(){
        System.out.println("show方法內部調用本方法,沒有出口!");
        a--;
        System.out.println(a);
        if(a >= 0){
            show1();
        }
    }
}

package file;
/*
 * 遞歸:方法內部調用本方法
 * 
 *         從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是:
 *             從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                 從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                     從前有座山,山裏有個廟,廟裏有一個老和尚,老和尚給小和尚講故事,故事的內容是
 *                         ...
 * 
 *         學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *             學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                 學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                     學習java -- 找工做 -- 娶媳婦 -- 生娃娃 -- 放羊 -- 長大了
 *                         。。。
 * 
 * 遞歸使用的時候,可能出現 java.lang.StackOverflowError異常, 內存溢出
 * 使用遞歸的注意事項:
 *         a: 遞歸程序必需要有 出口
 */
public class RecursionDemo {
    private static int a = 3;
    public static void main(String[] args) {
        //沒有出口
//        show();
        //有出口
//        show1();
//        System.out.println(a);
        System.out.println(factorialMethod(10));
        System.out.println(test(20));
    }
    public static void show(){
        System.out.println("show方法內部調用本方法,沒有出口!");
        show();
    }
    public static void show1(){
        System.out.println("show方法內部調用本方法,沒有出口!");
        a--;
        System.out.println(a);
        if(a >= 0){
            show1();
        }
    }
    /*
     * 需求: 請使用遞歸的方式, 打印出5的階乘
     * 
     * 思路:
     *         5! = 5*4!
     *         4! = 4*3!
     *         3! = 3*2!
     *         2! = 2*1!
     *         1! = 1;
     * 
     * 使用遞歸:
     *         a: 出口條件    1! = 1;
     *         b: 需找規律    n! = n * (n-1)!
     * 
     *     5 * 4 * 3 * 2 * 1 = 120
     * 
     * 
     *  做業: 求 10的階乘
     */
    public static int factorialMethod(int num){
        //出口條件
        //判斷傳入階乘參數爲1,直接返回1,1的階乘爲1
        if(num==1){
            return 1;
        }else if (num==0) {
            return 0;
        }else if (num < 0) {
            System.out.println("對不起請你檢查輸入數字:");
            return 0;
        }else 
            return num*factorialMethod(num-1);
    }
    /*
     * 小兔子的問題 數列  (斐波那契數列)
     *     1,1,2,3,5,8,13,.....
     * 
     * 經過遞歸的方式,獲得第20項的內容
     *                 number:6765
     * 
     * 遞歸:
     *         出口:
     *             知道第一項    1
     *             知道第二項    1
     *         規則:
     *             第N項的值     是N的 前兩項的和
     *             f(n): 表明的第N項的值
     *             N的前一項: f(n-1)
     *             N的前二項: f(n-2)
     * 
     *             f(n) =     f(n-1) + f(n-2)                     
     * 
     */
    public static int test(int num){
        //出口條件
        //判斷傳入參數爲1,直接返回1,
        if(num==1){
            return 1;
        }else if (num==0) {
            return 0;
        }else if (num < 0) {
            System.out.println("對不起請你檢查輸入數字:");
            return 0;
        }else 
            return test(num-1)+test(num-2);
    }
}

package file;

import java.io.File;

/*
 * 需求: 刪除指定目錄下的全部文件
 * 
 * 思路:
 *         a:封裝目錄
 *         b:獲取目錄下全部FIle對象
 *         c:獲取到每個File對象
 *         d:判斷是否爲文件夾
 *             是:遞歸, 調用本方法
 *             否:刪除
 */
public class FileDelete {

    public static void main(String[] args) {
        //建立指定目錄對象
        File file = new File("F:\\src");
        test1(file);
    }
    
    public static void test1(File file){
        //獲取文件目錄
        File[] f = file.listFiles();
        //發現,若是要刪除的文件是受保護的文件或者是系統文件,這個時候,f返回的內容爲null
        //爲了 解決該文件,  在使用前,判斷files數組是否爲空便可。
        if(f != null){
            for (File file2 : f) {
                //判斷文件是否爲文件夾
                if(file2.isDirectory()){
                    //遞歸
                    test1(file2);
                }else {
                    boolean flag = file2.delete();
                    System.out.println("刪除文件成功:"+flag);
                }
            }
        }
        //上面咱們只是把文件夾中的文件刪除了,而文件夾還在,咱們應該怎麼刪除文件夾呢
        System.out.println("刪除文件夾:"+file.getName()+"--"+file.delete());
        
    }

}

刪除文件成功:true
刪除文件成功:true
刪除文件成功:true
刪除文件成功:true
刪除文件成功:true
刪除文件夾:itcast_01--true
刪除文件成功:true
刪除文件成功:true
刪除文件成功:true
刪除文件夾:itcast_02--true
刪除文件成功:true
刪除文件成功:true
刪除文件夾:itcast_03--true
刪除文件夾:cn--true
刪除文件夾:src--true網絡

package file;

import java.io.File;
import java.io.FilenameFilter;

/*
 * 獲取指定目錄下的 全部java文件的絕對路徑(包含子文件夾中的java文件)
 * 
 * 遞歸:
 *         a: 封裝目錄
 *         b: 獲取當前目錄下的全部File對象 
 *         c: 獲取到每個File對象
 *         d: 判斷File 是不是 目錄
 *             是:     遞歸, 回到b的步驟
 *             否:
 *                 判斷是不是java文件
 *                     是:輸出java文件的絕對路徑
 *                     否:無論
 */
public class FileGetAbsolutePath {

    public static void main(String[] args) {
        File file = new File("F:\\src");
        test(file);
    }
    public static void test(File file){
        //獲取指定文件目錄
        File[] f = file.listFiles();
        //系統文件或受保護文件,返回null
        if(f != null){
            //遍歷文件數組
            for (File file2 : f) {
                //判斷是否爲目錄,若是是目錄遞歸,不是獲取絕對路徑
                if(file2.isDirectory()){
                    test(file2);
                }else {
                    if(file2.getName().endsWith(".java"));
                    System.out.println("若是是Java文件,獲取絕對路徑:"+file2.getAbsolutePath());
                }
            }
        }
        
    }
}

若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_01\FileDemo.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_01\FileDemo2.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_01\FileTest.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_01\MyFilenameFilter.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_01\文件名稱過濾器的源代碼解析.txt
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_02\DiGuiDemo.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_02\DiGuiDemo2.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_02\RabbitTest.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_03\DeleteFileTest.java
若是是Java文件,獲取絕對路徑:F:\src\cn\itcast_03\GetFilePathTest.javaapp

10.2 字符流

10.2.1 字符輸出流

package IO.writer;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/*
 * IO流:用來處理各類設備之間數據傳遞問題
 * 
 *         流向分類:
 *             輸入流        
 *             輸出流        
 *         
 *         數據類型:
 *             字節流    
 *                 字節輸入流:    InputStream
 *                 字節輸出流:  OutputStream
 *             字符流
 *                 字符輸入流:    Reader    
 *                 字符輸出流:    Writer
 * 
 *         IO的分類? 答的是數據類型的分類
 * 
 * 需求: 我要把數據寫入到文本文件中   "把紅燈當作猴屁股了" --> fw.txt
 * 
 * 分析:
 *         a: 文本文件 --  字符流
 *         b: 寫入數據 --     輸出流 
 *         綜上所述:  字符輸出流  -- Writer
 * 
 *  發現Writer是抽象類,不能建立對象, 因此使用子類 FileWriter來建立對象
 *  java.lang.Object
          java.io.Writer
              java.io.OutputStreamWriter
                  java.io.FileWriter

 * FileWriter
 *         構造函數:
 *             public FileWriter(File file) : 給定一個File對象, 建立字符輸出流
 *             public FileWriter(String fileName) : 給定一個字符串, 建立字符輸出流
 * 
 * 面試題: 
 *         一、FileWriter fw = new FileWriter("fw.txt",true);
 *             a: 經過系統操做, 若是fw.txt文件不存在,自動給咱們建立出來
 *                若是文件文件fw.txt存在,這時候看第二個參數 是否爲true
 *                 true: 開啓追加模式, 在原有數據的後面添加新數據
 *                 false:就是數據的覆蓋操做,  把原有的內容清空,寫入新的數據
 * 
 *             b: 建立了一個字符輸出流對象
 *             c: 把 字符輸出流對象  指向了 文本文件 fw.txt
 * 
 *         二、請問flush()和close()的區別?
 * 
 *             flush: 使用完畢後, 能夠繼續寫入數據
 *             close:使用完畢後, 流就關閉了,流對象變成了垃圾,不能夠繼續操做
 * 
 * 把大象從冰箱中 拿出來分幾步?
 * 1: 打開冰箱門
 * 2: 拽出大象
 * 3: 關閉冰箱門
 * 
 * 把數據寫入到文件裏 分幾步?
 * 1: 建立字符輸出流對象     FileWriter fw = new FileWriter("fw.txt");
 * 2: 把數據寫入到文件          fw.write();
 * 3: 釋放字符輸出流對象     fw.close();
 */
/*
 * FileWriter: 字符輸出流
 * 
 *  void write(char[] cbuf) 寫入字符數組。 
 *    abstract  void write(char[] cbuf, int startIndex, int len) 寫入字符數組的某一部分。 
 *    void write(int c) 寫入單個字符。 
 *     void write(String str) 寫入字符串。 
 *     void write(String str, int startIndex, int len) 寫入字符串的某一部分。 
 */
/*
 * 小問題:
 *         1: 內容覆蓋了,  我想要的是 內容的追加  構造函數來解決問題
 *             public FileWriter(File file, boolean append)
 *             public FileWriter(String fileName, boolean append)
 * 
 *         2: 我想換行
 *             Windows: \r\n
 *             Linux unix : \n
 *             macOS : \r
 */
public class FileWriterDemo {

    public static void main(String[] args) throws IOException {
        //將指定字符寫入到指定文本
//        testWriter();
        //字符輸出流的練習
//        writerPractice();
        //覆蓋,追加以及換行符的使用
//        writerTest();
        writerException();
    }
    //把給定字符串,寫入到fw.txt文件
    public static void testWriter() throws IOException{
        //建立字符輸出流對象
        File f = new File("F:\\IO\\fw.txt");
        //當咱們給定的目錄中沒有fw.txt文件時,會自動建立,若是存在會根據後面的Boolean值,決定是覆蓋false仍是追加true內容
        FileWriter fw = new FileWriter(f,true);
        //寫入數據
        fw.write("遊曉靜,我會回來的!");
        //此時咱們查看文件發現數據並無被寫入,爲何 數據沒有寫入進去呢?
        //由於咱們使用的字符流,一個字符對應2個字節,文件的基本單位是字節, 咱們不能將2個字節的數據 直接存儲
        //把這些數據 寫入到了  緩衝區中,  怎麼把緩衝區裏內容寫入到文件中呢?  
        // 經過 flush() 把緩衝區的數據,寫入到指定的文件中,flush以後還能夠繼續輸出字符
        fw.flush();
        fw.write("我必定會回來的!");
        //釋放資源
        //close方法只執行前,它會自動的調用一次flush方法
        fw.close();
        //當流被關閉後,再次寫入字符,後出現IOException   Stream closed
        //fw.write("11");
    }
    //字符輸出流的練習
    public static void writerPractice() throws IOException{
        //建立字符讀入流對象
        FileWriter fw = new FileWriter("F:\\IO\\fw.txt", true);
        //建立字符數組,字符串
        char[] ch = {'我','愛','你',',','真','的'};
        String str = "我真的愛你!";
        //寫入字符數組
        fw.write(ch);
        //寫入字符數組一部分,三個參數,字符數組名稱,開始腳標,長度,注意腳標越界異常,第二個參數和第三個參數相加<=數組長度
        fw.write(ch, 2, 4);
        fw.flush();
        //寫入字符串
        fw.write(str);
        //寫入字符串一部分,和上面寫入字符數組同樣,注意腳標越界異常
        fw.write(str, 2, 3);
        fw.flush();
        //寫入單個字符
        fw.write('靜');
        fw.close();
    }
    //覆蓋和追加,以及換行符的運用
    public static void writerTest() throws IOException{
        FileWriter fwC = new FileWriter("F:\\IO\\fw.txt", false);
        //覆蓋操做
        fwC.append('靜');
        fwC.flush();
        FileWriter fwA = new FileWriter("F:\\IO\\fw.txt", true);
        //追加操做
        fwA.append("\r\n");
        fwA.append('靜');
        fwA.flush();
        //循環寫入數據
        for (int i = 0; i < 10; i++) {
            fwA.append("jing");
            fwA.append("\r\n");
            fwA.flush();
        }
        //關閉流,釋放資源,咱們打開了兩個流,因此執行兩次關閉流操做
        fwA.close();
        fwC.close();
    }
    /*
     * FileWriter的異常處理
     */
    public static void writerException(){
        FileWriter fw = null;
        try {
            fw = new FileWriter("F:\\IO\\fw.txt");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            fw.write("靜");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            fw.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //連貫練習
        FileWriter fw1;
        try {
            //使用這種方式建立字符輸出對象,若是已經纔在文檔,默認是覆蓋操做,也就是構造函數第二個參數默認是false
            fw1 = new FileWriter("F:\\IO\\fw.txt");
            fw1.write("奮鬥!");
            fw1.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //終極寫法
        FileWriter fwri = null;
        try {
            fwri = new FileWriter("F:\\IO\\fw.txt");
            fwri.write("奮鬥終生!");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                fwri.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
                
    }
}

 10.2.2 字符輸入流

用來讀取字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩衝區大小都是適當的。要本身指定這些值,能夠先在 FileInputStream 上構造一個 InputStreamReader。ide

FileReader 用於讀取字符流。要讀取原始字節流,請考慮使用 FileInputStream函數

package IO.reader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * 需求: 讀取fw.txt中數據    打印到控制檯(一次讀取一個字符)
 * 
 * 分析: 文本文件: 字符流
 *              讀取數據: 輸入流
 *         綜上所述:  字符輸入流 
 *            
 * FileReader:
 *         構造函數:
 *             public FileReader(File file) : 經過給定的File對象 ,建立一個字符輸入流對象
 *            public FileReader(String fileName): 經過給給定的字符串, 建立一個字符輸入流對象
 *
 *    操做字符輸入流的步驟:
 *    1: 建立字符輸入流對象  (須要注意,使用的文件必需要提早存在)
 *  2: 讀取數據
 *  3: 釋放資源,關閉流對象
 *
 */
/*
 * 需求: 讀取fw.txt中數據    打印到控制檯(一次讀取一個字符數組)
 * 
 * 分析: 文本文件: 字符流
 *              讀取數據: 輸入流
 *         綜上所述:  字符輸入流 
 * 
 * public int read(char[] cbuf)
 * 
 * 
 * 操做字符輸入流的步驟:
 *    1: 建立字符輸入流對象  (須要注意,使用的文件必需要提早存在)
 *  2: 讀取數據
 *  3: 釋放資源,關閉流對象
 *  
 *  
 *  length = fr.read(chs);
 *  length: 本次讀取到的實際字符的個數
 */
public class FileReaderDemo {

    public static void main(String[] args) throws IOException {
        //文件輸入流
//        readerTest();
        //讀取指定字符長度
//        readerPractice();
        //讀取相對路徑下的一個文件,輸出打印
        readerDemo();

    }
    // 讀取fw.txt中數據    打印到控制檯(一次讀取一個字符)
    public static void readerTest() throws IOException{
        //建立字符輸入流對象,若是沒有這個文件會提示FileNotFoundException,文件對象找不到異常
        File file = new File("F:\\IO\\fw.txt");
        FileReader fr = new FileReader(file);
        //fr.read(),一次讀取一個字符,因此沒讀一次能夠輸出一次
        /*返回:  讀取的字符,若是已到達流的末尾,則返回 -1 
         * java遵循unicode編碼,因此每一個字符對應Unicode編碼表中的數字*/
//        int ch = fr.read();
//        System.out.println(ch);
//        int ch1 = fr.read();
//        System.out.println(ch1);
        //實際上,咱們可能讀取的是不少的字符,不多是已知的,也不能每次都System.out,那麼循環就成了最好的解決辦法
        //過渡版本
//        int ch = fr.read();
//        //判斷沒有讀到流的末尾
//        while (ch != -1) {
//            System.out.println(ch);
//            ch = fr.read();
//        }
        //觀察上面的書寫形式咱們發現簡化了不少,可是咱們看到最上邊和最下邊都有讀的操做,這是否是有代碼重複的嫌疑呢,可不能夠只寫一次呢
        //最終版本
        int ch = 0;
        while ((ch = fr.read()) != -1) {
            System.out.println(ch);
        }
        //關閉流,釋放資源
        fr.close();
    }
    //一次讀取多個字符,即讀取字符到字符數組,字符數組是一個讀取到的字符的緩衝區
    public static void readerPractice() throws IOException{
        FileReader fr = new FileReader("F:\\IO\\fw.txt");
        //指定一次讀取字符數組長度
        /*char[] ch = new char[30];
        int length = fr.read(ch);
        System.out.println("輸出自負輸入流讀取到的字符長度"+length);
        System.out.println(String.valueOf(ch, 0, length));
        length = fr.read(ch);
        System.out.println("輸出自負輸入流讀取到的字符長度"+length);
        System.out.println(String.valueOf(ch, 0, length));
        length = fr.read(ch);
        System.out.println("輸出自負輸入流讀取到的字符長度"+length);
        System.out.println(String.valueOf(ch, 0, length));
        length = fr.read(ch);
        System.out.println("輸出自負輸入流讀取到的字符長度"+length);
        System.out.println(String.valueOf(ch, 0, length));
        //使用這種方式的弊端,1,咱們不知道源文件的字符長度,因此不知道該有多少輸出語句,因此當流讀取到末尾繼續讀會java.lang.StringIndexOutOfBoundsException,由於讀取返回-1,而數組是沒有腳本爲-1的
        length = fr.read(ch);
        System.out.println("輸出自負輸入流讀取到的字符長度"+length);
        System.out.println(String.valueOf(ch, 0, length));*/
        //經過操做上面咱們知道這種方式既繁瑣,又不可取,那麼咱們如今就要考慮一下循環了
    /*    char[] ch = new char[30];
        int length = fr.read(ch);
        while (length != -1) {
            System.out.println("讀取到的長度:"+length);
            System.out.println(String.valueOf(ch, 0, length));
            //注意這裏咱們有時會忘記把讀取到的長度賦值給length,這會形成死循環
            length = fr.read(ch);
        }*/
        //上面的代碼咱們仍能看出,冗餘
        char[] ch = new char[1024];// 指定一次讀取字符的個數 1024表明一次最多能夠讀取1024個字符,一般開發中寫成1024的整數倍
        int length = 0;
        while ((length = fr.read(ch)) != -1) {
            System.out.println("讀取到的字符長度:"+length);
            System.out.println(String.valueOf(ch, 0, length));
        }
        //關閉流,釋放資源
        fr.close();
    }
    /*
     * 將FileWriterDemo.java文件中的內容 獲取出來, 在控制檯打印(一次獲取一個字符)
     * 
     * 操做字符輸入流的步驟:
     * 1: 建立字符輸入流對象
     * 2: 讀取數據
     * 3: 釋放資源
     */
    public static void readerDemo() throws IOException{
        FileReader fr = new FileReader("src/IO/writer/FileWriterDemo.java");
        char[] ch = new char[1024];
        int length = 0;
        while ((length = fr.read(ch)) != -1) {
            System.out.println("讀取到的字符長度:"+length);
            System.out.println(String.valueOf(ch, 0, length));
        }
        //關閉流,釋放資源
        fr.close();
    }
}

 

10.2.3 字符輸入流和字符輸出流的合併聯繫--即複製 粘貼的操做

package IO.reader;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*  FileWriterDemo.java 裏面的內容, 寫入到 E:\\Demo.java中
*  
*  思路:
*      a: 數據源 -- 獲取數據 -- 輸入流 -- Reader -- FileReader -- FileWriterDemo.java
*      b: 目的地 -- 寫入數據 -- 輸出流 -- Writer -- FileWriter -- E:\\Demo.java
*      c: 建立字符緩衝區  1024大小
*      d: 經過循環操做,進行數據的讀取與 寫入
*          先讀數據
*          再寫數據
*      e: 釋放資源    
*  
*/
public class FileReaderToWriterDemo {

    public static void main(String[] args) throws IOException {
        test();

    }
    public static void test() throws IOException{
        //建立源文件輸入流對象和輸出流對象
        FileReader fr = new FileReader("F:\\IO\\fw.txt");
        FileWriter fw = new FileWriter("F:\\IO\\f.txt");
        char[] ch = new char[1024];
        int length = 0;
        while ((length = fr.read(ch)) != -1) {
            fw.write(ch, 0, length);
        }
        fr.close();
        fw.close();
    }
}

 

10.3 字節流

10.3.1 字節輸入流

package IO.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * FileInputStream : 用於讀取諸如圖像數據之類的原始字節流
 * 
 *  字節輸入流的操做步驟:
 *      a: 建立字節輸入流對象
 *      b: 獲取數據
 *      c: 釋放資源
 */
public class FileInputStreamDemo {

    public static void main(String[] args) throws IOException {
        //字節流的入手
        fileInputStreamTest();

    }
    //字節輸入流的入手
    public static void fileInputStreamTest() throws IOException{
        FileInputStream fis = new FileInputStream("F:\\IO\\io\\b.txt");
        //方式一:一次讀取一個字節
//        int ch = 0;
//        while ((ch=fis.read()) != -1) {
//            System.out.println(ch);
//        }
        //方式二:一次讀取必定長度的字節數組
        byte[] b = new byte[1024];
        int length = 0;
        while ((length = fis.read(b)) != -1) {
            System.out.println("字節長度"+length);
            System.out.println("獲得字節數組的一部分:"+new String(b, 0, length));
        }
        //關閉流,釋放資源
        fis.close();
    }
}

10.3.2 字節輸出流

package IO.FileOutPutStream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * IO流
 *         字符流
 *             字符輸入流 -- Reader
 *             字符輸出流 -- Writer
 *         字節流
 *             字節輸入流 -- InputStream
 *             字節輸出流 -- OutputStream
 * 
 *  需求: 使用字節輸出流  向文本文件中寫入 數據
 * 
 *  FileOutputStream :用於寫入諸如圖像數據之類的原始字節的流
 *      寫入數據:
 *            public abstract void write(int b) :  寫入一個字節
 *          public void write(byte[] b) : 寫入一個字節數組
 *            public void write(byte[] b,int off, int len) 寫入一個字節數組的一部分

 *  
 *  使用字節輸出流的步驟:
 *      a: 建立字節輸出流對象
 *      b: 寫入數據
 *      c: 釋放資源
 */
public class FileOutputStreamDemo {

    public static void main(String[] args) throws IOException {
        //字節輸出流入手
        fileOutputStreamDemo();

    }
    public static void fileOutputStreamDemo() throws IOException{
        FileOutputStream fos = new FileOutputStream("F:\\IO\\Demo.java");
        //寫入一個字節
        fos.write(97);
        fos.flush();
        //寫入一個字節數組
        byte[] b = new byte[]{97,98,99,100,101};
        fos.write(b);
        fos.flush();
        //寫入字節數組的一部分,三個參數爲字節數組   寫去字節數組起始腳標   寫入長度
        fos.write(b, 0, 3);
        fos.flush();
        //字符串寫入---字符串轉換成字節數組
        fos.write("mnbvc".getBytes(), 0, "abcde".length());
        fos.flush();
        fos.close();
    }
}

 

10.3.3 字節輸入輸出流的聯合聯繫,複製粘貼(注意:複製粘貼意味着哪怕目的地已經有同名文件也會覆蓋)

package IO.FileOutPutStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileOutputStreamTest {

    public static void main(String[] args) throws IOException {
        //複製圖片
//        imgTest();
        //複製音樂
//        mp3Test();
        //測試字符流操做非字符內容---不可行
//        charStreamTest();
        //測試字節流操做文檔---可行
        byteStreamTest();
    }
    /*
     * 使用字節流  複製照片
     *  須要: 把 F:\\360wallpaper.jpg 複製到 項目根目錄下的 copy.bmp
     *  數據源: F:\\360wallpaper.jpg -- 字節輸入流 -- FileInputStream
     *  目的地: copy.bmp -- 字節輸出流  -- FileOutputStream
     */
    public static void imgTest() throws IOException{
        //數據源
        FileInputStream fis = new FileInputStream("F:\\360wallpaper.jpg");
        //目的地
        FileOutputStream fos = new FileOutputStream("copy.bmp");
        //定義一個字節數組,做爲每次讀和寫的長度標準
        byte[] b = new byte[5];
        int length = 0;
        while ((length = fis.read(b))!= -1) {
            fos.write(b, 0, length);
        }
        fis.close();
        fos.close();
    }
    /*
     * 需求: 把 F:\\重案六組1.mp4  拷貝  到 項目跟目下  小蘋果.mp4中
     *  數據源:F:\\重案六組1.mp4 -- 字節輸入流 -- FileInputStream
     *  目的地:    小蘋果.mp4 -- 字節輸出流 -- FileOutputStream
     */
    public static void mp3Test() throws IOException{
        FileInputStream fis = new FileInputStream("F:\\重案六組1.mp4");
        FileOutputStream fos = new FileOutputStream("小蘋果.mp4");
        //定義一個字節數組,做爲緩存
        byte[] b = new byte[1024];
        int length = 0;
        while ((length = fis.read(b))!= -1) {
            fos.write(b, 0, length);
        }
        //關閉流,釋放資源
        fis.close();
        fos.close();
    }
    /*
     * 問: 
     *         字節流  能操做,文本文件嗎?  
     *         能
     * 
     *         測試: 字符流 能操做,非文本文件(圖片、音視頻)嗎?
     *         不能,會出現數據的丟失,致使文件損壞
     * 
     *         字節流: 用於讀取、寫入諸如圖像數據之類的原始字節流(圖片、音視頻)  二進制文件
     *         字符流:用來讀取、寫入字符文件的便捷類(文本文件)
     *  --------------------------
     *  使用字符流   複製照片
     *  須要: 把  F:\\360wallpaper.jpg 複製到 項目根目錄下的 copy.bmp
     *  數據源: F:\\360wallpaper.jpg -- 字符輸入流 -- FileReader
     *  目的地: copy.bmp -- 字符輸出流  -- FileWriter
     */
    public static void charStreamTest() throws IOException{
        //建立字符輸入流和字符輸出流
        FileReader fr = new FileReader("F:\\360wallpaper.jpg");
        FileWriter fw = new FileWriter("copy1.bmp");
        //定義字符數組,做爲緩存
        char[] ch = new char[1024];
        int length = 0;
        while ((length = fr.read(ch))!= -1) {
            //fw.write(String.valueOf(ch), 0, length);
            fw.write(ch, 0, length);
        }
        fr.close();
        fw.close();
        System.out.println("經過操做咱們看到,項目根目錄下出現了copy1.bmp,可是打開的時候卻不能正常觀看,這說明字符流操做非字符內容形成數據丟失");
    }
    /*
     * 需求:把 F:\\Demo.java中的內容     拷貝到 項目根目錄下的 copy.java中
     * 數據源:F:\\Demo.java -- 字節輸入流 -- InputStream -- FileInputStream    
     * 目的地: copy.java -- 字節輸出流 -- OutputStream -- FileOutputStream 
     */
    public static void byteStreamTest() throws IOException{
        FileInputStream fis = new FileInputStream("F:\\Demo.java");
        FileOutputStream fos = new FileOutputStream("Demo.java");
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b))!= -1) {
            fos.write(b, 0, len);
        }
        fis.close();
        fos.close();
    }
}

 

10.4 緩衝流

10.4.1 字節緩衝流

10.4.1.1 字節輸入緩衝流

package IO.BufferedInputStream;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * (高效)字節緩衝輸入流:BufferedInputStream
 * 
 * 使用高效的流 : 來讀取指定文件中的數據
 * 
 * (高效)字節緩衝輸入流操做步驟:
 *         a:建立 (高效)字節緩衝輸入流 對象
 *         b:讀取數據
 *         c:釋放資源
 */
public class BufferedInputStreamDemo {

    public static void main(String[] args) throws IOException {
        bufferInputStreamTest();

    }
    public static void bufferInputStreamTest() throws IOException{
        //a:建立 (高效)字節緩衝輸入流 對象
        //public BufferedInputStream(InputStream in)
        //InputStream is = new FileInputStream("bos.txt");
        //BufferedInputStream bis = new BufferedInputStream(is);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\Demo.java"));
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = bis.read(b))!= -1) {
            System.out.println("讀取的長度:"+len);
            System.out.println("讀取到的內容:"+(new String(b, 0, len)));
        }
        bis.close();
    }
    
}

10.4.1.2 字節輸出緩衝流

package IO.BufferedOutputStream;

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * java中 提供了 高效的流
 * 
 *         數據類型分類:
 *             字節流:
 *                 字節輸入流: InputStream
 *                     (高效)字節緩衝輸入流:BufferedInputStream        
 *                 字節輸出流: OutputStream
 *                     (高效)字節緩衝輸出流: BufferedOutputStream
 *             字符流:
 *                 字符輸入流: Reader
 *                     (高效)字符緩衝輸入流: BufferedReader
 *                 字符輸出流: Writer
 *                     (高效)字符緩衝輸出流: BufferedWriter
 * 
 *  使用高效的流 : 來完成數據寫入到 文件中
 *  
 *  需求:使用字節高效的流, 向文本文件中 寫入 字節數據 
 *      (高效)字節緩衝輸出流
 *  
 *      a: 建立 (高效)字節緩衝輸出流對象
 *      b: 寫入數據
 *      c: 釋放資源
 */
public class BufferedOutputStreamDemo {

    public static void main(String[] args) throws IOException {
        bufferedOutputStreamTest();

    }
    public static void bufferedOutputStreamTest() throws IOException{
        //建立 (高效)字節緩衝輸出流對象
        //public BufferedOutputStream(OutputStream out)
        //OutputStream os = new FileOutputStream("bos.txt");
        //BufferedOutputStream bos = new BufferedOutputStream(os);
        //建立字節緩衝流對象,設置當文件存在時,追加不覆蓋
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:\\Demo.java", true));
        //要輸出的字節
        byte[] b = new byte[]{97,98,99,100,101,102};
        bos.write(b, 0, b.length);
        bos.close();
    }
}

10.4.1.3 字節輸出輸入緩衝流聯合聯繫

package IO.BufferedOutputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedInputOutputStreamTest {

    public static void main(String[] args) throws IOException {
        //圖片複製
//        imgTest();
        //文檔複製
//        fileTest();
        Long start = System.currentTimeMillis();
//        test1();
//        test2();
//        test3();
        test4();
        Long end = System.currentTimeMillis();
        Long time = end-start;
//        System.out.println("普通流一次一個字節共耗時:"+time);106782
//        System.out.println("普通流一次一個字節數組共耗時:"+time);148
//        System.out.println("高效流一次一個字節共耗時:"+time);1076
//        System.out.println("高效流一次一個字節數組共耗時:"+time);113

    }
    /*
     *     使用字符緩衝流  複製文本文件
     *  須要: 把 F:\360wallpaper.jpg 複製到 項目根目錄下的 copy.bmp
     *  數據源:F:\360wallpaper.jpg -- 字節輸入流 -- FileInputStream -- BufferedInputStream
     *  目的地: copy.bmp -- 字節輸出流  -- FileOutputStream -- BufferedOutputStream
     */
    public static void imgTest() throws IOException{
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\360wallpaper.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.bmp"));
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = bis.read(b)) != -1) {
            bos.write(b, 0, len);
        }
        bis.close();
        bos.close();
    }
    /*
     * 使用字節緩衝流
     * 需求:把 F:\\Demo.java中的內容     拷貝到 項目根目錄下的 copy.java中
     * 數據源: F:\\Demo.java -- 字節輸入流 -- 字節緩衝輸入流 -- BufferedInputStream 
     * 目的地:copy.java -- -- 字節輸出流 -- 字節緩衝輸出流  -- BufferedOutputStream
     */
    public static void fileTest() throws IOException{
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\Demo.java"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("demo.java"));
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = bis.read(b))!= -1) {
            bos.write(b, 0, len);
        }
        bis.close();
        bos.close();
    }
    /*
     *  經過四種方式,複製視頻文件
     *  
     *  把F:\\重案六組1.mp4 拷貝到  項目根目錄下  copy.mp4
     *  看4種方式的效率
     *  
     *  數據源:    F:\\重案六組1.mp4
     *  目的地:    copy.mp4
     *  
     *  字節流
     *      普通的流: 
     *          一次一個字節        共耗時:133065 毫秒
     *          一次一個字節數組    共耗時:          213 毫秒
     *      高效的流:
     *          一次一個字節        共耗時:      1050 毫秒
     *          一次一個字節數組    共耗時:             65 毫秒
     */
    public static void test1() throws IOException{
        //建立字節流對象
        FileInputStream fis = new FileInputStream("F:\\重案六組1.mp4");
        FileOutputStream fos = new FileOutputStream("copy.mp4");
        int len = 0;
        while ((len = fis.read())!= -1) {
            fos.write(len);
        }
        //關閉流,釋放資源
        fis.close();
        fos.close();
    }
    public static void test2() throws IOException{
        //建立字節流對象
        FileInputStream fis = new FileInputStream("F:\\重案六組1.mp4");
        FileOutputStream fos = new FileOutputStream("copy.mp4");
        //定義讀取字節長度數組
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b))!= -1) {
            fos.write(b, 0, len);
        }
        //關閉流,釋放資源
        fis.close();
        fos.close();
    }
    public static void test3() throws IOException{
        //建立字節緩衝流對象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\重案六組1.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
        //定義int類型變量做爲字節輸入流讀取的字節
        int len = 0;
        while ((len = bis.read())!=-1) {
            bos.write(len);
        }
        bis.close();
        bos.close();
    }
    public static void test4() throws IOException{
        //建立字節緩衝流對象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\重案六組1.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
        byte[] b = new byte[1024];
        //定義int類型變量做爲字節輸入流讀取的字節長度
        int len = 0;
        while ((len = bis.read(b))!=-1) {
            bos.write(b, 0, len);
        }
        bis.close();
        bos.close();
    }
}

 

10.4.2 字符緩衝流

10.4.2.1 字符輸入緩衝流

package IO.BufferedReader;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
 * BufferedReader
 *         public String readLine() : 讀取一行文本內容,可是不包含換行符
 *
 *    把 Demo.java中的 數據 讀取出來 (使用BufferedReader的特有方法 readLine() )
 *
 *    高效的字符緩衝輸入流的操做步驟:
 *        a: 建立字符緩衝輸入流對象
 *        b: 讀取數據
 *        c: 釋放資源
 */
public class BufferedReaderDemo {

    public static void main(String[] args) throws IOException {
        bufferedReaderTest();

    }
    public static void bufferedReaderTest() throws IOException{
        //建立字符輸入緩衝流對象
        BufferedReader br = new BufferedReader(new FileReader("F:\\Demo.java"));
        //讀取數據
        // String line = br.readLine();
        // System.out.println(line);
        //
        // line = br.readLine();
        // System.out.println(line);
        //
        // line = br.readLine();
        // System.out.println(line);
        //
        // line = br.readLine();
        // System.out.println(line);
        //定義字符串對象做爲字符輸入緩衝流對象讀取後返回的行
        String line = null;
        while ((line = br.readLine())!= null) {
            System.out.println(line);
        }
        br.close();
    }

}

10.4.2.2 字符輸出緩衝流

package IO.BufferedWriter;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/*
 * BufferedWriter:
 *         public void newLine() : 換行符
 * 
 * BufferedWriter寫入數據的三部曲:
 *         write();
 *         newLine();
 *         flush();
 * flush() 
          刷新該流的緩衝。 
 void newLine() 
          寫入一個行分隔符。 

 * 向文本文件中寫入指定的數據
 * 
 * 數據源:
 *         數據
 * 目的地:
 *         文本文件
 * 
 * 操做 高效 字符緩衝輸出流的步驟:
 *     a: 建立字符緩衝輸出流對象
 *     b: 寫入數據
 *     c: 釋放資源
 */
public class BufferedWriterDemo {

    public static void main(String[] args) throws IOException {
        bufferedWriterTest();

    }
    public static void bufferedWriterTest() throws IOException{
        //建立字符輸出緩存流的對象,指定目錄中沒有文件會先建立文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\Demo.txt"));
        //寫入數據
        bw.write("Hello");
        //換行
        bw.newLine();
        //刷新該留=流的緩衝
        bw.flush();
        //循環輸入
        for (int i = 0; i < 10; i++) {
            bw.write("人間正道是滄桑!");
            bw.newLine();
            bw.flush();
        }
        //關閉流
        bw.close();
    }
}

10.4.2.3 字符緩衝流練習

package IO.BufferedWriter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/*
 * 使用高效的字符緩衝流, 來 拷貝文件
 * 需求:把 F:\\Demo.java中的內容     拷貝到 項目根目錄下的 copy.java中
 * 數據源:F:\\Demo.java -- 字符輸入流 -- 字符緩衝輸入流 -- BufferedReader
 * 目的地:  copy.java -- 字符輸出流  -- 字符緩衝輸出流 -- BufferedWriter
 */
public class BufferedReaderWriterDemo {

    public static void main(String[] args) throws IOException {
        test();

    }
    public static void test() throws IOException{
        //建立字符緩衝流
        BufferedReader br = new BufferedReader(new FileReader("F:\\Demo.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("copy.java"));
        byte[] b = new byte[1024];
        String line = null;
        while ((line = br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        //關閉流
        br.close();
        bw.close();
    }
}

 10.4.3 中間流

package IO.inputStreamReader;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/*
 * InputStreamReader 是字節流通向字符流的橋樑
 * InputStreamReader(InputStream in) 
          建立一個使用默認字符集的 InputStreamReader。
 * 
 * 需求: 經過鍵盤輸入數據, 寫入到 abc.txt 文本文件中 (使用轉換流)
 * 
 * 數據源:
 *         鍵盤輸入    -- System.in -- InputStream -- 
 *                     <--  InputStreamReader -->
 *                     -- BufferedReader --readLine()
 * 目的地:
 *          abc.txt  文本文件
 */
public class InputStreamReaderDemo {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
//        test1();
        test2();
    }
    public static void test1() throws IOException{
        //建立數據源流
        InputStream is = System.in;
        //建立中間流
        InputStreamReader isr = new InputStreamReader(is);
        //建立字符緩衝流
        BufferedReader fr = new BufferedReader(isr);
        BufferedWriter bw = new BufferedWriter(new FileWriter("abc.txt"));
        String line = null;
        while ((line = fr.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        is.close();
        isr.close();
        fr.close();
        bw.close();
    }
    //咱們看到上邊的代碼,會有這麼幾個疑問,1開了這麼多流,四次關閉流,麻煩,2,窗口輸入也沒有一個判斷何時終止
    public static void test2() throws IOException{
        //建立字節流轉換爲字符緩衝流的流
        //InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new FileWriter("abc.txt"));
        String line = null;
        while ((line = br.readLine())!= null) {
            if ("911".equals(line)) {
                break;
            } else {
                bw.write(line);
                bw.newLine();
                bw.flush();
            }
        }
        //關閉流
        br.close();
        bw.close();
    }
}
package IO.outputStreamWriter;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;

/*
 * OutputStreamWriter 是字符流通向字節流的橋樑
 * 
 * 把 abc.txt 內容 讀取出來, 輸出(使用轉換流)
 * 
 * 數據源
 *          FileInputStreamDemo.java -- 輸入流 -- BufferedReader
 *          br.readLine();
 * 目的地:
 *                      字符流            <-- 把字節流轉換成字符流       <-- 字節流            <-- 控制檯輸出打印
 *          BufferedWriter <-- OutputStreamWriter <-- OutputStream <-- System.out
 *             
 *          bw.write(line);
 *          bw.newLine();
 *          bw.flush();
 * 
 * 使用上 與  理解上的區別?
 *         
 *         理解上:  字符流  --> 字節流
 *         使用上:  字符流 <-- 字節流
 *     
 */
public class OutputStreamWriterDemo {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        test();
        
    }
    public static void test() throws IOException{
        //目的源   字符緩衝流對象
        BufferedReader br = new BufferedReader(new FileReader("abc.txt"));
        //字符流            <-- 把字節流轉換成字符流       <-- 字節流            <-- 控制檯輸出打印
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String line = null;
        char[] ch = new char[1024];
        while ((line = br.readLine())!=null) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        //關閉流
        br.close();
        bw.close();
    }
}

 

10.5 編碼

package encode;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class EncodeDemo {

    public static void main(String[] args) throws IOException {
        //IO流的編碼
        encodeIO();
        //字符串編碼
        encodeString();
        
    }
    /*
     * IO流的編碼
     * 需求: 
     *         一、使用gbk編碼表 將數據寫入到demo.txt 文件中
     *         二、使用gbk編碼表,將demo.txt文件中的數據獲取出來
     * 編碼:
     * OutputStreamWriter(字符-->字節)
     *         public OutputStreamWriter(OutputStream out,Charset cs)
     * 解碼:
     * InputStreamReader(字節--> 字符)
     *         public InputStreamReader(InputStream in,Charset cs)
     */
    public static void encodeIO() throws IOException{
        //解碼操做---看得懂的轉爲看不懂的字節碼
        InputStreamReader fis = new InputStreamReader(new FileInputStream("demo.java"),"gbk");
        //編碼操做---把看不懂的字節碼按照編碼規則編爲看得懂的字符
        OutputStreamWriter fos = new OutputStreamWriter(new FileOutputStream("demo.txt"),"utf-8");
        int len = 0;
        char[] ch = new char[1024];
        while ((len = fis.read(ch))!= -1) {
            System.out.println(String.valueOf(ch, 0, len));
            fos.write(ch, 0, len);
        }
        fis.close();
        fos.close();
    }
    /*
     * 字符編碼
     * 編碼: 把能看懂的,變成看不懂的
     * 解碼:把看不懂, 變成看懂的
     * 常見的編碼表:
     *         ASCII碼錶: 用7位字節來存儲數據
     *         ISO-8859-1: 西歐編碼,用8位字節來存儲數據
     *         GB2312: 簡體中文
     *         GBK:
     *         GB18030:
     *         BIG5: 臺灣,繁體中文
     *         Unicode: 統一碼
     *             utf-8: 用1-4字節來存儲數據的,具體每一個數據使用一、二、三、4個字節的哪個,要看國家區域來決定
     * 編碼:
     *         public byte[] getBytes(Charset charset): 使用給定的編碼表 進行編碼
     * 解碼:
     *         public String(byte[] bytes, Charset charset): 使用給定的編碼表,進行解碼
     * 注意事項:
     *         編碼與解碼操做,使用的編碼表要求統一
     */
    public static void encodeString(){
        //建立字符串,用於做爲字符編碼的模板
        String str = "我是一個兵,保衛老百姓!";
        try {
            //使用給定的格式進行編碼,看懂的編程看不懂得了
            byte[] b = str.getBytes("utf-8");
            //編碼上下要一致,不然會出現亂碼
            System.out.println("使用該定的編碼表進行解碼(看不懂的變成看懂的了):"+new String(b,"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

 

10.6 文檔複製粘貼

單層文檔複製

package IO.practice;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 複製 單層文件夾
 * 
 * 需求: 把F:\IO\io文件夾 複製到 項目的跟目錄  copy文件夾
 * 
 * 數據源:F:\IO\io -- 字節流 -- 字節輸入流 -- FileInputStream -- BufferedInputStream
 *          
 * 目的地: copy -- 字節流 -- 字節輸出流 -- FileOutputStream -- BufferedOutputStream
 * 
 * 思路:
 *     a:封裝數據源
 *     b:建立目的地文件夾,封裝目的地
 *     c:獲取 數據源 中全部File對象
 *  d:遍歷,獲取到每個File對象
 *  e:複製
 *      設置新文件路徑
 *      複製文件
 */
public class CopyDirectory {

    public static void main(String[] args) {
        //複製單層目錄下的文件
        fileTest();

    }
    //封裝數據源,獲得每個file文件
    public static void fileTest(){
        //封裝數據源目錄對象
        File file = new File("F:\\IO\\io");
        //封裝目的地目錄對象,建立目的地文件
        File file1 = new File("copy");
        file1.mkdir();
        //獲取源目錄
        File[] ff = file.listFiles();
        //遍歷每一個文件,獲取目的地文件
        for (File file2 : ff) {
            //目的地文件名封裝對象
            String name = file2.getName();
//            System.out.println(name);
            File dest = new File(file1, name);
            //複製文件,兩個參數,一個是源文件,一個是目的地文件
            try {
                copyFile(file2, dest);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            
    }
    //複製文件,兩個參數,一個是源目錄封裝對象,一個是目的地文件封裝對象
    public static void copyFile(File srcFile,File destFile) throws IOException{
        //由於不知道要複製的是文本仍是其餘,因此選擇字節緩衝流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        //設置byte數組做爲每次讀取字節的長度
        byte[] b = new byte[1024];
        int len = 0;
        //讀寫操做
        while ((len = bis.read(b))!= -1) {
            bos.write(b, 0, len);
        }
        //關閉流,釋放資源
        bis.close();
        bos.close();
        System.out.println("複製完畢!");
    }
}

 

多層文檔複製

package IO.practice;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/*
 * 複製  多層文件夾
 * 
 * 把 E:\\day20副本 全部內容  複製到  項目根目錄  副本  文件夾中
 * 
 * 數據源:E:\\day20副本
 * 
 * 目的地: 副本
 * 
 * 思路:
 *         一、封裝數據源
 *         二、封裝目的地
 *         三、建立目的地文件夾
 *         四、獲取數據源中全部File對象
 *         五、遍歷,獲取到每個File對象
 *         六、判斷File對象 是否爲 文件夾
 *             是:    
 *                 遞歸,調用本方法,回到第3步
 *             否:
 *                 封裝新文件的路徑
 *                 複製文件    
 */
public class CopyDirectories {

    public static void main(String[] args) {
        //封裝源路徑對象    目的地父文檔
        File srcFile = new File("F:\\IO");
        File dest = new File("copyIO");
        //複製文件夾
        try {
            copyDirectory(srcFile, dest);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //f封裝源路徑對象,目的地路徑對象
    public static void copyDirectory(File srcFile, File dest) throws IOException{
        //建立目的地父文檔
        dest.mkdir();
        //遍歷源路徑目錄
        File[] file = srcFile.listFiles();
        for (File file2 : file) {
            //獲取名稱
            String name = file2.getName();
            //目的地文件或文件夾
            File destFile = new File(dest, name);
            //判斷是否爲文件夾
            if(file2.isDirectory()){
                //若是是文件夾,那麼遞歸調用,建立文件夾            
                //複製文件夾,源文件夾file2,目的地文件夾destFile
                copyDirectory(file2, destFile);
                //若是不是文件夾,執行復制,兩個參數,源文件,目的地文件
            }else {
                //封裝目的地文件新路徑
                copyFile(file2,destFile);
            }
        }
    }
    //複製文件,兩個參數,一個是源目錄封裝對象,一個是目的地文件封裝對象
    public static void copyFile(File srcFile,File destFile) throws IOException{
        //由於不知道要複製的是文本仍是其餘,因此選擇字節緩衝流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        //設置byte數組做爲每次讀取字節的長度
        byte[] b = new byte[1024];
        int len = 0;
        //讀寫操做
        while ((len = bis.read(b))!= -1) {
            bos.write(b, 0, len);
        }
        //關閉流,釋放資源
        bis.close();
        bos.close();
        System.out.println("複製完畢!");
    }

}

 

10.7 集合和文件之間的轉換

package IO.listAndFile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import IO.Student;

/*
 * 把文件中的數據 讀取出來, 存儲集合中
 * 數據源:文件  bw.txt
 * 目的地:集合
 * 思路:
 *         封裝數據源  
 *         建立集合對象
 *         讀取數據源中的數據
 *         把數據存儲到集合
 * 
 * 把集合中的數據 寫入到文件
 * 數據源:集合
 * 目的地:文件
 * 思路:
 *         建立集合對象
 *         添加元素到集合
 *         建立目的地(File)
 *         把集合中的數據  寫入到 文件
 */
public class ListAndFileChange {

    public static void main(String[] args) {
        //文件轉變爲集合
        try {
            FileToList();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //集合轉變爲文件
        try {
            listToFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //集合中存放對象,存放到文件中的是對象的地址
        try {
            ListObjectToFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    //文件轉變爲集合
    public static void FileToList() throws IOException{
        //封裝數據源對象
        File srcFile = new File("demo.txt");
        //建立集合對象,做爲文件存儲的集合
        List<String> list = new ArrayList<>();
        //建立字節輸入流,咱們要考慮編碼,因此字節更容易控制
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        //建立字符輸入緩衝流,讀取文件
//        BufferedReader br = new BufferedReader(new FileReader(srcFile));
        String line = null;
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = bis.read(b))!=-1) {
            String str = new String(b, "utf-8");
            list.add(str);
        }
        //關閉流,釋放資源
        bis.close();
        arrayListItrator(list);
    }
    //集合轉變爲文件,這裏使用字節緩存流,可使用字符緩衝流
    public static void listToFile() throws IOException{
        //建立集合做爲源文件
        List<String> list = new ArrayList<>();
        list.add("張三");
        list.add("李四");
        list.add("王二麻子");
        //建立目的地文件,做爲寫入
        File destFile = new File("abc.txt");
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        Iterator<String> iter = list.iterator();
        for (String string : list) {
            byte[] b = string.getBytes();
            bos.write(b);
        }
        bos.close();
    }
    //若是集合中存儲的是對象,那麼會在文件中存儲什麼呢
    public static void ListObjectToFile() throws IOException{
        //建立集合做爲源文件
        List<Student> list = new ArrayList<>();
        Student s1 = new Student(17, "王五");
        Student s2 = new Student(16, "張三");
        list.add(s1);
        list.add(s2);
        //建立目的地文件,做爲寫入
        File destFile = new File("abc.txt");
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        Iterator<Student> iter = list.iterator();
        for (Student stu : list) {
            byte[] b = stu.toString().getBytes();
            bos.write(b);
        }
        bos.close();
    }
    
    //遍歷集合
    public static void arrayListItrator(List<String> list){
        Iterator<String> iter = list.iterator();
        for (String string : list) {
            System.out.println("集合中的元素:"+string);
        }
    }
}

10.8 打印流

package IO.print;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterDemo {

    public static void main(String[] args) {
        //打印流   字符流
        try {
            printTest();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //打印流  方法
        try {
            printMethod();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //打印流  println
        try {
            printlnMethodAndAutoFlush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //複製指定源文件到目的地文件
        try {
            printWriterDemo();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    /*
     * 打印流
     * PrintWriter: 字符打印輸出流
     * PrintStream: 字節打印輸出流
     * 把數據寫到如文件
     */
    public static void printTest() throws IOException{
        //建立字符打印輸出流
        PrintWriter pw = new PrintWriter("abc.txt");
        //寫入
        pw.write("PrintWriter: 字符打印輸出流");
        pw.write("\r\n");
        pw.write("PrintWriter: 字符打印輸出流");
        //釋放資源
        pw.close();
    }
    /*
     * 打印流的特有方法
     *         print() 能夠打印各類數據類型的數據
     */
    public static void printMethod() throws IOException{
        //建立字符打印輸出流
        PrintWriter pw = new PrintWriter("abc.txt");
        //寫入
        pw.write("PrintWriter: 字符打印輸出流");
        pw.write("\r\n");
        pw.write("PrintWriter: 字符打印輸出流");
        //打印到目的地文件,
        pw.print('a');
        pw.write("\r\n");
        pw.print("我想你了!");
//        pw.flush();  close()實現了刷新流操做,能夠省略
        //釋放資源
        pw.close();
    }
    /*
     * public void println() : 把各類數據類型的數據打印, 實現換行功能
     * 若是啓用了自動刷新,則只有在調用 println 數據自動寫入到文件中
     * 
     * 經過構造函數來完成自動刷新
     * public PrintWriter(OutputStream out,boolean autoFlush)
     * public PrintWriter(Writer out, boolean autoFlush)
     */
    public static void printlnMethodAndAutoFlush() throws IOException{
        PrintWriter pw = new PrintWriter(new FileWriter("abc.txt"), true);
        pw.write("我是中國人!");
        pw.print("我是中國人!");
        //只有println配合構造函數的自動刷新纔會起做用,println會把前面的也flush了.writer()和print()不會自動把內容刷新到目的地
        pw.println("我是中國人!");
        pw.println("我是中國人!");
        pw.close();
    }
    /*
     * 需求:把F:\\Demo.java 文件  複製  到 項目的根目錄下 Copy.java  (使用打印流)
     * 
     * 數據源:    E:\\Demo.java -- 字符輸入流 -- FileReader -- BufferedReader
     * 
     * 目的地:Copy.java -- 字符輸出流 -- FileWriter -- BufferedWriter -- PrintWriter
     * 
     * 思路:
     *         a:封裝數據源
     *         b:封裝目的地
     *         c:讀寫操做
     *         d:釋放資源
     */
    public static void printWriterDemo() throws IOException{
        //建立字符輸入緩衝流和打印流  封裝數據源和目的地文件
        BufferedReader br = new BufferedReader(new FileReader("F:\\Demo.java"));
        PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
        String str = null;
        while ((str = br.readLine())!= null) {
            pw.println(str);
        }
        br.close();
        pw.close();
    }
}

 10.8.1 printf方法

/*
     * public PrintWriter printf(String format, Object... args):按照指定的格式 進行數據的輸出打印
     */
    public static void test(){
        System.out.printf("%B",true);
        System.out.printf("%s","dsadsaeds");
        int x = 20;
        int y = 20;
        System.out.printf("%d+%d=%d",x,y,x+y);
        
    }

10.9 可變參數

package args;
/*
 * 可變參數
 *         格式:
 *         修飾符 返回值類型 方法名(數據類型... 變量){
 *         }
 *         變量: 其實 它是數據類型數據的數組
 * 
 *         注意事項: 當使用可變參數的時候, 可變參數必需要在參數列表的最後一個位置
 */
public class ArgsDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArgsDemo ad = new ArgsDemo();
        test(1,2,3,4);
        System.out.println(ad.test('a',2));
        ad.test(1, 2);
        ad.test(1, 2, 3);
        
    }
    //可變參數---能夠考慮方法重載,可變參數意味着,當咱們不肯定參數個數時使用
    public static void test(int... i){
        for (int j : i) {
            System.out.print(j+" ");
        }
    }
    //方法重載
    public void test(int a,int b){
        System.out.println(a+b);
    }
    //方法的重載注意兩點,方法名相同,參數類型或者參數個數不一樣,其餘的不在方法重載的判別範圍內(如返回值等)
    public int test(char a,int b){
        return a+b;
    }
    public void test(int a,int b,int c){
        System.out.println(a+b+c);
    }
    
}

10.10 數組轉變爲List集合

package Arrays;

import java.util.Arrays;
import java.util.List;

/*
 * Arrays:數組工具類中的方法
 *         public static <T> List<T> asList(T... a)
 *         把數組 轉換爲List集合
 */
public class ArrayToList {

    public static void main(String[] args) {
        arrayToListDemo();

    }
    //把數組轉變爲集合
    public static void arrayToListDemo(){
        //建立Integer類型數組
        Integer[] i = new Integer[]{1,2,3,4,5};
        //將數組做爲可變參數傳入,方法,轉變爲List集合
        List<Integer> list = Arrays.asList(i);
        for (Integer in : list) {
            System.out.println(in);
        }
    }
}

10.11 Properties

package properties;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
//        propertiesTest();
//        propertiesMethod();
//        propertiesFunction();
//        propertiesLoadTest();
        propertiesDemo();
    }
    /*
     * Properties
     * 是一個集合與IO流相互處理的類
     * 經過觀察,Properties它的父類 是Hashtable類,因此,它是Map集合
     * 屬性列表中每一個鍵及其對應值都是一個字符串
     */
    public static void propertiesTest(){
        Properties p = new Properties();
        p.put("及時雨", "宋公明");
        p.put("玉麒麟", "盧俊義");
        p.put("智多星", "吳用");
        System.out.println("經過鍵獲取值:"+p.get("智多星"));
    }
    /*
     * Properties的特有方法
     *         添加功能:
     *             public Object setProperty(String key, String value) 調用 Hashtable 的方法 put
     *         獲取功能:
     *             public String getProperty(String key) : 返回給定的key 對應的值
     *             public String getProperty(String key, String defaultValue) 
     *                     返回給定的key 對應的值, 若是該鍵不存在,返回 defaultValue
     *                 
     *             public Set<String> stringPropertyNames() 返回鍵的集合
     */
    public static void propertiesMethod(){
        Properties p = new Properties();
        p.setProperty("及時雨", "宋公明");
        p.setProperty("玉麒麟", "盧俊義");
        p.setProperty("智多星", "吳用");
        System.out.println("經過指定的鍵獲取值,若是值不存在返回null:"+p.getProperty("黑旋風"));
        System.out.println("經過指定的鍵獲取值,若是值不存在返回null:"+p.getProperty("及時雨"));
        System.out.println("返回給定的key 對應的值, 若是該鍵不存在,返回 defaultValue:"+p.getProperty("黑旋風", "是李逵"));
        System.out.println("返回給定的key 對應的值, 若是該鍵不存在,返回 defaultValue:"+p.getProperty("及時雨", "是李逵"));
        Set<String> s = p.stringPropertyNames();
        for (String string : s) {
            System.out.println("鍵:"+string);
        }
    }
    /*
     * Properties特有方法
     *         public void list(PrintStream out) : 把集合數據 寫入到指定的文件中
     *         public void list(PrintWriter out) :  把集合數據 寫入到指定的文件中
     * 
     *  我想把集合中的數據  寫入到文件
     *  
     *  思路:
     *      a:集合
     *      b:添加數據
     *      c:封裝目的地   prop.txt
     *      d:把集合中的數據寫入目的地 文件
     */
    public static void propertiesFunction() throws IOException{
        //集合
        Properties p = new Properties();
        p.setProperty("及時雨", "宋公明");
        p.setProperty("玉麒麟", "盧俊義");
        p.setProperty("智多星", "吳用");
        //目的地封裝文件
        PrintWriter pw = new PrintWriter("p.properties");
        //把集合寫入到文件
        p.list(pw);
        //關閉流
        pw.close();
    }
    /*
     * Properties特有方法
     *         public void load(InputStream inStream)
     *         public void load(Reader reader)
     * 
     * 需求: 把文件中的數據獲取出來, 存入集合  (這個文件中的數據要是必須是鍵值對格式)
     * 思路:
     *         a: 建立集合
     *         b: 封裝數據源 prop.txt
     *         c: 獲取數據到集合
     */
    public static void propertiesLoadTest() throws IOException{
        Properties p = new Properties();
        System.out.println("P:"+p);
        FileReader fr = new FileReader("abc.txt");
        p.load(fr);
        System.out.println("p:"+p);
        Set<String> s = p.stringPropertyNames();
        for (String string : s) {
            System.out.println(string);
            System.out.println(p.getProperty(string));
        }
    }
    /*
     * Properties特有方法
     *         public void store(OutputStream out, String comments)
     *         public void store(Writer writer, String comments)
     * 參數2是 屬性列表的描述
     * 把集合數據 存入到文件中
     */
    public static void propertiesDemo() throws IOException{
        Properties p = new Properties();
        p.setProperty("及時雨", "宋公明");
        p.setProperty("玉麒麟", "盧俊義");
        p.setProperty("智多星", "吳用");
        //目的地封裝文件
        PrintWriter pw = new PrintWriter("pp.properties");
        p.store(pw, "what is this!");
    }
    
}

經過鍵獲取值:吳用
經過指定的鍵獲取值,若是值不存在返回null:null
經過指定的鍵獲取值,若是值不存在返回null:宋公明
返回給定的key 對應的值, 若是該鍵不存在,返回 defaultValue:是李逵
返回給定的key 對應的值, 若是該鍵不存在,返回 defaultValue:宋公明
鍵:及時雨
鍵:玉麒麟
鍵:智多星
P:{}
p:{我是中國人!我是中國人!我是中國人!=, 我是中國人!=}
我是中國人!我是中國人!我是中國人!工具

我是中國人!

package properties;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;
import java.util.Set;

/*
 * 需求: 讀取user.txt中的數據 (一個鍵值對形式內容,  鍵是名稱,  值是年齡)  
 *         若是有"lisi"這我的,把這我的的年齡 更給爲100
 *         從新存儲起來
 * 
 * 
 * 思路:
 *         a:讀取user.txt文件, 讀取到Properties集合中
 *         b: 獲取全部的鍵
 *         c: 遍歷,獲得每個鍵
 *         d: 判斷鍵是不是"lisi"
 *             是:給"lisi"的值 更新爲100
 *             否:無論了
 */
public class PropertiesTest {

    public static void main(String[] args) throws IOException {
        //建立集合對象
        Properties p = new Properties();
        //常見源文件對象,封裝文件
        FileReader fr = new FileReader("user.txt");
        //把文件寫入集合
        p.load(fr);
        //獲取全部鍵
        Set<String> s = p.stringPropertyNames();
        System.out.println(p.get("李四"));
        //遍歷鍵
        for (String string : s) {
            //判斷
            if(string.equals("李四")){
                p.setProperty(string, "100");
            }
        }
        System.out.println(p.get("李四"));
        //把集合中元素,寫入文件
        p.list(new PrintStream("user.txt"));
        fr.close();
    }

}

 

 

10.12 序列化流&&反序列化流

package Serializable;

import java.io.Serializable;

/*java.io.NotSerializableException: Serializable.Person
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at Serializable.ObjectOutputSreamDemo.test1(ObjectOutputSreamDemo.java:40)
    at Serializable.ObjectOutputSreamDemo.main(ObjectOutputSreamDemo.java:25)
 * * 當實例須要具備序列化接口時,拋出此異常
 * 沒有實現序列化接口
 * java.io.NotSerializableException
 * 
 * Serializable:序列化接口
 * 類經過實現 java.io.Serializable 接口以啓用其序列化功能
 * 
 * */
public class Person implements Serializable{
    public String name;
    public int age;
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
}
package Serializable;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/*
 *  序列化流:
 *  ObjectOutputStream : 把對象  以流的方式操做
 *  ObjectOutputStream : 將 Java 對象的基本數據類型和圖形寫入 OutputStream
 *      方法:
 *      public final void writeObject(Object obj): 將指定的對象寫入 ObjectOutputStream
 *  
 *  反序列化流:
 *  ObjectInputStream: 把流對象 解析成 對象使用
 *  
 *  把person 對象 寫入 demo.txt中
 */
public class ObjectOutputSreamDemo {

    public static void main(String[] args) throws ClassNotFoundException, IOException {
        //序列化流
        try {
            test1();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //反序列化流
        test2();
    }
    //把對象寫入流
    public static void test1() throws IOException{
        //常見序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
        //建立自定義對象
        Person p = new Person("遊先生",27);
        //把對象寫入流,網絡上傳輸都是字節流
        //把自定義對象 寫入流中,就至關於 寫入到文件中
        oos.writeObject(p);
        //關閉流
        oos.close();
    }
    //把流中的對象解析出來
    public static void test2() throws IOException,ClassNotFoundException{
        //建立反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
        //把反序列化流寫出
        Object object = ois.readObject();
        Person p = (Person) object;
        System.out.println(p.getName()+"  "+p.getAge());
        //關閉流
        ois.close();
    }
}

相關文章
相關標籤/搜索