Java基礎(chǔ) - IO流

6.IO流

6.1 File

系統(tǒng)中我們一眼看到的就是文件或者文件夾
本質(zhì)是一個路徑(字符串);用字符串來表示這個路徑不符合面向?qū)ο?/p>

File類對路徑的字符串進(jìn)行面向?qū)ο蟮姆庋b,是文件和文件夾路徑的抽象表現(xiàn)形式

基本操作:

  • 構(gòu)造方法

      File(String pathname) 將給定的路徑名字符串轉(zhuǎn)為抽象路徑名來創(chuàng)建一個File實(shí)例
    
      例子:  new File("D:java/testDoc/test.java") //文件路徑
            new File("D:java/testDoc") //文件夾路徑
      
      File(String parent, String child) 根據(jù)父路徑字符串和子路徑字符串創(chuàng)建一個File實(shí)
    
      例子:new File("D:java","/testDoc/test.java") //文件
      例子:new File("D:java","/testDoc") //文件夾
    
  • 創(chuàng)建

    • 創(chuàng)建文件夾

        mkdir():創(chuàng)建文件夾
        
        mkdirs():?創(chuàng)建多級文件夾
      
    • 創(chuàng)建文件

        createNewFile():創(chuàng)建文件
      
    • 重命名

        renameTo():給文件或文件夾重命名
      
  • 判斷

      exists():判斷此路徑是否存在
    
      isFile():判斷是否文件
    
      isDirectory():判斷是否文件夾
    
  • 獲取

      getAbsolutePath():獲取絕對路徑,包括根路徑
    
      getName():獲取相對路徑(文件名或者文件夾名).不包括根路徑
    
      length():獲取文件的大小,單位是字節(jié)
    
  • 刪除

      delete():刪除文件
      
      deleteOnExit():在程序退出的時(shí)候刪除文件
    
  • 示例代碼:

      //創(chuàng)建File實(shí)例對象,路徑的抽象表現(xiàn)
      File file = new File("D:java/testDoc/test.java");
      // File file = new File("D:java/testDoc");
      // File file = new File("D:java","testDoc/test.java");
      //判斷路徑是否存在
      if (!file.exists()){
          //判斷是否是文件路徑
          if (file.isFile()){
              //創(chuàng)建文件
              file.createNewFile();
          }
          //判斷是否是文件夾路徑
          if (file.isDirectory()){
              //創(chuàng)建文件夾
              file.mkdir();
          }
      }
      //獲取絕對路徑
      System.out.println(file.getAbsoluteFile()); // 輸出 /D:java/testDoc/test.java
      //獲取相對路徑(文件名或者文件夾名)
      System.out.println(file.getName()); // 輸出test.java
    

File類的高級獲取

  • 方法:
    listFiles():返回一個File數(shù)組,包括了路徑名下的的所有文件和文件夾路徑名

    listRoots():此方法是靜態(tài)的,返回路徑名下的所有根路徑

    listFiles(FileFilter filter):返回File數(shù)組,數(shù)組是有經(jīng)過過濾器FileFilter篩選的

    FileFilter 重寫的方法: accept(File pathname)  返回true表示需包含在數(shù)組內(nèi),不要去掉
  • 示例代碼1:

      if (file != null && file.isDirectory()) {
          //打印文件夾
          System.out.println(file);
          //列出所有的文件和文件夾路徑
          File[] files = file.listFiles();
          for (File f : files) {
              //遞歸調(diào)用,找出所有的文件 文件夾
              testFileSearch(f);
          }
      } else {
          //打印文件
          System.out.println(file);
      }
    
  • 示例代碼2

      if (file != null && file.isDirectory()) {
          File[] files = file.listFiles(new FileFilter() {
              @Override
              public boolean accept(File file) {
                  //.class結(jié)尾的需要保留,不要去掉
                  return file.getName().endsWith(".class");
              }
          });
      }
    

6.2 IO流基類

  1. 字節(jié)輸入流 InputStream

  2. 字節(jié)輸出流 OutputStream

  3. 字符輸入流 Reader

  4. 字符輸出流 Writer

特點(diǎn):

  • 四大基類都是抽象類,核心功能一句話總結(jié):讀進(jìn)來,寫出去

    • 輸出流:將數(shù)據(jù)寫到目標(biāo)中去

    • 輸入流:從源中讀取數(shù)據(jù)

  • 所有的流都是資源對象谁榜,最后使用完都必須關(guān)閉資源

  • 字節(jié)流比較通用

  • IO流的操作模板

      1):定義源或目標(biāo)  源:輸入流  目標(biāo):輸出流
    
      2):根據(jù)源和目標(biāo)創(chuàng)建流對象
    
      3):進(jìn)行讀/寫操作
    
      4):關(guān)閉資源
    

6.2.1 字節(jié)流

字節(jié)輸入流  InputStream

字節(jié)輸出流  OutputStream 

字節(jié)文件流

1-1.FileOutputStream

將數(shù)據(jù)寫到目標(biāo)文件中

  • 構(gòu)造方法

          FileOutputStream(File file) 創(chuàng)建向指定File對象的目標(biāo)文件中寫入數(shù)據(jù)的文件輸出流 
    
          FileOutputStream(String name) 創(chuàng)建向指定名稱的目標(biāo)文件中寫入數(shù)據(jù)的文件輸出流
    
          FileOutputStream(String name, boolean append) append 是否在源數(shù)據(jù)中追加
    
  • 常用方法

          write(int b) //將指定數(shù)量的字節(jié)寫到輸入流
    
          write(byte[] b,int off, int len ) 將指定的byte數(shù)組從off索引開始的len個字節(jié)寫到輸出流
    
  • 分析流對象的創(chuàng)建

          1.創(chuàng)建了輸出流對象
    
          2.通知系統(tǒng)去檢查目標(biāo)文件,如果不存在則創(chuàng)建出來
    
          3.將這個輸出流對象與硬盤上的文件關(guān)聯(lián)起來
    
  • 示例代碼:

          String dest = "d:/java/test.txt"; //輸出的目標(biāo)文件路徑
          try {
              //創(chuàng)建流對象,如果文件不存在,則會自動創(chuàng)建文件
              FileOutputStream fo = new FileOutputStream(dest);
              byte[] bytes = "hello".getBytes();//需要寫到流的數(shù)據(jù)
              fo.write(bytes,2,3);
              fo.close();//關(guān)閉流,釋放資源,等待GC回收
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
    

1-2.FileInputStream

從源文件讀取數(shù)據(jù)

  • 構(gòu)造方法

          FileInputStream(String name)
    
          FileInputStream(File file)   創(chuàng)建從源文件中讀取數(shù)據(jù)的輸入流對象
    
  • 常用方法

          read()  從輸入流中讀取數(shù)據(jù)的下一個字節(jié),
                  返回值是讀取到的字節(jié),如果為-1表示已讀完
    
          read(byte[] b)  從輸入流中讀取數(shù)據(jù)的一定數(shù)量字節(jié),并存儲到緩沖數(shù)組b中.
                          返回值是讀取的字節(jié)個數(shù),如果為-1表示已讀完
    
  • 示例代碼:

          //源
          String path = "d:/java/in.txt";
          //根據(jù)源創(chuàng)建輸入流對象
          try {
              FileInputStream fi = new FileInputStream(path);
              //定義一個緩沖數(shù)組
              byte[] bytes = new byte[1024 * 1024];
              fi.read(bytes);
              int len;//記錄讀取了多少個字節(jié)
              while ((len = fi.read(bytes)) != -1) { //不等于-1 表示還有數(shù)據(jù)
                  System.out.println(new String(bytes, 0, len));
              }
              fi.close();
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
    

緩沖流

  • 特點(diǎn)

    緩沖字節(jié)流和普通字節(jié)流在使用上沒有區(qū)別 ,在效率上緩沖流效率更高

  • 為什么會比較效率?

    • 緩沖流對象底層自帶一個8k的緩沖區(qū),這個緩沖區(qū)跟我們輸入流的自定義的緩沖數(shù)組沒有關(guān)系

    • 緩沖流對象的緩沖區(qū)指的是管道的粗細(xì),而自定義的緩沖數(shù)組指的的是讀取到的數(shù)據(jù)儲存的地方

    • 緩沖流將管道加粗了,從而使輸入和輸出更加效率

字節(jié)緩沖流

2-1.BufferedInputStream

  • 構(gòu)造方法

      BufferedInputStream(InputStream in)
    
  • 示例代碼

      FileInputStream in = new FileInputStream("d:/java/test.java");
      BufferedInputStream bufin = new BufferedInputStream(in);
    

2-2.BufferedOutputStream

  • 構(gòu)造方法

      BufferedOutputStream(OutputStream out)
    
  • 示例代碼

      FileOutputStream out = new FileOutputStream("d:/java/test.java");
      BufferedOutputStream bufOut= new BufferedOutputStream(out);
    

對象流

  • 作用

    把內(nèi)存中的對象輸出到文件中或者把文件中保存的對象輸入到內(nèi)存

  • 為什么保存到文件中?

    目的是為了進(jìn)程之間的數(shù)據(jù)做交流

  • 序列化和反序列化

    序列化:內(nèi)存中的對象寫出到文件

    反序列化:將文件中的對象讀進(jìn)內(nèi)存

  • 序列化對象

    保存的對象需要經(jīng)過序列化,開啟序列化可以通過實(shí)現(xiàn)Serializable接口

    實(shí)現(xiàn)Serializable接口需要在對象中顯示聲明序列化ID;不顯式聲明時(shí),會根據(jù)類上的信息產(chǎn)生不同的序列化ID,由于編譯器的不同,可能導(dǎo)致反序列化出現(xiàn)意外

3-1.ObjectOutputStream

ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants

序列化:把內(nèi)存中的對象保存到硬盤中

  • 構(gòu)造方法

      ObjectOutputStream(OutputStream out) 創(chuàng)建寫入指定OutputStream的對象
    
  • 常用方法

      void writeObject(Object obj) 將對象寫到流中
    
  • 示例代碼

      public class ShareData implements Serializable {
    
       private static final long serialVersionUID = -1190188205817401171L;
    
      }
    
      ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data"));
      ShareData data = new ShareData();
      out.writeObject(data);
      out.close();
    

3-2.ObjectInputStream

ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants

反序列化:將文件中的對象讀取到內(nèi)存中

一個程序去讀取另一個程序序列化的數(shù)據(jù),達(dá)到進(jìn)程通信

  • 構(gòu)造方法

      ObjectInputStream(InputStream in)
    
  • 常用方法

      readObject() 
    
  • 示例代碼

      ObjectInputStream in = new ObjectInputStream(new FileInputStream("data"));
      Object object = in.readObject();
      in.close(); 
    

字節(jié)數(shù)組流

4-1.ByteArrayOutputStream

ByteArrayOutputStream extends OutputStream

  • 特點(diǎn)

    會將數(shù)據(jù)寫入到底層緩沖區(qū)的byte數(shù)組,緩沖區(qū)會隨著數(shù)據(jù)的不斷寫入而自動增長

  • 使用場景:

    在需要接收大量是數(shù)據(jù)時(shí),有些數(shù)據(jù)不適合一次性全部接收,我們可以使用每次收集1小部分的形式,拿到零散的數(shù)據(jù),再將零散的數(shù)據(jù)統(tǒng)一收集起來,最后統(tǒng)一使用,此時(shí)就要用到這個ByteArrayOutputStream

  • 構(gòu)造方法

      ByteArrayOutputStream()
    
  • 常用方法

      byte[] toByteArray() //將緩沖數(shù)組的數(shù)據(jù)放到一個新的數(shù)組
    
      String toString()  用默認(rèn)字符集將緩沖區(qū)數(shù)據(jù)解碼成字符串
    
      String toString(String charsetName)  用指定字符集將緩沖區(qū)數(shù)據(jù)解碼成字符串
    
      void write(byte[] b, int off, int len)  將數(shù)組b寫到流中
    
  • 示例代碼

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      //模擬每次有一部分?jǐn)?shù)據(jù)過來
      //這個方法就是將零散的數(shù)據(jù)先暫時(shí)保存起來
      byteOut.write(new byte[]{'a', 'b', 'c'});
      byteOut.write(new byte[]{'d', 'e', 'e'});
      byteOut.write(new byte[]{100, 127, 32});
    
      byte[] bytes = byteOut.toByteArray();//將保存的零散數(shù)據(jù)使用起來
      System.out.println(new String(bytes));
      System.out.println(byteOut.toString());//解碼流的數(shù)據(jù)為字符串
    

4-2.ByteArrayIntputStream

ByteArrayInputStream extends InputStream

  • 特點(diǎn)

    包含一個內(nèi)部緩沖區(qū),該緩沖區(qū)包含從流中讀取的字節(jié)

    關(guān)閉 ByteArrayIntputStream無效,其方法在關(guān)閉后仍可被調(diào)用,而不會產(chǎn)生IOException

  • 構(gòu)造方法

      ByteArrayInputStream(byte[] buf) 創(chuàng)建一個流對象,使用buf作為其緩沖區(qū)數(shù)組
    
  • 示例代碼

      byte[] bs = new byte[]{9,98,100};//把字節(jié)數(shù)組轉(zhuǎn)成流對象
      ByteArrayInputStream byteIn = new ByteArrayInputStream(bs);
      byte[] buf = new byte[1024];
      int len;
      while ((len = byteIn.read(buf)) != -1){
          System.out.println(new String(buf,0,len));
      }
    

6.2.2 字符流

字符輸入流  Reader

字符輸出流  Writer
  • 為什么使用字符流

    使用字節(jié)流讀取文件可能會出現(xiàn)亂碼的情況,因?yàn)樽止?jié)流是一次只讀取一個字節(jié),而有些數(shù)據(jù)不是一個字節(jié)構(gòu)成,如漢字占兩個字節(jié)或3個字節(jié),在解析的時(shí)候不知道用幾個字節(jié)去解析,因此容易出現(xiàn)亂碼.

  • 字符流工作過程

    • 字符流底層有一個1kb大小的緩沖區(qū),讀寫都是跟緩沖區(qū)有關(guān)的

    • 字符輸入流的緩沖區(qū)的作用:用于讀取數(shù)據(jù)后解析數(shù)據(jù),如果解析成功就會存入緩沖數(shù)組中;如果解析失敗,則會再讀一個數(shù)據(jù)一起解析;如果要解析的字節(jié)在編碼表中找不到對應(yīng)的就會轉(zhuǎn)成問號!

    • 字符輸出流的緩沖區(qū)作用: 先寫入數(shù)據(jù)到緩沖區(qū),然后調(diào)用flush()方法將數(shù)據(jù)從緩沖數(shù)組中寫到文件中,或者緩沖數(shù)組滿了也會寫出去

1-1. FileReader

FileReader extends InputStreamReader

擅長從文件讀取字符的類

  • 構(gòu)造方法

      FileReader(String fileName)
    
  • 常用方法

      int read() 每次讀取一個字符
      
      int read(char[] cbuf) 將字符讀入緩沖數(shù)組中
    
  • 示例代碼

      String path = "d:/java/test.txt";
      try {
          FileReader fr = new FileReader(path);
          char[] chrs = new char[3];//讀取多少個字符到緩沖數(shù)組
          int len;//記錄讀取了多少個字符
          while ((len = fr.read(chrs)) != -1) {
              String s = new String(chrs, 0, len);
              System.out.println(s);
          }
          fr.close();
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      } catch (IOException e) {
          e.printStackTrace();
      }
    

1-2.FileWriter

FileWriter extends OutputStreamWriter

擅長寫出字符到文件的類

  • 構(gòu)造方法

      FileWriter(String fileName)
    
  • 常用方法

      void write(String str) 將字符串寫出到文件
    
      flush() 將緩沖的數(shù)據(jù)寫出到文件 ,在關(guān)閉流之前調(diào)用
    
  • 注意事項(xiàng)

    字符流底層存在一個緩沖數(shù)組,調(diào)用write方法時(shí),會將數(shù)據(jù)臨時(shí)保存在緩沖數(shù)組中,當(dāng)緩沖數(shù)組存滿后,會自動把數(shù)組中的數(shù)據(jù)真正寫到文件中.我們可以手動調(diào)用flush()方法,刷新緩存區(qū),讓數(shù)據(jù)寫到文件

  • 示例代碼

      String dest = "d:/java/write.txt";
      try {
          FileWriter fw = new FileWriter(dest);
          String needData = "hossss";
          fw.write(needData);
          //刷新數(shù)據(jù)
          fw.flush();
          fw.close();
      } catch (IOException e) {
          e.printStackTrace();
      }
    

轉(zhuǎn)換字符流

特點(diǎn):

  • 將字節(jié)流轉(zhuǎn)換成字符流

為什么要轉(zhuǎn)換?

  1. 字節(jié)流是基本流,一般流對象都設(shè)計(jì)成字節(jié)流,比較通用

  2. 有時(shí)流對象并不是我們自己創(chuàng)建的,而是別的地方返回的,而返回的一般是字節(jié)流,如果字節(jié)流用來處理文本數(shù)據(jù)可能會出現(xiàn)亂碼,所以必須將字節(jié)流轉(zhuǎn)成字符流

2-1.InputStreamReader

轉(zhuǎn)換輸入流

  • 構(gòu)造方法

      InputStreamReader(InputStream in)
    
      InputStreamReader(InputStream in, String charsetName)  指定字符集讀取字節(jié)并解碼為字符
    
  • 示例代碼

      FileInputStream in = new FileInputStream("d:/java/test.java");
      InputStreamReader reader = new InputStreamReader(in, "UTF-8");
      char[] chars = new char[1024];
      int len;
      while ((len = reader.read(chars)) != -1){
          System.out.println(new String(chars,0,len));
      }
      reader.close();
    

2-2.OutputStreamWriter

轉(zhuǎn)換輸出流

  • 構(gòu)造方法

      OutputStreamWriter(OutputStream out)
    
      OutputStreamWriter(OutputStream out, String charsetName) 指定字符集將字符編碼成字節(jié)寫到流中
    
  • 示例代碼

      FileOutputStream out = new FileOutputStream("d:/java/test.java");
      OutputStreamWriter writer = new OutputStreamWriter(out,"UTF-8");
      writer.write("你好啊");
      writer.close();//轉(zhuǎn)換流的close包含了刷新數(shù)據(jù),關(guān)閉資源操作
    

字符緩沖流

3-1.BufferedReader

  • 構(gòu)造方法

      BufferedReader(Reader in)   
    
  • 特有方法

      String readLine()  讀取一行文本
    
  • 示例代碼

      BufferedReader reader =new BufferedReader(new FileReader("d:/java/test2.java"));
      String data; //記錄讀取到的內(nèi)容
      while ((data = reader.readLine()) != null){
          System.out.println(data);
      }
      reader.close();
    

3-2.BufferedWriter

  • 構(gòu)造方法

      BufferedWriter(Writer out)
    
  • 特有方法

      void newLine()  寫入一個行分隔符(換行)
    
  • 示例代碼

      BufferedWriter writer = new BufferedWriter(new FileWriter("d:/java/test.java"));
      writer.write("哈哈");
      writer.newLine();//換行
      writer.write("我是哈哈");
      writer.flush();
      writer.close();
    

6.3 文件拷貝

  • 字節(jié)流拷貝

    字節(jié)流可以讀寫文本文件和二進(jìn)制文件

      //需求:將test1.java的內(nèi)容拷貝到test2.java
      FileInputStream in = new FileInputStream("d:/java/test1.java");
      FileOutputStream out = new FileOutputStream("d:/java/test2.java");
      byte[] bytes = new byte[1024];
      int len;
      while ((len = in.read(bytes)) != -1) {
          //將讀取到的數(shù)據(jù)寫出去,邊讀邊寫
          out.write(bytes, 0, len);
      }
      in.close();
      out.close();
    
  • 字符流拷貝

    字符流只能拷貝純文本文件,拷貝二進(jìn)制文件肯定是打不開的

    拷貝二進(jìn)制文件的問題:

    讀取回來的字節(jié)數(shù)據(jù)在轉(zhuǎn)換成字符的過程中,發(fā)現(xiàn)找不到對應(yīng)的字符和它對應(yīng),而轉(zhuǎn)成了?(63)只有一個字節(jié),所以寫出去的就丟失了字節(jié),最終導(dǎo)致拷貝的數(shù)據(jù)變少了

      //需求:將test1.java的內(nèi)容拷貝到test2.java
       FileReader reader = new FileReader("d:/java/test1.java");
       FileWriter writer = new FileWriter("d:/java/test2.java");
       char[] chars = new char[1024];
       int len;
       while ((len = reader.read(chars)) != -1) {
           writer.write(chars, 0, len);
           writer.flush();
       }
       reader.close();
       writer.close();
    

6.4 IO流異常處理

  • 異常處理的核心:

    • 所有的編譯時(shí)期異常必須try-catch

    • 保證流對象得到關(guān)閉

  • 異常一般處理示例代碼

      FileReader reader = null;
      FileWriter writer = null;
      try {
          reader = new FileReader("d:/java/test1.java");
          writer = new FileWriter("d:/java/test2.java");
          //需求:將test1.java的內(nèi)容拷貝到test2.java
          char[] chars = new char[1024];
          int len;
          while ((len = reader.read(chars)) != -1) {
              writer.write(chars, 0, len);
              writer.flush();
          }
      } catch (Exception e) {
          e.printStackTrace();
      }finally {
          if (reader != null){
              try {
                  reader.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }finally {
                  if (writer != null){
                      try {
                          writer.close();
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
    

從上面的代碼可以看出處理異常的代碼邏輯比IO操作還多,結(jié)構(gòu)嵌套很深

  • 異常高級處理

    • try-with-resource

      • java1.7開始出現(xiàn)的跟資源有關(guān)的

      • 相關(guān)的對象需要實(shí)現(xiàn)AutoCloseable接口,流對象都實(shí)現(xiàn)了此接口

      • 應(yīng)用了此語法的流對象不用關(guān)閉資源,會自動關(guān)閉

      • 這個語法只能在Java7或者更高的版本使用

    • 語法

        try (
                ...
                創(chuàng)建AutoCloseable對象的代碼
                ...
        ) {
              可能出現(xiàn)異常的代碼
        } catch (異常類型  變量名) {
        }
      
    • 示例代碼

         try (
            //創(chuàng)建資源對象的代碼放在這里
            FileReader reader = new FileReader("d:/java/test1.java");
            FileWriter writer = new FileWriter("d:/java/test2.java");
        ) {
            char[] chars = new char[1024];
            int len;
            while ((len = reader.read(chars)) != -1) {
                writer.write(chars, 0, len);
                writer.flush();
            }
            //不用關(guān)閉資源
            //reader.close();
            //writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
      

6.5 字符的編碼和解碼

  1. 編碼表

    所謂編碼表就是用一個整數(shù)去對應(yīng)一個字符

    如: ASCII編碼表字符's' s --> 10 -->0000 1010(二進(jìn)制)

    • ASCII
    - 是用**一個 8 位的字節(jié)**來表示空格篙耗、標(biāo)點(diǎn)符號、數(shù)字轿腺、大小寫字母或者控制字符的向瓷,其中最高位為 "0"业踢,其他位可以自由組合成 128 個字符的碼表

    - **ASCII的漢字是1個字節(jié)**

- IOS-8859-1

    是國際標(biāo)準(zhǔn)化組織 ISO 字符編碼標(biāo)準(zhǔn) ISO-8859 的一部分玻淑,它在 ASCII 編碼空置的 0xA0-0xFF 的范圍內(nèi)加入了其他符號字母以供西歐來使用嗽冒,所以也叫 "西歐語言",另外 ISO 的編碼還有其他的一些語言編碼补履,這些都是**單字節(jié) 8 位編碼**添坊。

- GB*
    
    - GB2312 共收錄了七千個字符,由于 GB2312 支持的漢字太少而且不支持繁體中文干像,所以 GBK 對 GB2312 進(jìn)行了擴(kuò)展帅腌,對低字節(jié)不再做大于 127 的規(guī)定驰弄,以支持繁體中文和更多的字符麻汰,GBK 共支持大概 22000 個字符,GB18030 是在 GBK 的基礎(chǔ)上又增加了藏文戚篙、蒙文五鲫、維吾爾文等主要的少數(shù)民族文字。

    - **GBK的漢字是2個字節(jié)**

- Unicode

    - 一個全球性的編碼方案把所有字母和符號都統(tǒng)一編碼進(jìn)去

    - UTF-8以字節(jié)為單位對Unicode進(jìn)行編碼

    - **UTF-8的漢字是3個字節(jié)**
  1. 編碼和解碼

    編碼和解碼都必須依靠一個工具作為橋梁,這個工具就是編碼表

    • 編碼: 把字符變成字節(jié)(整數(shù))

      String類的編碼方法:

        byte[] getBytes() 使用平臺默認(rèn)字符集(一般默認(rèn)GBK)將String編碼為byte,并存到byte數(shù)組中
      
        byte[] getBytes(String charsetName) 使用指定字符集將String編碼為byte,并存到byte數(shù)組中
      
    • 解碼: 把字節(jié)(整數(shù))變成字符

      String類的解碼方法:

        String(byte[] bytes) 使用默認(rèn)字符集將字節(jié)數(shù)組解碼成一個String對象
      
        String(byte[] bytes,String charsetName) 使用指定字符集將字節(jié)數(shù)組解碼成一個String對象
      
    • 編碼和解碼的字符集必須一致,不然在多個字節(jié)的數(shù)據(jù)中,會出現(xiàn)亂碼

    • 示例代碼

        String str = "你好啊";
        byte[] bytes = str.getBytes();//使用默認(rèn)字符集GBK進(jìn)行編碼
        String s = new String(bytes); //使用默認(rèn)字符集GBK進(jìn)行解碼
      
        //編碼和解碼的字符集必須一致
        byte[] bUtf =  str.getBytes("UTF-8");//使用UTF-8編碼
        String sUtf = new String(bUtf,"UTF-8");//使用UTF-8解碼
      

6.6 屬性文件 properties

  • 使用背景

    一般來說,一些簡單的改動都需要經(jīng)過修改源碼-編譯-運(yùn)行,這樣拓展不強(qiáng),不好維護(hù),靈活性不夠.

    我們可以把一些程序中的變量提取出來,放在java代碼的外部,用一個文件保存,這個文件是不需要編譯的,在程序運(yùn)行的時(shí)候再去動態(tài)的讀取這些變量信息.

  • 實(shí)際應(yīng)用

    在項(xiàng)目中使用屬性文件,文件必須以.properties結(jié)尾,在程序運(yùn)行時(shí)用流去讀取信息,Java中專門去讀取屬性文件并解析的類Properties

  • Properties

    Properties extends Hashtable<Object, Object>

    • Properties 可以從流中加載數(shù)據(jù)或者將數(shù)據(jù)保存在流中,屬性列表中的鍵值都是字符串

    • 構(gòu)造方法

        Properties()
      
    • 常用方法

        void load(Reader reader) 從輸入字符流中讀取屬性鍵值對
      
        String getProperty(String key) 獲得指定鍵的屬性值
      
    • 屬性文件的寫法

        src=e:/qq.exe
        dest=d:/java/test.java
      
    • 示例代碼

        Properties properties = new Properties();
        FileReader reader =new FileReader("local.properties");
        //從流中加載屬性文件
        properties.load(reader);
      
        //根據(jù)屬性鍵獲得屬性值
        String src = properties.getProperty("src");
        String dest = properties.getProperty("dest");
      

6.7 RandomAccessFile

RandomAccessFile implements DataOutput, DataInput, Closeable

支持對隨機(jī)訪問文件的讀取和寫入

  • 特征:

    1. 可以讀也可以寫

    2. 底層是byte[]

    3. 包含一個索引叫文件指針

    4. 發(fā)送讀或?qū)懖僮骱笪募羔槙耙苿?/p>

  • 構(gòu)造方法

      RandomAccessFile(String name, String mode)
    
      RandomAccessFile(File file, String mode)
    
      mode參數(shù):
    
          r:表示只支持讀,調(diào)用write方法會拋出異常
          rw:表示支持讀寫操作,如文件不存在,則會嘗試創(chuàng)建文件
    
  • 常用方法

      long getFilePointer() 獲得當(dāng)前指針?biāo)饕?
      seek(long offset) 設(shè)置指針位置
    
  • 示例代碼

      //創(chuàng)建讀寫的流對象
      RandomAccessFile rw = new RandomAccessFile("d:/java/test.txt", "rw");
      rw.writeInt(100);
      rw.writeChar(98);
      long index = rw.getFilePointer();//獲得指針?biāo)饕?  //進(jìn)行讀操作前,需要先將指針回到開始位置,因?yàn)橹斑M(jìn)行寫操作,指針已移動至當(dāng)前寫的位置
      rw.seek(0);
      int a = rw.readInt();
      char c = rw.readChar();
      rw.close();
    
  • 實(shí)際運(yùn)用

    可用于斷點(diǎn)下載

    操作步驟:

    1. 先獲取到要下載的文件的大小
    2. 使用一個隨機(jī)讀寫文件記錄下載的最新位置
    3. 使用兩個隨機(jī)讀取文件對要下載的文件進(jìn)行關(guān)聯(lián),一個負(fù)責(zé)讀,一個負(fù)責(zé)寫
    4. 每次操作都記錄下文件的最新位置并且存入硬盤
    5. 發(fā)送斷點(diǎn)后,讀取最新的記錄,從最新的歷史記錄繼續(xù)讀取

6.8 正則表達(dá)式

  • 使用場景

    使用正確的規(guī)則對字符串進(jìn)行相關(guān)操作(匹配/替換/切割)

  • 基本字符

      x       字符x
    
      \\      反斜線字符
    
  • 字符類(多個中匹配1個)

      [abc]           a b 或c
    
      [^abc]          任何字符,除了a,b或c
    
      [a-zA-Z]            a到z,或   A到Z,兩頭的字母包含在內(nèi)
    
      [a-d[m-p]]      a到d,或者m到p:[a-dm-p](并集)
    
      [a-z&&[def]]        d,e或者f(交集)
    
  • 特殊意義字符(類似關(guān)鍵字)

      .           任何字符(與行結(jié)束符可能匹配也可能不匹配)
    
      \d          數(shù)字:[0-9]
    
      \D          非數(shù)字:[^0-9]
    
      \s          空白字符:[\t\n\x0B\f\r]
    
      \S          非空白字符:[^\s]
    
      \w          單詞字符:[a-zA-Z_0-9]
    
      \W          非單詞字符:[^\w]
    
  • 數(shù)量詞

      X?          X, 一次或者一次也沒有, <=1
    
      X*          X, 零次或者多次, >=0
    
      X+          X, 一次或多次, >=1
    
      X{n}        X, 恰好n次, =n
    
      X{n,}       X, 至少n次, >=n
    
      X{n,m}      X, 至少n次,但不超過m次, >=n <=m
    
  • 字符串正則的常用方法

      boolean matches(String regex)  判斷此字符串是否匹配給定的正則表達(dá)式
    
      String[] split(String regex) 根據(jù)給定的正則拆分字符串
    
      String replaceAll(String regex,String replacement) 用指定的字符串替換所有匹配正則的內(nèi)容
    
  • 正則中需要注意的

      匹配文本中含有的正則特殊字符: \\d , \\[ , \\{ , \\S
    
      匹配文本的一個反斜杠: \\\\
    
      匹配文本中的\r\n制表符時(shí): \r\n
    
  • 示例代碼

      //1開頭,11位數(shù)字,第二個數(shù)字必須為3 5 7
      String tel = "13788888843";
      String regex1 = "1[357]\\d{9}";
      boolean ma = tel.matches(regex1);
      System.out.println(ma);
    
      String exe = "png-jpg;gif-jpeg";
      String regex2 = "[-;]";
      String[] split = exe.split(regex2);
      for (String s : split) {
          System.out.println(s);
      }
    
      String str = "你個S B";
      String regex3 = "S.*B";
      System.out.println(str.replaceAll(regex3,"*")); 
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岔擂,一起剝皮案震驚了整個濱河市位喂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乱灵,老刑警劉巖塑崖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痛倚,居然都是意外死亡规婆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抒蚜,“玉大人掘鄙,你說我怎么就攤上這事∥怂瑁” “怎么了操漠?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饿这。 經(jīng)常有香客問我浊伙,道長,這世上最難降的妖魔是什么长捧? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任吧黄,我火速辦了婚禮,結(jié)果婚禮上唆姐,老公的妹妹穿的比我還像新娘拗慨。我一直安慰自己,他們只是感情好奉芦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布赵抢。 她就那樣靜靜地躺著,像睡著了一般声功。 火紅的嫁衣襯著肌膚如雪烦却。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天先巴,我揣著相機(jī)與錄音其爵,去河邊找鬼。 笑死伸蚯,一個胖子當(dāng)著我的面吹牛摩渺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剂邮,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼摇幻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挥萌?” 一聲冷哼從身側(cè)響起绰姻,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎引瀑,沒想到半個月后狂芋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡憨栽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年帜矾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辆影。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡黍特,死狀恐怖蛙讥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灭衷,我是刑警寧澤次慢,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站翔曲,受9級特大地震影響迫像,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞳遍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一闻妓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掠械,春花似錦由缆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肚菠,卻和暖如春舔箭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚊逢。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工层扶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烙荷。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓镜会,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奢讨。 傳聞我的和親對象是個殘疾皇子稚叹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

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

  • 五、IO流 1拿诸、IO流概述 (1)用來處理設(shè)備(硬盤,控制臺塞茅,內(nèi)存)間的數(shù)據(jù)亩码。(2)java中對數(shù)據(jù)的操作都是通過...
    佘大將軍閱讀 507評論 0 0
  • 一、基礎(chǔ)知識:1野瘦、JVM描沟、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,378評論 0 4
  • 1飒泻、IO流 1.1、概述 之前學(xué)習(xí)的File類它只能操作文件或文件夾吏廉,并不能去操作文件中的數(shù)據(jù)泞遗。真正保存數(shù)據(jù)的是文...
    Villain丶Cc閱讀 2,668評論 0 5
  • 啟動第一步--加載BIOS 當(dāng)你打開計(jì)算機(jī)電源,計(jì)算機(jī)會首先加載BIOS信息席覆,BIOS信息是如此的重要史辙,以至于計(jì)算...
    石樂志的LK閱讀 249評論 0 0
  • “藝術(shù)能幫助你逃離現(xiàn)實(shí)、表達(dá)政治觀點(diǎn)或個人主張佩伤,可以幫助你思考聊倔,增強(qiáng)感知力,質(zhì)疑世界生巡,講述故事耙蔑,留存并保持記憶的鮮...
    大貓兒_Skyfire閱讀 656評論 0 1