Java編程基礎22——IO(字符流)&字符流其餘內容&遞歸

1_字符流FileReader

  • 1.字符流是什麼java

    • 字符流是能夠直接讀寫字符的IO流
    • 字符流讀取字符, 就要先讀取到字節數據, 而後轉爲字符. 若是要寫出字符, 須要把字符轉爲字節再寫出.
  • 2.FileReadermysql

    • FileReader類的read()方法能夠按照字符大小讀取
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo1_FileReader {
    public static void main(String[] args) throws IOException {
//        demo1();
        FileReader fr = new FileReader("xxx.txt");
        int c;
        while((c = fr.read()) != -1) {    //經過項目默認的碼錶一次讀取一個字符,賦值給c
            System.out.print((char)c);    //將讀到的字符強轉後打印
        }
        fr.close();
    }

    private static void demo1() throws FileNotFoundException, IOException {
        FileReader fr = new FileReader("xxx.txt");
        int x = fr.read();
        System.out.println(x);
        char c = (char)x;
        System.out.println(c);
        fr.close();
    }
}

2_字符流FileWriter

  • FileWriter類的write()方法能夠自動把字符轉爲字節寫出
import java.io.FileWriter;
import java.io.IOException;
public class Demo2_fileWriter {
    public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter("yyy.txt");
        fw.write("你們好,SE快學完了!");
        fw.write(97);
        fw.close();
    }
}

3_字符流的拷貝

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo3_Copy {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("xxx.txt");
        FileWriter fw = new FileWriter("zzz.txt");
        
        int c;
        while((c = fr.read()) != -1) {
            fw.write(c);
        }
        
        fr.close();
        //Writer類中有一個2k的小緩衝區,若是不關流,就會將內容寫到緩衝區裏,關流會將緩衝區內容寫出並結束
        fw.close();            
    }
}

4_什麼狀況下使用字符流

  • 字符流也能夠拷貝文本文件, 但不推薦使用. 由於讀取時會把字節轉爲字符, 寫出時還要把字符轉回字節.
  • 程序須要讀取一段文本, 或者須要寫出一段文本的時候可使用字符流
  • 讀取的時候是按照字符的大小讀取的,不會出現半個中文
  • 寫出的時候能夠直接將字符串寫出,不用轉換爲字節數組

圖片描述

5_字符流是否能夠拷貝非純文本的文件

  • 不能夠拷貝非純文本的文件
  • 由於在讀的時候會將字節轉換爲字符,在轉換過程當中,可能找不到對應的字符,就會用?代替,寫出的時候會將字符轉換成字節寫出去,若是是?,直接寫出,這樣寫出以後的文件就亂了,看不了了。

6_自定義字符數組的拷貝

public static void main(String[] args) throws IOException {    
        FileReader fr = new FileReader("xxx.txt");
        FileWriter fw = new FileWriter("yyy.txt");
        
        char[] arr = new char[1024];
        
        int len;
        while((len = fr.read(arr)) != -1) {        //將文件上的數據讀取到字符數組中
            fw.write(arr, 0, len);                //將字符數組中的數據寫到文件上
        }
        
        fr.close();
        fw.close();
    }

7_帶緩衝的字符流

  • BufferedReader的read()方法讀取字符時會一次讀取若干字符到緩衝區, 而後逐個返回給程序, 下降讀取文件的次數, 提升效率
  • BufferedWriter的write()方法寫出字符時會先寫到緩衝區, 緩衝區寫滿時纔會寫到文件, 下降寫文件的次數, 提升效率
public static void main(String[] args) throws IOException {
        BufferedReader    br = new BufferedReader(new FileReader("xxx.txt"));
        BufferedWriter    bw = new BufferedWriter(new FileWriter("yyy.txt"));
        
        int c;
        while((c = br.read()) != -1) {    //read一次,會先將緩衝區讀滿,從緩衝去中一個一個的返給臨時變量c
            bw.write(c);                //write一次,是將數據裝到字符數組,裝滿後再一塊兒寫出去
        }
        
        br.close();
        bw.close();
    }

8_readLine()和newLine()方法

  • BufferedReader的readLine()方法能夠讀取一行字符(不包含換行符號)
  • BufferedWriter的newLine()能夠輸出一個跨平臺的換行符號"rn"
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo4_Buffered {
    public static void main(String[] args) throws IOException {
//        demo1();
        BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("aaa.txt"));
        String line;
        while((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();            //寫出回車換行符,跨平臺的
            bw.write("\r\n");        //只支持windows系統
        }
        br.close();
        bw.close();
    }
    private static void demo1() throws FileNotFoundException, IOException {
        BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}

9_將文本反轉

  • 將一個文本文檔上的文本反轉,第一行和倒數第一行交換,第二行和倒數第二行交換
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Demo5_test {
    public static void main(String[] args) throws IOException {
        //1.建立輸入輸出流對象
        BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
        
        //2.建立集合對象
        ArrayList<String> list = new ArrayList<>();
        
        //3.將讀到的數據存儲在集合中
        String line;
        while((line = br.readLine()) != null) {
            list.add(line);
        }
        br.close();//晚開早關
        //4.倒着遍歷集合將數據寫到文件上
        BufferedWriter bw = new BufferedWriter(new FileWriter("revzzz.txt"));//晚開早關
        for (int i = list.size() - 1; i >= 0; i--) {
            bw.write(list.get(i));
            bw.newLine();
        }
        //5.關流
        bw.close();
    }
}

10_LineNumberReader

  • LineNumberReader是BufferedReader的子類, 具備相同的功能, 而且能夠統計行號spring

    • 調用getLineNumber()方法能夠獲取當前行號
    • 調用setLineNumber()方法能夠設置當前行號
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class Demo6_LineNumberReader {
    public static void main(String[] args) throws IOException {
        LineNumberReader lnr = new LineNumberReader(new FileReader("zzz.txt"));
        
        String line;
        lnr.setLineNumber(100);            //設置行號
        while((line = lnr.readLine()) != null) {
            System.out.println(lnr.getLineNumber() + ":" + line);    //獲取行號
        }
        
        lnr.close();
    }
}

11_裝飾設計模式

  • 優勢:耦合性不強,被裝飾的類的變化與裝飾類的變化無關
public class Demo7_Wrap {
    public static void main(String[] args) {
        AllIdea ai = new AllIdea(new Student());
        ai.code();
    }
}

interface Coder{
    public void code();
}

class Student implements Coder{

    @Override
    public void code() {
        System.out.println("JavaSE");
        System.out.println("JavaWEB");
    }
}

class AllIdea implements Coder{
    //1.獲取被裝飾類的引用
    private Student s;
    //2.在構造方法中傳入被裝飾的對象
    public AllIdea(Student s) {
        this.s = s;
    }
    //3.對原有的功能進行升級
    @Override
    public void code() {
        s.code();
        System.out.println("mysql");
        System.out.println("spring");
    }
}

12_使用指定的碼錶讀寫字符

  • FileReader是使用默認碼錶讀取文件, 若是須要使用指定碼錶讀取, 那麼可使用InputStreamReader(字節流,編碼表)
  • FileWriter是使用默認碼錶寫出文件, 若是須要使用指定碼錶寫出, 那麼可使用OutputStreamWriter(字節流,編碼表)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class Demo8_TransIO {
    public static void main(String[] args) throws IOException {
//        demo1();
//        demo2();
        BufferedReader br =                         //更高效的讀
                new BufferedReader(new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8"));
        BufferedWriter bw =                         //更高效的寫
                new BufferedWriter(new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk"));
        
        int c;
        while((c = br.read()) != -1) {
            bw.write(c);
        }
        br.close();
        bw.close();
    }

    private static void demo2() throws UnsupportedEncodingException, FileNotFoundException, IOException {
        //用指定碼錶讀字符
        InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "utf-8");
        //用指定碼錶寫字符
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "gbk");
        
        int c;
        while((c = isr.read()) != -1) {
            osw.write(c);
        }
        
        isr.close();
        osw.close();
    }

    private static void demo1() throws FileNotFoundException, IOException {
        //用默認碼錶讀寫,出現亂碼
        FileReader fr = new FileReader("utf-8.txt");
        FileWriter fw = new FileWriter("gbk.txt");
        
        int c;
        while((c = fr.read()) != -1) {
            fw.write(c);
        }
        
        fr.close();
        fw.close();
    }
}

13_轉換流圖解

  • 畫圖分析轉換流

圖片描述

14_獲取文本上字符出現的次數

  • 獲取一個文本上每一個字符出現的次數,將結果寫在times.txt上
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.TreeMap;

public class Demo91_test {
    public static void main(String[] args) throws IOException {
        //1.建立帶緩衝的輸入流對象
        BufferedReader br = new BufferedReader(new FileReader("zzz.txt"));
        //2.建立雙列集合對象TreeMap
        TreeMap<Character, Integer>    tm = new TreeMap<>();
        //3.將讀到的字符存儲在雙列集合中,存儲的時候要作判斷,若是不包含這個鍵,就將鍵和1存儲,
        //若是包含這個鍵,就將該鍵和值加1存儲
        int ch;
        while((ch = br.read()) != -1) {
            char c = (char)ch;                //向下強制類型轉換
            /*if(!tm.containsKey(c)) {
                tm.put(c, 1);
            }else {
                tm.put(c, tm.get(c) + 1);
            }*/
            tm.put(c, !tm.containsKey(c) ? 1 : tm.get(c) + 1);
        }
        //4.關閉輸入流
        br.close();
        //5.建立輸出流對象
        BufferedWriter bw = new BufferedWriter(new FileWriter("times.txt"));
        //6.遍歷集合將集合中的內容寫到times.txt中
        for (Character key : tm.keySet()) {
            switch (key) {
            case '\t':
                bw.write("\\t" + "=" + tm.get(key));
                break;
            case '\n':
                bw.write("\\n" + "=" + tm.get(key));
                break;
            case '\r':
                bw.write("\\r" + "=" + tm.get(key));
                break;
            default:
                bw.write(key + "=" + tm.get(key));    //寫出鍵和值
                break;
            }
            bw.newLine();
        }
        //7.關閉輸出流
        bw.close();
    }
}

15_試用版軟件

  • 當咱們下載一個試用版軟件,沒有購買正版的時候,每執行一次就會提醒咱們還有多少次使用機會用學過的IO流知識,模擬試用版軟件,試用10次機會,執行一次就提示一次您還有幾回機會,若是次數到了提示請購買正版
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo92_test {
    public static void main(String[] args) throws IOException {
        //1.建立帶緩衝的輸入流對象,由於要使用readLine方法,能夠保證數據的原樣性
        BufferedReader br = new BufferedReader(new FileReader("config.txt"));
        //2.將讀到的字符串轉換爲int數
        String line = br.readLine();
        int times = Integer.parseInt(line);        //將數字字符串轉換爲數字
        //3.對int數進行判斷,若是大於0,就將其一一寫回去,若是不大於0,就提示請購買正版。
        if(times > 0) {
            //4.在if判斷中要將--的結果打印,並將結果經過輸出流寫到文件上
            System.out.println("您還有" + times-- + "次機會");
            FileWriter fw = new FileWriter("config.txt");
            fw.write(times-- + "");
            fw.close();
        }else {
            System.out.println("您的試用次數已到,請購買正版");
        }
        br.close();
    }
}

16_File類(遞歸)

  • 概念:方法本身調用本身sql

    • 弊端:是不能調用次數過多,容易致使棧內存溢出
    • 好處:不用知道循環次數
    • 構造方法不能試用遞歸調用
    • 遞歸調用是否必須有返回值(能夠有也能夠沒有)
  • 案例:5的階乘(5!)
5 * 4 * 3 * 2 * 1   
  5 * fun(4)(表明4!)
           4 * fun(3)(表明3!)
               3 * fun(2)(表明2!)
                   2 * fun(1)(表明1!)
public class Demo93_recursive {
    public static void main(String[] args) {
//        demo1();
        System.out.println(fun(10));
    }
    
    public static int fun(int num) {
        if(num == 1) {
            return 1;
        }else {
            return num * fun(num - 1);
        }
    }

    private static void demo1() {
        int result = 1;
        for(int i = 1; i <= 5; i++) {
            result = result * i;
        }
        System.out.println(result);
    }
}

17_File類(練習)

  • 需求:從鍵盤輸入接收一個文件夾路徑,打印出該文件夾下全部的.java文件名
import java.io.File;
import java.util.Scanner;
public class Demo94_test {
    public static void main(String[] args) {
        File dir = getDir();
        printJavaFile(dir);
    }
    /*獲取鍵盤錄入的文件夾路徑
     * 1.返回值類型File
     * 2.不須要有參數*/
    public static File getDir() {
        Scanner sc = new Scanner(System.in);            //建立鍵盤錄入對象
        System.out.println("請輸入一個文件夾路徑");
        while (true) {
            String line = sc.nextLine();                //將鍵盤錄入的文件夾路徑存儲
            File dir = new File(line);
            if(!dir.exists()) {
                System.out.println("您錄入的文件夾路徑不存在,請從新錄入");
            }else if(dir.isFile()) {
                System.out.println("您錄入的是文件路徑,請從新錄入文件夾路徑");
            }else {
                return dir;
            }
        }
    }
    /*獲取文件夾路徑下的全部.java文件
     * 1.返回值類型void
     * 2.參數列表File dir*/
    public static void printJavaFile(File dir) {
        //1.獲取到該文件夾路徑下的全部文件和文件夾,存儲在File數組中
        File[] subFiles = dir.listFiles();
        //2.遍歷數組,對每個文件或文件夾判斷
        for(File subFile : subFiles) {
        //3.若是是文件,而且是.java的就打印
            if(subFile.isFile() && subFile.getName().endsWith(".java")) {
                System.out.println(subFile);
            //4.若是是文件夾,就遞歸調用    
            }else if(subFile.isDirectory()) {
                printJavaFile(subFile);
            }
        }
    }
}

18_總結

  • 1.會用BufferedReader讀取GBK碼錶和UTF-8碼錶的字符
  • 2.會用BufferedWriter寫出字符到GBK碼錶和UTF-8碼錶的文件中
  • 3.會使用BufferedReader從鍵盤讀取一行
相關文章
相關標籤/搜索