Java IO流之字符流

①I(mǎi)O流(字符流FileReader)

  • 1.字符流是什么
    • 字符流是可以直接讀寫(xiě)字符的IO流
    • 字符流讀取字符, 就要先讀取到字節(jié)數(shù)據(jù), 然后轉(zhuǎn)為字符. 如果要寫(xiě)出字符, 需要把字符轉(zhuǎn)為字節(jié)再寫(xiě)出.
  • 2.FileReader
    • FileReader類(lèi)的read()方法可以按照字符大小讀取
  •   FileReader fr = new FileReader("aaa.txt");                //創(chuàng)建輸入流對(duì)象,關(guān)聯(lián)aaa.txt
      int ch;
      while((ch = fr.read()) != -1) {                            //將讀到的字符賦值給ch
          System.out.println((char)ch);                        //將讀到的字符強(qiáng)轉(zhuǎn)后打印
      }
      
      fr.close();                                                //關(guān)流 
    

②IO流(字符流FileWriter)

  • FileWriter類(lèi)的write()方法可以自動(dòng)把字符轉(zhuǎn)為字節(jié)寫(xiě)出

      FileWriter fw = new FileWriter("aaa.txt");
      fw.write("aaa");
      fw.close();
    

③IO流(字符流的拷貝)

FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

int ch;
while((ch = fr.read()) != -1) {
    fw.write(ch);
}

fr.close();
fw.close();

④IO流(什么情況下使用字符流)

  • 字符流也可以拷貝文本文件, 但不推薦使用. 因?yàn)樽x取時(shí)會(huì)把字節(jié)轉(zhuǎn)為字符, 寫(xiě)出時(shí)還要把字符轉(zhuǎn)回字節(jié).
  • 程序需要讀取一段文本, 或者需要寫(xiě)出一段文本的時(shí)候可以使用字符流
  • 讀取的時(shí)候是按照字符的大小讀取的,不會(huì)出現(xiàn)半個(gè)中文
  • 寫(xiě)出的時(shí)候可以直接將字符串寫(xiě)出,不用轉(zhuǎn)換為字節(jié)數(shù)組

⑤IO流(字符流是否可以拷貝非純文本的文件)

  • 不可以拷貝非純文本的文件
  • 因?yàn)樵谧x的時(shí)候會(huì)將字節(jié)轉(zhuǎn)換為字符,在轉(zhuǎn)換過(guò)程中,可能找不到對(duì)應(yīng)的字符,就會(huì)用?代替,寫(xiě)出的時(shí)候會(huì)將字符轉(zhuǎn)換成字節(jié)寫(xiě)出去
  • 如果是?,直接寫(xiě)出,這樣寫(xiě)出之后的文件就亂了,看不了了

⑥IO流(自定義字符數(shù)組的拷貝)

  •   FileReader fr = new FileReader("aaa.txt");            //創(chuàng)建字符輸入流,關(guān)聯(lián)aaa.txt
      FileWriter fw = new FileWriter("bbb.txt");            //創(chuàng)建字符輸出流,關(guān)聯(lián)bbb.txt
      
      int len;
      char[] arr = new char[1024*8];                        //創(chuàng)建字符數(shù)組
      while((len = fr.read(arr)) != -1) {                    //將數(shù)據(jù)讀到字符數(shù)組中
          fw.write(arr, 0, len);                            //從字符數(shù)組將數(shù)據(jù)寫(xiě)到文件上
      }
      
      fr.close();                                            //關(guān)流釋放資源
      fw.close();    
    

⑦IO流(帶緩沖的字符流)

  • BufferedReader的read()方法讀取字符時(shí)會(huì)一次讀取若干字符到緩沖區(qū), 然后逐個(gè)返回給程序, 降低讀取文件的次數(shù), 提高效率
  • BufferedWriter的write()方法寫(xiě)出字符時(shí)會(huì)先寫(xiě)到緩沖區(qū), 緩沖區(qū)寫(xiě)滿(mǎn)時(shí)才會(huì)寫(xiě)到文件, 降低寫(xiě)文件的次數(shù), 提高效率
  •   BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));    //創(chuàng)建字符輸入流對(duì)象,關(guān)聯(lián)aaa.txt
      BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));    //創(chuàng)建字符輸出流對(duì)象,關(guān)聯(lián)bbb.txt
      
      int ch;                
      while((ch = br.read()) != -1) {        //read一次,會(huì)先將緩沖區(qū)讀滿(mǎn),從緩沖去中一個(gè)一個(gè)的返給臨時(shí)變量ch
          bw.write(ch);                    //write一次,是將數(shù)據(jù)裝到字符數(shù)組,裝滿(mǎn)后再一起寫(xiě)出去
      }
      
      br.close();                            //關(guān)流
      bw.close();  
    

⑧IO流(readLine()和newLine()方法)

  • BufferedReader的readLine()方法可以讀取一行字符(不包含換行符號(hào))
  • BufferedWriter的newLine()可以輸出一個(gè)跨平臺(tái)的換行符號(hào)"\r\n"
  •   BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
      BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
      String line;
      while((line = br.readLine()) != null) {
          bw.write(line);
          //bw.write("\r\n");                    //只支持windows系統(tǒng)
          bw.newLine();                        //跨平臺(tái)的
      }
      
      br.close();
      bw.close(); 
    

⑨IO流(將文本反轉(zhuǎn))

  • 將一個(gè)文本文檔上的文本反轉(zhuǎn),第一行和倒數(shù)第一行交換,第二行和倒數(shù)第二行交換

⑩IO流(LineNumberReader)

  • LineNumberReader是BufferedReader的子類(lèi), 具有相同的功能, 并且可以統(tǒng)計(jì)行號(hào)
    • 調(diào)用getLineNumber()方法可以獲取當(dāng)前行號(hào)
    • 調(diào)用setLineNumber()方法可以設(shè)置當(dāng)前行號(hào)
  •   LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
      String line;
      lnr.setLineNumber(100);                                    //設(shè)置行號(hào)
      while((line = lnr.readLine()) != null) {
          System.out.println(lnr.getLineNumber() + ":" + line);//獲取行號(hào)
      }
      
      lnr.close(); 
    

11、IO流(裝飾設(shè)計(jì)模式)

  •   interface Coder {
          public void code();
      }
      
      class Student implements Coder {
      
          @Override
          public void code() {
              System.out.println("javase");
              System.out.println("javaweb");
          }
          
      }
      
      class HeiMaStudent implements Coder {
          private Student s;                        //獲取到被包裝的類(lèi)的引用
          public ItcastStudent(Student s) {        //通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象的時(shí)候,傳入被包裝的對(duì)象
              this.s = s;
          }
          @Override
          public void code() {                    //對(duì)其原有功能進(jìn)行升級(jí)
              s.code();
              System.out.println("數(shù)據(jù)庫(kù)");
              System.out.println("ssh");
              System.out.println("安卓");
              System.out.println(".....");
          }
          
      } 
    

12、IO流(使用指定的碼表讀寫(xiě)字符)

  • FileReader是使用默認(rèn)碼表讀取文件, 如果需要使用指定碼表讀取, 那么可以使用InputStreamReader(字節(jié)流,編碼表)
  • FileWriter是使用默認(rèn)碼表寫(xiě)出文件, 如果需要使用指定碼表寫(xiě)出, 那么可以使用OutputStreamWriter(字節(jié)流,編碼表)
  •   BufferedReader br =                                     //高效的用指定的編碼表讀
              new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8"));
      BufferedWriter bw =                                     //高效的用指定的編碼表寫(xiě)
              new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));
      int ch;
      while((ch = br.read()) != -1) {
          bw.write(ch);
      }
      
      br.close();
      bw.close();
    

13、File類(lèi)(遞歸)

  • 5的階乘
    package com.heima.chario;
/**
 * @param args
 * 遞歸:方法自己調(diào)用自己
 * 5!
 * 5 * 4 * 3 * 2 * 1
 * 
 * 5 * fun(4)(代表4!)
 *         4 * fun(3)(代表3!)
 *                 3 * fun(2)(代表2!) 
 *                         2 * fun(1)(代表1!)
 * 遞歸的弊端:不能調(diào)用次數(shù)過(guò)多,容易導(dǎo)致棧內(nèi)存溢出
 * 遞歸的好處:不用知道循環(huán)次數(shù)
 * 
 * 構(gòu)造方法是否可以遞歸調(diào)用?
 * 構(gòu)造方法不能使用遞歸調(diào)用
 * 
 * 遞歸調(diào)用是否必須有返回值?
 * 不一定(可以有,也可以沒(méi)有)
 */
public static void main(String[] args) {
    /*int result = 1;
    
    for(int i = 1; i <= 5; i++) {
        result = result * i;
    }
    
    System.out.println(result);*/
    System.out.println(fun(6000));
}

public static int fun(int num) {
    if(num == 1) {
        return 1;
    }else {
        return num * fun(num - 1);
    }
}

14、File類(lèi)(練習(xí))

  • 需求:從鍵盤(pán)輸入接收一個(gè)文件夾路徑,打印出該文件夾下所有的.java文件名

/**
* 需求:從鍵盤(pán)輸入接收一個(gè)文件夾路徑,打印出該文件夾下所有的.java文件名
*
* 分析:
* 從鍵盤(pán)接收一個(gè)文件夾路徑
* 1,如果錄入的是不存在,給與提示
* 2,如果錄入的是文件路徑,給與提示
* 3,如果是文件夾路徑,直接返回
*
* 打印出該文件夾下所有的.java文件名
* 1,獲取到該文件夾路徑下的所有的文件和文件夾,存儲(chǔ)在File數(shù)組中
* 2,遍歷數(shù)組,對(duì)每一個(gè)文件或文件夾做判斷
* 3,如果是文件,并且后綴是.java的,就打印
* 4,如果是文件夾,就遞歸調(diào)用
*/
public static void main(String[] args) {
File dir = getDir();
printJavaFile(dir);
}

/*
 * 獲取鍵盤(pán)錄入的文件夾路徑
 * 1,返回值類(lèi)型File
 * 2,不需要有參數(shù)
 */
public static File getDir() {
    Scanner sc = new Scanner(System.in);                //創(chuàng)建鍵盤(pán)錄入對(duì)象
    System.out.println("請(qǐng)輸入一個(gè)文件夾路徑");
    while(true) {
        String line = sc.nextLine();                    //將鍵盤(pán)錄入的文件夾路徑存儲(chǔ)
        File dir = new File(line);                        //封裝成File對(duì)象
        if(!dir.exists()) {
            System.out.println("您錄入的文件夾路徑不存在,請(qǐng)重新錄入");
        }else if(dir.isFile()) {
            System.out.println("您錄入的是文件路徑,請(qǐng)重新錄入文件夾路徑");
        }else {
            return dir;
        }
    }
}
/*
 * 獲取文件夾路徑下的所.java文件
 * 1,返回值類(lèi)型 void
 * 2,參數(shù)列表File dir
 */
public static void printJavaFile(File dir) {
    //1,獲取到該文件夾路徑下的所有的文件和文件夾,存儲(chǔ)在File數(shù)組中
    File[] subFiles = dir.listFiles();
    //2,遍歷數(shù)組,對(duì)每一個(gè)文件或文件夾做判斷
    for (File subFile : subFiles) {
        //3,如果是文件,并且后綴是.java的,就打印
        if(subFile.isFile() && subFile.getName().endsWith(".java")) {
            System.out.println(subFile);
        //4,如果是文件夾,就遞歸調(diào)用
        }else if (subFile.isDirectory()){
            printJavaFile(subFile);
        }
    }
}

15、IO流(總結(jié))

  • 1.會(huì)用BufferedReader讀取GBK碼表和UTF-8碼表的字符
  • 2.會(huì)用BufferedWriter寫(xiě)出字符到GBK碼表和UTF-8碼表的文件中
  • 3.會(huì)使用BufferedReader從鍵盤(pán)讀取一行
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • IO流 看著字少,內(nèi)容著實(shí)不少,這里開(kāi)始就給諸君推薦一篇大神的博客,總結(jié)的思路清晰,鬼斧神工,哈哈,總之總結(jié)的很好...
    向日花開(kāi)閱讀 847評(píng)論 0 8
  • 概述 計(jì)算機(jī)并不區(qū)分二進(jìn)制文件與文本文件。所有的文件都是以二進(jìn)制形式來(lái)存儲(chǔ)的,因此,從本質(zhì)上說(shuō),所有的文件都是二進(jìn)...
    奮斗的老王閱讀 1,359評(píng)論 0 51
  • 一、IO流整體結(jié)構(gòu)圖 流是一組有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q(chēng)或抽象。即數(shù)據(jù)在兩設(shè)備間的傳輸稱(chēng)...
    慕凌峰閱讀 1,190評(píng)論 0 12
  • 概述: 1、IO流:即Input Output的縮寫(xiě)。 2、特點(diǎn):1)IO流用來(lái)處理設(shè)備間的數(shù)據(jù)傳輸。2)Java...
    玉圣閱讀 1,265評(píng)論 0 3
  • 導(dǎo)語(yǔ): 打開(kāi)簡(jiǎn)書(shū),看到自己的文章被瀏覽了五十多次的時(shí)候真的很開(kāi)心,然后發(fā)現(xiàn)有幾個(gè)喜歡一個(gè)粉絲的時(shí)候,真的是非常開(kāi)心...
    我是小徐同學(xué)閱讀 818評(píng)論 5 17