JavaSEday10File類、遞歸和字節流

day10_面向對象(File類、遞歸和字節流)
    一.File類
        1.File類的作用
            File類可以用來表示文件或者文件夾
        2.File類的構造
            public File(String pathname);
            public File(String parent, String child);
            public File(File file, String child);

/**
 * File類的構造方法
 */
public class FileDemo01 {
    public static void main(String[] args) {
        //1.根據路徑
        File f1 = new File("C:\\Users\\Administrator\\Desktop\\temp\\aaa\\1.png");
        System.out.println(f1);
        //2.父路徑和子路徑
        File f2 = new File("C:\\Users\\Administrator", "Desktop\\temp\\aaa\\1.png");
        System.out.println(f2);
        //3.父File對象和子路徑
        File parent = new File("C:\\Users\\Administrator");
        File f3 = new File(parent, "Desktop\\temp\\aaa\\1.png");
        System.out.println(f3);
    }
}

        3.相對路徑和絕對路徑的概念*****************
            絕對路徑:以盤符開頭的路徑 比如:C:\\code\\1.java
            相對路徑:以當前項目的根目錄開始 比如1.txt 該文件就從當前項目的根目錄開始尋找
        4.File類的獲取方法
            public String getAbsolutePath(); // 獲取絕對路徑
            public String getPath(); // 獲取創建時傳入路徑

            public long length(); // 只能獲取文件的大小(單位字節),不能獲取文件夾的大小
            public String getName(); // 獲取名字(文件名字)

/**
 * File類的獲取方法
 */
public class FileDemo02 {
    public static void main(String[] args) {
        //1.創建File對象
        File f1 = new File("E:\\mycode\\heima112\\111.txt");
//        File f1 = new File("1.txt");
        //2.獲取絕對路徑
        String absolutePath = f1.getAbsolutePath();
        System.out.println(absolutePath);
        System.out.println("=====================");
        //3.獲取構造時傳入的路徑
        String path = f1.getPath();
        System.out.println(path);
        System.out.println("=====================");
        //4.獲取文件的大小
        long len = f1.length();
        System.out.println("文件大小爲:"+len); //GBK/UTF-8 編碼下1箇中文2/3個字節
        //5.獲取名字
        System.out.println("=====================");
        String name = f1.getName();
        System.out.println(name);
    }
}

        5.File類的判斷方法
            public boolean exists(); // 判斷File對象所表示的文件或者文件夾是否存在
            public boolean isFile(); // 判斷是否是文件
            public boolean isDirectory(); // 判斷是否是文件夾

/**
 * File類的判斷方法
 */
public class FileDemo03 {
    public static void main(String[] args) {
        //1.判斷是否存在
        File f1 = new File("11.txt");
        boolean exists = f1.exists();
        System.out.println(exists);
        System.out.println("===========");
        //2.判斷是文件還是文件夾
        boolean isFile = f1.isFile();
        System.out.println("是文件嗎?" + isFile);
        boolean isDirectory = f1.isDirectory();
        System.out.println("是文件夾嗎?" + isDirectory);
    }
}

            注意:判斷是文件還是文件時,必須要保證該File對象表示路徑存在!!!
            在Windows中同一路徑下文件和文件名不允許重名(Windows中也不區分大小寫)
        6.File類的創建刪除方法
            public boolean createNewFile(); 創建一個文件,返回值代表是否成功
            public boolean mkdir(); 創建一個單級文件夾,返回值代表是否成功
            public boolean mkdirs(); 創建一個多級文件夾,返回值代表是否成功
            public boolean delete(); 刪除文件或者空的文件夾,返回值代表是否成功

/**
 * File類的創建和刪除方法
 */
public class FileDemo04 {
    public static void main(String[] args) throws IOException {
        //1.創建文件
        File f1 = new File("2.txt");
        boolean newFile = f1.createNewFile();
        System.out.println("是否創建成功:" + newFile);
//        //2.創建文件夾
        File f2 = new File("aaa");
        boolean mkdir = f2.mkdir();
        System.out.println("是否創建成功:"+mkdir);
        //3.刪除文件或者文件夾
        boolean b1 = f1.delete();
        boolean b2 = f2.delete();
        System.out.println("文件是否刪除成功:"+b1);
        System.out.println("文件夾是否刪除成功:"+b2);
        //4.mkdirs
        File f3 = new File("aaa\\bbb\\ccc\\ddd");
        System.out.println(f3.mkdir());
        System.out.println(f3.mkdirs());
        //5.delete方法的限制
        File f4 = new File("bbb");
        System.out.println(f4.delete());

    }
}

        7.File類遍歷目錄的方法
            public String[] list(); 列出當前文件夾下所有東西的名字
            public File[] listFiles(); 列出當前文件夾下所有File對象

/**
 * 遍歷目錄方法
 */
public class FileDemo05 {
    public static void main(String[] args) {
        //1.列出名字
        File f1 = new File("C:\\Users\\Administrator\\Desktop\\temp\\aaa");
        String[] names = f1.list();
        for (String name : names) {
            System.out.println(name);
        }
        //2.列出File對象
        System.out.println("===================");
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.print(file.getAbsolutePath());
            if (file.isFile()) {
                System.out.print("是文件");
                System.out.println(",大小爲:"+file.length()+"字節");
            }else{
                System.out.println("是文件夾");
            }
        }
    }
}


    二.遞歸
        1.什麼是遞歸
            在方法內部調用自己
            如果是無限遞歸(或死遞歸),程序最終會出現錯誤            StackOverflowError(棧溢出錯誤)
             
            如果想要正確地使用遞歸,必須保證遞歸有正確的出口(結束條件),所謂的出口,是指當滿足某個條件時,直接使用return結束本次遞歸函數調用,返回上級遞歸調用

public class RecursionDemo {
    public static void main(String[] args) {
        method(100);
    }

    public static void method(int n) {
        //讓遞歸有一個出口,不再繼續調用自己
        if (n == 0) {
            return;
        }
        System.out.println("method方法...");
        method(n-1);
    }
}

        2.遞歸求和案例
            需求:使用遞歸求1+2+3...+n的和
            遞歸步驟:
                a.定義方法
                b.找規律,遞歸調用自己
                c.找遞歸的出口條件

public class RecursionTestDemo01 {
    public static void main(String[] args) {
        //調用
        int sum = getSum(10);
        System.out.println(sum);
    }

    /**
     * 遞歸步驟:
     * a.定義方法
     * b.找規律,遞歸調用自己
     * c.找遞歸的出口條件
     */
    //a.定義方法
    public static int getSum(int n) {
        //c.找遞歸的出口條件
        if (n == 1) {
            return 1;
        }
        //b.找規律,遞歸調用自己
        // 求 1+2+3..n = (1+2+3..n-1) + n
        return getSum(n-1)+n;
    }

    //使用for循環
    public static int getSum(int n) {
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum+=i;
        }
        return sum;
    }
}


        3.遞歸求積案例
            需求:使用遞歸求1*2*3...*n的積
            遞歸步驟:
                a.定義方法
                b.找規律,遞歸調用自己
                c.找遞歸的出口條件

public class RecursionTestDemo02 {
    public static void main(String[] args) {
        //調用方法
        int ji = getJi(6);
        System.out.println(ji);
    }

    //使用遞歸求1-n積
    public static int getJi(int n) {
        if (n == 1) {
            return 1;
        }
        //1*2*3..n = (1*2*3..n-1)*n
        return getJi(n-1)*n;
    }
}

        4.文件搜索案例
            在目錄:C:\Users\Administrator\Desktop\temp\aaa
            搜索所有的:xxx.txt文件

public class RecursionTestDemo03 {
    public static void main(String[] args) {
        //搜索文件案例
        //目標文件夾
        File objDir = new File("C:\\Users\\Administrator\\Desktop\\temp\\aaa");
        //目標文件: xx.txt文件
        printTxtFile(objDir);
    }

    //定義方法,在某個文件夾下搜索.txt文件
    public static void printTxtFile(File objDir) {
        //1.列出所有文件
        File[] files = objDir.listFiles();
        //2.遍歷
        for (File file : files) {
            //3.判斷
            if (file.isFile() && file.getName().endsWith(".txt")) { //endsWith 判斷以xxx結尾  startsWith判斷以xx開頭
                //說明是一個txt的文本文件
                System.out.println(file.getAbsolutePath());
            } else if (file.isDirectory()) {
                //說明是文件夾
                printTxtFile(file);
            }
        }
    }
}

    
    三.IO流的概述
        1.什麼是IO流
            流:數據流,一種比喻,把數據傳輸過程比喻流
            I:Input 輸入流 將數據從外部設備讀取到內存中
            O:Output 輸出流 將數據從內存寫到外部設備中
            IO流都是相對於內存而言的!!!
        2.IO流的分類
            a.根據流的方向來分
                輸入流
                輸出流
            b.根據流中數據類型來分
                字節流
                字符流
        3.Java中IO的四大流***************
            字節輸入流 OutputStream(抽象類)
            字節輸出流 InputSream(抽象類)

            字符輸入流 Writer(抽象類)
            字符輸出流 Reader(抽象類)
            
            Java中流的命名:功能+父類名
                比如:FileInputStream 文件的字節輸入流
                    ObjectInputStream 對象的字節輸入流(反序列化流)(序列化時輸出流)
    四.字節流********************
        1.萬物皆對象和IO流一切皆字節
            Java中思想:萬物皆對象
            IO流中:一切皆字節
                在計算機中,所有東西,最終底層都是0101二進制(8個0101稱爲一個字節)    
            問題:
                a.既然.txt文件是字節,那麼    打開時爲什麼不是0101??
                因爲我們打開文件時,是用某個軟件打開,軟件具有解析功能,同樣道理,視頻文件,音頻文件,圖片文件等,都需            要使用對應的軟件打開,這些軟件都會把數據解析成他們指定的格式。
                b.能不能不要解析0101,就像看0101?
                可以的,只要使用某些二進制工具打開即可

        2.字節輸出流******************
            字節輸出流:頂層父類:OutputStream(抽象類)
            共性方法:    
                public void write(int b);一次寫一個字節
                public void write(byte[] bs);一次寫一個字節數組
                public void write(byte[] bs, int startIndex, int len);一次寫一個字節數組的一部分
                
                public void flush();刷新緩衝區(對於字節流來說沒用)
                public void close();關閉流(釋放資源)
        3.FileOutputStream類的使用*****************
            FileOutputStream文件的字節輸出流
            a.構造方法
                public FileOutputStream(String pathname);
                public FileOutputStream(File file);

/**
 * FileOutputStream的構造方法
 */
public class FileOutputStreamDemo01 {
    public static void main(String[] args) throws Exception {
        //1.構造方法
        FileOutputStream fos = new FileOutputStream("1.txt");
//        FileOutputStream fos = new FileOutputStream(new File("1.txt"));
        /**
         * 以上構造幹了三件事!!!
         * a.創建對象fos
         * b.判斷文件是否存在
         *      不存在,自動創建!!!
         *      存在,會清空文件內容
         * c.讓fos對象和1.txt綁定了     
         */
    }
}


            b.寫字節數據的三個方法*****************
                public void write(int b); 一次寫一個字節
                public void write(byte[] bs); 一次寫一個字節數組
                public void write(byte[] bs, int startIndex, int len); 一次寫一個字節數組的一部分

/**
 * FileOutputStream的構造方法
 */
public class FileOutputStreamDemo02 {
    public static void main(String[] args) throws Exception {
        //1.構造方法
        FileOutputStream fos = new FileOutputStream("1.txt");
        //2.寫字節數據三個方法
        //a.一次寫單個字節
        fos.write(97);//0110 0001
        //問題:現在我需要打開記事本後看到97,怎麼做?
        fos.write(57); //9的二進制 57
        fos.write(55); //9的二進制 57
        //問題:現在我需要打開記事本後看到java,怎麼做?
        fos.write(106);
        fos.write(97);
        fos.write(118);
        fos.write(97);
        //b.一次寫一個字節數組
        byte[] bs = {106,97,118,97};
        fos.write(bs);
        //問題:現在我需要打開記事本後看到ghjkvbnmtyudsagdhfwertygasdfg,怎麼做?
        //使用String類中的getBytes方法,自動把字符串中的字母變成碼值
        byte[] bs1 = "Java我愛你".getBytes();
        fos.write(bs1);
        //c.一次寫一個字節數組的一部分
        byte[] bs2 = {106,97,118,97};
        fos.write(bs2,1,2);
    }
}

        c.如何追加/續寫
            想要追加文件只需要使用以下構造即可
            public FileOutputStream(String pathname, boolean append); 
            public FileOutputStream(File file, boolean append);

/**
 * FileOutputStream的追加/續寫
 */
public class FileOutputStreamDemo03 {
    public static void main(String[] args) throws Exception {
        //1.追加創建對象
//        FileOutputStream fos = new FileOutputStream("1.txt",true);//true表示追加,默認是false
        FileOutputStream fos = new FileOutputStream(new File("1.txt"),true);//true表示追加,默認是false
        //2.調用寫數據方法
        fos.write("你喜歡嗎?".getBytes());
    }
}

        d.如何換行
            很簡單,只需要向文件寫一個換行符即可
            window:\r\n
            Linux: \n
            Mac: \r(MacOS X之後換行變爲\n)
/**
 * FileOutputStream的換行
 */
public class FileOutputStreamDemo04 {
    public static void main(String[] args) throws Exception {
        //1.創建輸出流
        FileOutputStream fos = new FileOutputStream("1.txt");
        //2.寫數據
        for (int i = 0; i < 10; i++) {
            fos.write("java".getBytes());
            //寫一個換行符
            fos.write("\r\n".getBytes());
        }
    }
}

        e.flush和close
            public void flush(); 刷新緩衝區(對於字節流來說沒用,是一個空方法,對字符流纔有用)
            public void close(); 釋放資源

/**
 * FileOutputStream的flush和close
 */
public class FileOutputStreamDemo04 {
    public static void main(String[] args) throws Exception {
        //1.創建輸出流
        FileOutputStream fos = new FileOutputStream("1.txt");
        //2.寫數據
        for (int i = 0; i < 10; i++) {
            fos.write("java".getBytes());
            //寫一個換行符
            fos.write("\r\n".getBytes());
        }
        //3.刷新
//        fos.flush();
        //4.關閉
        fos.close();
    }
}


總結:
        -[] 能夠說出File對象的創建方式
            public File(String pathname);
        -[] 能夠使用File類常用方法
            public File listFiles();
        -[] 能夠辨別相對路徑和絕對路徑
        -[] 能夠遍歷文件夾(list和listFiles)
        -[] 能夠解釋遞歸的含義
        -[] 能夠使用遞歸的方式計算5的階乘(1*2*3*4*5)
        -[] 能夠說出使用遞歸會內存棧溢出的隱患的原因
        -[] 能夠說出IO流的分類和功能
                輸入流 讀
                輸出流 寫
        -[] 能夠使用文件的字節輸出流向文件中寫出數據到文件中***
                blic void write(int b);一次寫一個字節
                public void write(byte[] bs);一次寫一個字節數組
                public void wirte(byte[] bs,int startIndex,int len);一次寫一個字節數組的一部分

            
            


            
         
 


            
            

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