1. 程式人生 > >遞歸、字節流、文件復制_DAY20

遞歸、字節流、文件復制_DAY20

app 一個數 sta red write 接收 文件名 掌握 這一

1:遞歸(理解)

(1)方法定義中調用方法本身的現象。

(2)遞歸註意事項:

A:要有出口,否則就是死遞歸。

B:次數不能太多,否則內存溢出。

特殊事項:構造方法不能遞歸定義。

例子:cn.itcast.demo

技術分享
package cn.itcast;
/*
 * 遞歸算法:
 *         自己調用自己。
 *         方法內定義:調用到什麽程度,就不調用自己了。即遞歸出口。
 */
public class Demo {

    public static void main(String[] args) {

        method(
5); } public static void method(int flag){ System.out.println("我是一個遞歸方法調用前的代碼"+flag); if(flag>0) { flag--; method(flag); System.out.println("我是一個遞歸方法調用後的代碼"+flag); } else { System.out.println("遞歸出口出來了!");
return; } } }
View Code

(3)案例:(面試可能見到)

A:遞歸求1到10的和 例子:cn.itcast.Test

技術分享
package cn.itcast;
/*
 * 遞歸:將復雜問題分解,即復雜問題簡單化。
 * 使用遞歸求1-10的和。
 *         10 + 1-9的和
 *         9 + 1-8的和
 *         8+ 1-7的和
 *         ...
 *         3+  1-2和
 *         2+  1的和
 *         1 返回1
 */
public
class Test { public static void main(String[] args) { System.out.println(getSum(3)); } //獲取1到指定數字的和 public static int getSum(int number) { //遞歸出口:如果加到1了,則返回1。 if(number==1) { return 1; //如果不是1,就使用這個數,加上:1——比它小1的數的和。 }else { int nextNumber = number-1; return number + getSum(nextNumber); } } }
View Code

B:遞歸求階乘 例子:cn.itcast.Test0

技術分享
/**
 * 階乘
 * 10 * 9-1
 * 9 * 8-1
 * 8 * 7-1
 * ...
 * 2 * 1
 * 1 return 1;
 */
public class Factorial {
    public static void main(String[] args) {
        int max=4;
        int factorial=method(max);
        System.out.println(factorial);
    }

    public static int method(int max) {
        int fatorial=max;
        if(max==1){
            return max;
        }else {
            fatorial=max*method(max-1);
            max--;
        }
        return fatorial;
    }
}
View Code

C:遞歸求5的階乘 例子:cn.itcast.Test2

技術分享
package cn.itcast;
/*
 * 遞歸:將復雜問題分解,即復雜問題簡單化。
 * 使用遞歸求5的階乘。
 */
public class Test2 {

    public static void main(String[] args) {
            
        System.out.println(getSum(5));
    }

    //獲取1到指定數字的積
    public static int getSum(int number) {
        //遞歸出口:如果加到1了,則返回1。
        if(number==1) {
            return 1;
        //如果不是1,就使用這個數,加上:1——比它小1的數的和。
        }else {
            int nextNumber = number-1;
            return number * getSum(nextNumber);
        }
    }
}
View Code

D:遞歸求兔子問題(斐波那契數列) cn.itcast.Test4; n.itcast.Test3

技術分享
package cn.itcast;
/*
 * 使用遞歸計算斐波那契數列
 * 結果: 1    1     2     3     5       8     13      21      34...
 * number:1    2     3     4     5
 * 計算到第幾個數時,那個數是多少
 */
public class Test3 {

    public static void main(String[] args) {
        
        System.out.println(method(7));
    }
    
    //這個方法到底是幹什麽的?給我第幾個數,我給你返回這一個數的值。!!!!
    public static int method(int number) {  //number:第幾個數
        
        if(number == 1||number == 2) {//如果是前兩個數,就返回1
            return 1;
        } else {
            int before = number-1;  //得到前一個數是第幾個數
            int beforeBefore = number-2; //得到前一個數的前一個數是第幾個數
            return method(before) + method(beforeBefore);   //拿到前一個數的值,拿到前一個數的前一個數的值,相加,得到這個數。
        }
    }

}
View Code 技術分享
package cn.itcast;
/*
 * 一對兔子:每到第三個月,生一對兔子,之後每個月都生一對兔子。這一對小兔子,在第三個月時,生下一對兔子,之後每個月都生一對兔子。
 * 註意:
 *         兔子,不生病,不死亡。
 * 問某個月後,有多少對兔子?
 * 1   :    1
 * A1
 * 2   :    1
 * A2
 * 3   :    2
 * A3 B1
 * 4   :    3
 * A3 C1 B2
 * 5   :    5
 * A3 D1 C2 B3 E1
 * 6   :    8
 * A3 F1 D2 C3 G1 B3 H1 E2
 * 7   :    13
 * A3 J1 F2 D3 K1 C3 L1 G2 B3 M1 H2 E3 N1
 */
public class Test4 {

    public static void main(String[] args) {
        //使用斐波那契數列
    }

}
View Code

E:遞歸遍歷目錄(帶內容的目錄) cn.itcast.Test5

技術分享
package cn.itcast;

import java.io.File;

/*
 * 遞歸輸出指定目錄下所有java文件的絕對路徑
 */
public class Test5 {

    public static void main(String[] args) {

        File file = new File("src");
        method(file);
    }

    public static void method(File dir) {
        
        File[] listFiles = dir.listFiles();
        
        for (File fileorDir : listFiles) {
            //如果是文件夾
            if(fileorDir.isDirectory()) {
                System.out.println("dir:"+fileorDir.getName());
                method(fileorDir);
            } else { //如果是文件
                
                if(fileorDir.getName().endsWith(".java"))  //判斷文件名是否以.java結尾
                    System.out.println(fileorDir.getAbsolutePath());
            }
        }
    }
}
View Code

F:遞歸刪除目錄(帶內容的目錄) cn.itcast.Test6

技術分享
package cn.itcast;

import java.io.File;

/*
 * 遞歸刪除指定文件夾
 */
public class Test6 {

    public static void main(String[] args) {
        
        File dir = new File("a");
        method(dir);
    }

    public static void method(File dir) {
        //先刪除內容
        //返回該目錄下所有的文件及文件夾對象
        File[] listFiles = dir.listFiles();
        
        for (File fileorDir : listFiles) {
            if(fileorDir.isDirectory()) {
                //刪除這個文件夾
                method(fileorDir);
            }else {
                //直接刪除這個文件
                System.out.println(fileorDir.getName());
                fileorDir.delete();
            }
        }
        
        //刪除我自己
        System.out.println(dir.getName());
        dir.delete();
    }
}
View Code

2:IO(掌握)

(1)IO就是在不同設備間傳遞數據。

(2)IO流分類:

A:流向

輸入流 讀取數據

輸出流 寫出數據

B:數據類型

字節流

字節輸入流 InputStream

文件字節輸入流:FileInputStream 例子:cn.itcast3.demo2

技術分享
package cn.itcast3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

/*
 *  文件字節輸入流:FileInputStream
 *         構造方法:
 *             public FileInputStream(File file)throws FileNotFoundException。
 *             public FileInputStream(String name)throws FileNotFoundException。
 *         主要方法:
 *             public int read() throws IOException  一次讀取一個字節
 *             public int read(byte[] b) throws IOException 一次讀取一個字節數組  返回值為本次讀到的字節個數
 */
public class Demo2 {

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

        method2();
    }

    public static void method() throws FileNotFoundException, IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream(new File("b.txt"));
        //讀取輸入
//        int myByte = fis.read();
//        System.out.println(myByte);
//        int myByte2 = fis.read();
//        System.out.println(myByte2);
//        int myByte3 = fis.read();
//        System.out.println(myByte3);
//        int myByte4 = fis.read();
//        System.out.println(myByte4);
//        int myByte5 = fis.read();
//        System.out.println(myByte5);
        int c;
        while((c=fis.read())!=-1) {
            System.out.println(c);
        }
        //關閉資源
        fis.close();
    }
    
    public static void method2() throws FileNotFoundException, IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream(new File("b.txt"));     //b.txt內容: javav\r\n
        //讀取輸入
        byte[] bytes = new byte[3];
        
//        int len = fis.read(bytes);  //{j,a,v}
//        System.out.println(len);
//        System.out.println(Arrays.toString(bytes));
//        int len2 = fis.read(bytes); //{a,v,\r}
//        System.out.println(len2);
//        System.out.println(Arrays.toString(bytes));
//        int len3 = fis.read(bytes); //{\n,v,\r}      //v,\r重復讀取了
//        System.out.println(len3);
//        System.out.println(Arrays.toString(bytes));
        
        int len;
        while((len=fis.read(bytes))!=-1) {
//            System.out.println(Arrays.toString(bytes));
            System.out.println(new String(bytes, 0, len));
        }
        
        //關閉資源
        fis.close();
    }

}
View Code

字節輸出流 OutputStream

文件字節輸出流:FileOutputStream 例子:cn.itcast3.demo

技術分享
package cn.itcast3;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

/*
 * 字節輸出流:OutputStream
 *         00000000 00000000 00000000 0000 1111  15
 * 
 * 文件字節輸出流:FileOutputStream
 *         構造方法:
 *             public FileOutputStream(File file)throws FileNotFoundException  寫出是覆蓋操作,不是追加。
 *             public FileOutputStream(String name)throws FileNotFoundException  寫出是覆蓋操作,不是追加。
 *             public FileOutputStream(File file,boolean append)throws FileNotFoundException  布爾值為true,寫出追加操作。
 *             public FileOutputStream(String name,boolean append)throws FileNotFoundException  布爾值為true,寫出追加操作。
 *         主要方法:
 *             public void write(int b) throws IOException  寫出一個字節    
 *             public void write(byte[] b) throws IOException  寫出一個字節數組
 * 
 *         註意:
 *             1:使用(File file)與(String name)參數的構造方法,寫出是覆蓋操作。
 *                   使用(File file,boolean append)與(String name,boolean append)參數的構造方法,寫出是追加操作。
 *             2:使用一次一個字節的方式,無法直接輸出中文。可以使用一次一個字節數組的方式。
 *             3:如果寫出目標的這個文件不存在,則直接創建一個文件,再寫出。
 */
public class Demo {

    public static void main(String[] args) throws FileNotFoundException,IOException {
        
        method3();
        
    }

    //一次輸出一個字節。
    public static void method() throws FileNotFoundException,IOException {
        //1創建流對象
        FileOutputStream fos = null;
        try {
            File file = new File("b.txt");
            fos = new FileOutputStream(file);
            //2寫出內容
            fos.write(-42);
            fos.write(-48);
            fos.write(‘9‘);
            fos.write(‘7‘);
            fos.write(‘中‘);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(fos!=null) {
                //3關閉資源
                fos.close();
            }
        }
    }
    //一次輸出一個字節數組。
    public static void method2() throws FileNotFoundException,IOException {
        //1創建流對象
        FileOutputStream fos = new FileOutputStream("b.txt");
        //2準備寫出的數據
//        byte[] data = new byte[]{97,98,99,100};  //方式一
        String sData = "java中國";      //方式二
        byte[] data = sData.getBytes();
        
        System.out.println(Arrays.toString(data));
        //3寫出內容
        fos.write(data);
        //4關閉資源
        fos.close();
    }
    
    //一次輸出一個字節數組。追加
    public static void method3() throws FileNotFoundException,IOException {
        //1創建流對象
        FileOutputStream fos = new FileOutputStream("b.txt",true);
        
        //2準備寫出的數據
//        byte[] data = new byte[]{97,98,99,100};
        String sData = "java中國";
        byte[] data = sData.getBytes();
        
        System.out.println(Arrays.toString(data));
        
        //3寫出內容
        fos.write(data);
        
        //4關閉資源
        fos.close();
    }
}
View Code

例子:文件的復制 :cn.itcast3.demo3

技術分享
package cn.itcast3;

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

/*
 * 文件復制:
 *         方式一:一次一個字節的復制。
 *              方式二:一次一個字節數組的復制。
/
 */
public class Demo3 {

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

        method2();
    }
    //一次一個字節:
    public static void method() throws FileNotFoundException, IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");
        
        //
        int c;
        while((c=fis.read())!=-1) {  //一次讀一個字節
            
            //
            fos.write(c);
        }

        //關閉流
        fos.close();
        fis.close();
    }
    
    //一次一個字節數組:
    public static void method2() throws FileNotFoundException, IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");
        
        ////定義字節數組用來接收讀取到的字節們
        byte[] bytes = new byte[4];
        //定義變量,記錄本次讀取到的字節個數
        int len;
        //循環讀取文件內容
        while((len = fis.read(bytes))!=-1) {  //只要讀到信息就進入循環體
            ////一次寫入長度為4的數組內容
            fos.write(bytes,0,len);
        }

        //關閉流
        fos.close();
        fis.close();
    }


}
View Code

高效字節流:將原有IO流進行包裝,使其效率更高。

高效字節輸出流:BufferedOutputStream

高效字節輸入流:BufferedInputStream

例子:cn.itcast3.demo4

技術分享
package cn.itcast3;

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

/*
 *    高效字節流:
 *        BufferedInputStream
 *        BufferedOutputStream
 *
 *        構造方法:均要一個對應的流對象
 *                public BufferedOutputStream(OutputStream out)創建一個新的緩沖輸出流,以將數據寫入指定的底層輸出流。
 *          public BufferedInputStream(InputStream in)創建一個 BufferedInputStream 並保存其參數,即輸入流 in,以便將來使用。創建一個內部緩沖區  *                數組並將其存儲在 buf 中。
 *            
 */
public class Demo4 {

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

        long currentTimeMillis = System.currentTimeMillis();
        //創建輸入流對象
        FileInputStream fis = new FileInputStream("b.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        //創建輸出流對象
        FileOutputStream fos = new FileOutputStream("b2.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        
        //讀入
        byte[] bytes = new byte[2];
        int len;
        while((len=bis.read(bytes))!=-1) {
            //寫出
            bos.write(bytes, 0, len);
            bos.flush();  //刷新此緩沖的輸出流。這迫使所有緩沖的輸出字節被寫出到底層輸出流中。 
        }

        
        //關閉流
        bos.close();
        bis.close();
        long currentTimeMillis2 = System.currentTimeMillis();
        
        System.out.println(currentTimeMillis2-currentTimeMillis);
    }

}
View Code

字符流

字符輸入流 Reader

字符輸出流 Writer

註意:

A:四個頂層類都是抽象類。

B:一般每個體系的流都是以基類作為後綴名。

什麽時候使用誰?

如果文件能夠通過記事本打開並讀懂,就用字符流。

其他的全部使用字節流。

3:字節流(掌握)

InputStream

|--FileInputStream

|--BufferedInputStream

OutputStream

|--FileOutputStream

|--BufferedOutputSteam

掌握:(4種方式)

是否使用數組

是否使用高效

把c:\\a.jpg復制到d:\\b.jpg中。

---------------------------------------

4、例子

(1):使用普通字節流完成文件復制

一次一個字節 188毫秒

一次一個字節數組 0毫秒

技術分享
package cn;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 文件復制:
 * (1)使用普通字節流,一次一個字節的復制。
 * (2)使用普通字節流,一次復制一個字節數組。
 */
public class Demo4 {
    public static void main(String[] args) throws IOException {
        long currentTimeMillis = System.currentTimeMillis();
         //method();  //188毫秒
        method2(); //1毫秒
        long currentTimeMillis2 = System.currentTimeMillis();
        System.out.println(currentTimeMillis2 - currentTimeMillis);

    }

    //(1)一次一個字節的復制。
    public static void method() throws IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");

        //
        int c;
        while ((c = fis.read()) != -1) {
            //
            fos.write(c);
        }

        //關閉流
        fis.close();
        fos.close();
    }

    //(2)一次一個字節數組的復制。
    public static void method2() throws IOException {
        //創建流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");

        //
        byte[] bytes = new byte[1024];//創建自己數組
        int len;//保存每次讀取的字節的長度
        while ((len = fis.read(bytes)) != -1) {
          /* String s= new String(bytes,0,len);
            //寫
            fos.write(s.getBytes());*/
            fos.write(bytes, 0, len);
        }

        //關閉流
        fis.close();
        fos.close();
    }

}
View Code

(2):使用高效字節流完成文件復制

一次一個字節 6毫秒

一次一個字節數組 0毫秒

技術分享
package cn;

import java.io.*;


/**
 * (1)使用高效字節流,一次復制一個字節
 * (2)使用高效字節流,一次復制一個字節數組
 */
public class Demo5 {
    public static void main(String[] args) throws IOException {
        long currentTimeMillis = System.currentTimeMillis();
       // method(); //6毫秒
        method2(); //0毫秒
        long currentTimeMillis2 = System.currentTimeMillis();
        System.out.println(currentTimeMillis2 - currentTimeMillis);
    }

    //(1)使用普通字節流,一次復制一個字節數組
    public static void method() throws IOException {
        //創建輸入、輸出流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");

        //創建高效輸入、輸出流對象
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //
        int c;
        while ((c = bis.read()) != -1) {
            //
            bos.write(c);
        }

        //關閉流
        bos.close();
        bis.close();
    }


    //(2)使用高效字節流,一次復制一個字節數組
    public static void method2() throws IOException {
        //創建輸入、輸出流對象
        FileInputStream fis = new FileInputStream("b.txt");
        FileOutputStream fos = new FileOutputStream("b2.txt");

        //創建高效輸入、輸出流對象
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        //
        int len;
        byte[] bytes = new byte[1024];
        while ((len = bis.read(bytes)) != -1) {
            //
            bos.write(bytes, 0, len);
            bos.flush();
        }

        //關閉流
        bos.close();
        bis.close();
    }

}
View Code

(3):比較四種方式的運算時間,並總結規律。

遞歸、字節流、文件復制_DAY20