Java基础 - IO流

6.IO流

6.1 File

系统中我们一眼看到的就是文件或者文件夹
本质是一个路径(字符串);用字符串来表示这个路径不符合面向对象

File类对路径的字符串进行面向对象的封装,是文件和文件夹路径的抽象表现形式

基本操作:

  • 构造方法

      File(String pathname) 将给定的路径名字符串转为抽象路径名来创建一个File实例
    
      例子:  new File("D:java/testDoc/test.java") //文件路径
            new File("D:java/testDoc") //文件夹路径
      
      File(String parent, String child) 根据父路径字符串和子路径字符串创建一个File实
    
      例子:new File("D:java","/testDoc/test.java") //文件
      例子:new File("D:java","/testDoc") //文件夹
    
  • 创建

    • 创建文件夹

        mkdir():创建文件夹
        
        mkdirs():?创建多级文件夹
      
    • 创建文件

        createNewFile():创建文件
      
    • 重命名

        renameTo():给文件或文件夹重命名
      
  • 判断

      exists():判断此路径是否存在
    
      isFile():判断是否文件
    
      isDirectory():判断是否文件夹
    
  • 获取

      getAbsolutePath():获取绝对路径,包括根路径
    
      getName():获取相对路径(文件名或者文件夹名).不包括根路径
    
      length():获取文件的大小,单位是字节
    
  • 删除

      delete():删除文件
      
      deleteOnExit():在程序退出的时候删除文件
    
  • 示例代码:

      //创建File实例对象,路径的抽象表现
      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()){
              //创建文件
              file.createNewFile();
          }
          //判断是否是文件夹路径
          if (file.isDirectory()){
              //创建文件夹
              file.mkdir();
          }
      }
      //获取绝对路径
      System.out.println(file.getAbsoluteFile()); // 输出 /D:java/testDoc/test.java
      //获取相对路径(文件名或者文件夹名)
      System.out.println(file.getName()); // 输出test.java
    

File类的高级获取

  • 方法:
    listFiles():返回一个File数组,包括了路径名下的的所有文件和文件夹路径名

    listRoots():此方法是静态的,返回路径名下的所有根路径

    listFiles(FileFilter filter):返回File数组,数组是有经过过滤器FileFilter筛选的

    FileFilter 重写的方法: accept(File pathname)  返回true表示需包含在数组内,不要去掉
  • 示例代码1:

      if (file != null && file.isDirectory()) {
          //打印文件夹
          System.out.println(file);
          //列出所有的文件和文件夹路径
          File[] files = file.listFiles();
          for (File f : files) {
              //递归调用,找出所有的文件 文件夹
              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结尾的需要保留,不要去掉
                  return file.getName().endsWith(".class");
              }
          });
      }
    

6.2 IO流基类

  1. 字节输入流 InputStream

  2. 字节输出流 OutputStream

  3. 字符输入流 Reader

  4. 字符输出流 Writer

特点:

  • 四大基类都是抽象类,核心功能一句话总结:读进来,写出去

    • 输出流:将数据写到目标中去

    • 输入流:从源中读取数据

  • 所有的流都是资源对象,最后使用完都必须关闭资源

  • 字节流比较通用

  • IO流的操作模板

      1):定义源或目标  源:输入流  目标:输出流
    
      2):根据源和目标创建流对象
    
      3):进行读/写操作
    
      4):关闭资源
    

6.2.1 字节流

字节输入流  InputStream

字节输出流  OutputStream 

字节文件流

1-1.FileOutputStream

将数据写到目标文件中

  • 构造方法

          FileOutputStream(File file) 创建向指定File对象的目标文件中写入数据的文件输出流 
    
          FileOutputStream(String name) 创建向指定名称的目标文件中写入数据的文件输出流
    
          FileOutputStream(String name, boolean append) append 是否在源数据中追加
    
  • 常用方法

          write(int b) //将指定数量的字节写到输入流
    
          write(byte[] b,int off, int len ) 将指定的byte数组从off索引开始的len个字节写到输出流
    
  • 分析流对象的创建

          1.创建了输出流对象
    
          2.通知系统去检查目标文件,如果不存在则创建出来
    
          3.将这个输出流对象与硬盘上的文件关联起来
    
  • 示例代码:

          String dest = "d:/java/test.txt"; //输出的目标文件路径
          try {
              //创建流对象,如果文件不存在,则会自动创建文件
              FileOutputStream fo = new FileOutputStream(dest);
              byte[] bytes = "hello".getBytes();//需要写到流的数据
              fo.write(bytes,2,3);
              fo.close();//关闭流,释放资源,等待GC回收
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
    

1-2.FileInputStream

从源文件读取数据

  • 构造方法

          FileInputStream(String name)
    
          FileInputStream(File file)   创建从源文件中读取数据的输入流对象
    
  • 常用方法

          read()  从输入流中读取数据的下一个字节,
                  返回值是读取到的字节,如果为-1表示已读完
    
          read(byte[] b)  从输入流中读取数据的一定数量字节,并存储到缓冲数组b中.
                          返回值是读取的字节个数,如果为-1表示已读完
    
  • 示例代码:

          //源
          String path = "d:/java/in.txt";
          //根据源创建输入流对象
          try {
              FileInputStream fi = new FileInputStream(path);
              //定义一个缓冲数组
              byte[] bytes = new byte[1024 * 1024];
              fi.read(bytes);
              int len;//记录读取了多少个字节
              while ((len = fi.read(bytes)) != -1) { //不等于-1 表示还有数据
                  System.out.println(new String(bytes, 0, len));
              }
              fi.close();
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
    

缓冲流

  • 特点

    缓冲字节流和普通字节流在使用上没有区别 ,在效率上缓冲流效率更高

  • 为什么会比较效率?

    • 缓冲流对象底层自带一个8k的缓冲区,这个缓冲区跟我们输入流的自定义的缓冲数组没有关系

    • 缓冲流对象的缓冲区指的是管道的粗细,而自定义的缓冲数组指的的是读取到的数据储存的地方

    • 缓冲流将管道加粗了,从而使输入和输出更加效率

字节缓冲流

2-1.BufferedInputStream

  • 构造方法

      BufferedInputStream(InputStream in)
    
  • 示例代码

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

2-2.BufferedOutputStream

  • 构造方法

      BufferedOutputStream(OutputStream out)
    
  • 示例代码

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

对象流

  • 作用

    把内存中的对象输出到文件中或者把文件中保存的对象输入到内存

  • 为什么保存到文件中?

    目的是为了进程之间的数据做交流

  • 序列化和反序列化

    序列化:内存中的对象写出到文件

    反序列化:将文件中的对象读进内存

  • 序列化对象

    保存的对象需要经过序列化,开启序列化可以通过实现Serializable接口

    实现Serializable接口需要在对象中显示声明序列化ID;不显式声明时,会根据类上的信息产生不同的序列化ID,由于编译器的不同,可能导致反序列化出现意外

3-1.ObjectOutputStream

ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants

序列化:把内存中的对象保存到硬盘中

  • 构造方法

      ObjectOutputStream(OutputStream out) 创建写入指定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

反序列化:将文件中的对象读取到内存中

一个程序去读取另一个程序序列化的数据,达到进程通信

  • 构造方法

      ObjectInputStream(InputStream in)
    
  • 常用方法

      readObject() 
    
  • 示例代码

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

字节数组流

4-1.ByteArrayOutputStream

ByteArrayOutputStream extends OutputStream

  • 特点

    会将数据写入到底层缓冲区的byte数组,缓冲区会随着数据的不断写入而自动增长

  • 使用场景:

    在需要接收大量是数据时,有些数据不适合一次性全部接收,我们可以使用每次收集1小部分的形式,拿到零散的数据,再将零散的数据统一收集起来,最后统一使用,此时就要用到这个ByteArrayOutputStream

  • 构造方法

      ByteArrayOutputStream()
    
  • 常用方法

      byte[] toByteArray() //将缓冲数组的数据放到一个新的数组
    
      String toString()  用默认字符集将缓冲区数据解码成字符串
    
      String toString(String charsetName)  用指定字符集将缓冲区数据解码成字符串
    
      void write(byte[] b, int off, int len)  将数组b写到流中
    
  • 示例代码

      ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
      //模拟每次有一部分数据过来
      //这个方法就是将零散的数据先暂时保存起来
      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();//将保存的零散数据使用起来
      System.out.println(new String(bytes));
      System.out.println(byteOut.toString());//解码流的数据为字符串
    

4-2.ByteArrayIntputStream

ByteArrayInputStream extends InputStream

  • 特点

    包含一个内部缓冲区,该缓冲区包含从流中读取的字节

    关闭 ByteArrayIntputStream无效,其方法在关闭后仍可被调用,而不会产生IOException

  • 构造方法

      ByteArrayInputStream(byte[] buf) 创建一个流对象,使用buf作为其缓冲区数组
    
  • 示例代码

      byte[] bs = new byte[]{9,98,100};//把字节数组转成流对象
      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
  • 为什么使用字符流

    使用字节流读取文件可能会出现乱码的情况,因为字节流是一次只读取一个字节,而有些数据不是一个字节构成,如汉字占两个字节或3个字节,在解析的时候不知道用几个字节去解析,因此容易出现乱码.

  • 字符流工作过程

    • 字符流底层有一个1kb大小的缓冲区,读写都是跟缓冲区有关的

    • 字符输入流的缓冲区的作用:用于读取数据后解析数据,如果解析成功就会存入缓冲数组中;如果解析失败,则会再读一个数据一起解析;如果要解析的字节在编码表中找不到对应的就会转成问号!

    • 字符输出流的缓冲区作用: 先写入数据到缓冲区,然后调用flush()方法将数据从缓冲数组中写到文件中,或者缓冲数组满了也会写出去

1-1. FileReader

FileReader extends InputStreamReader

擅长从文件读取字符的类

  • 构造方法

      FileReader(String fileName)
    
  • 常用方法

      int read() 每次读取一个字符
      
      int read(char[] cbuf) 将字符读入缓冲数组中
    
  • 示例代码

      String path = "d:/java/test.txt";
      try {
          FileReader fr = new FileReader(path);
          char[] chrs = new char[3];//读取多少个字符到缓冲数组
          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

擅长写出字符到文件的类

  • 构造方法

      FileWriter(String fileName)
    
  • 常用方法

      void write(String str) 将字符串写出到文件
    
      flush() 将缓冲的数据写出到文件 ,在关闭流之前调用
    
  • 注意事项

    字符流底层存在一个缓冲数组,调用write方法时,会将数据临时保存在缓冲数组中,当缓冲数组存满后,会自动把数组中的数据真正写到文件中.我们可以手动调用flush()方法,刷新缓存区,让数据写到文件

  • 示例代码

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

转换字符流

特点:

  • 将字节流转换成字符流

为什么要转换?

  1. 字节流是基本流,一般流对象都设计成字节流,比较通用

  2. 有时流对象并不是我们自己创建的,而是别的地方返回的,而返回的一般是字节流,如果字节流用来处理文本数据可能会出现乱码,所以必须将字节流转成字符流

2-1.InputStreamReader

转换输入流

  • 构造方法

      InputStreamReader(InputStream in)
    
      InputStreamReader(InputStream in, String charsetName)  指定字符集读取字节并解码为字符
    
  • 示例代码

      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

转换输出流

  • 构造方法

      OutputStreamWriter(OutputStream out)
    
      OutputStreamWriter(OutputStream out, String charsetName) 指定字符集将字符编码成字节写到流中
    
  • 示例代码

      FileOutputStream out = new FileOutputStream("d:/java/test.java");
      OutputStreamWriter writer = new OutputStreamWriter(out,"UTF-8");
      writer.write("你好啊");
      writer.close();//转换流的close包含了刷新数据,关闭资源操作
    

字符缓冲流

3-1.BufferedReader

  • 构造方法

      BufferedReader(Reader in)   
    
  • 特有方法

      String readLine()  读取一行文本
    
  • 示例代码

      BufferedReader reader =new BufferedReader(new FileReader("d:/java/test2.java"));
      String data; //记录读取到的内容
      while ((data = reader.readLine()) != null){
          System.out.println(data);
      }
      reader.close();
    

3-2.BufferedWriter

  • 构造方法

      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 文件拷贝

  • 字节流拷贝

    字节流可以读写文本文件和二进制文件

      //需求:将test1.java的内容拷贝到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) {
          //将读取到的数据写出去,边读边写
          out.write(bytes, 0, len);
      }
      in.close();
      out.close();
    
  • 字符流拷贝

    字符流只能拷贝纯文本文件,拷贝二进制文件肯定是打不开的

    拷贝二进制文件的问题:

    读取回来的字节数据在转换成字符的过程中,发现找不到对应的字符和它对应,而转成了?(63)只有一个字节,所以写出去的就丢失了字节,最终导致拷贝的数据变少了

      //需求:将test1.java的内容拷贝到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流异常处理

  • 异常处理的核心:

    • 所有的编译时期异常必须try-catch

    • 保证流对象得到关闭

  • 异常一般处理示例代码

      FileReader reader = null;
      FileWriter writer = null;
      try {
          reader = new FileReader("d:/java/test1.java");
          writer = new FileWriter("d:/java/test2.java");
          //需求:将test1.java的内容拷贝到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操作还多,结构嵌套很深

  • 异常高级处理

    • try-with-resource

      • java1.7开始出现的跟资源有关的

      • 相关的对象需要实现AutoCloseable接口,流对象都实现了此接口

      • 应用了此语法的流对象不用关闭资源,会自动关闭

      • 这个语法只能在Java7或者更高的版本使用

    • 语法

        try (
                ...
                创建AutoCloseable对象的代码
                ...
        ) {
              可能出现异常的代码
        } catch (异常类型  变量名) {
        }
      
    • 示例代码

         try (
            //创建资源对象的代码放在这里
            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();
        } catch (Exception e) {
            e.printStackTrace();
        }
      

6.5 字符的编码和解码

  1. 编码表

    所谓编码表就是用一个整数去对应一个字符

    如: ASCII编码表字符's' s --> 10 -->0000 1010(二进制)

    • ASCII
    - 是用**一个 8 位的字节**来表示空格、标点符号、数字、大小写字母或者控制字符的,其中最高位为 "0",其他位可以自由组合成 128 个字符的码表

    - **ASCII的汉字是1个字节**

- IOS-8859-1

    是国际标准化组织 ISO 字符编码标准 ISO-8859 的一部分,它在 ASCII 编码空置的 0xA0-0xFF 的范围内加入了其他符号字母以供西欧来使用,所以也叫 "西欧语言",另外 ISO 的编码还有其他的一些语言编码,这些都是**单字节 8 位编码**。

- GB*
    
    - GB2312 共收录了七千个字符,由于 GB2312 支持的汉字太少而且不支持繁体中文,所以 GBK 对 GB2312 进行了扩展,对低字节不再做大于 127 的规定,以支持繁体中文和更多的字符,GBK 共支持大概 22000 个字符,GB18030 是在 GBK 的基础上又增加了藏文、蒙文、维吾尔文等主要的少数民族文字。

    - **GBK的汉字是2个字节**

- Unicode

    - 一个全球性的编码方案把所有字母和符号都统一编码进去

    - UTF-8以字节为单位对Unicode进行编码

    - **UTF-8的汉字是3个字节**
  1. 编码和解码

    编码和解码都必须依靠一个工具作为桥梁,这个工具就是编码表

    • 编码: 把字符变成字节(整数)

      String类的编码方法:

        byte[] getBytes() 使用平台默认字符集(一般默认GBK)将String编码为byte,并存到byte数组中
      
        byte[] getBytes(String charsetName) 使用指定字符集将String编码为byte,并存到byte数组中
      
    • 解码: 把字节(整数)变成字符

      String类的解码方法:

        String(byte[] bytes) 使用默认字符集将字节数组解码成一个String对象
      
        String(byte[] bytes,String charsetName) 使用指定字符集将字节数组解码成一个String对象
      
    • 编码和解码的字符集必须一致,不然在多个字节的数据中,会出现乱码

    • 示例代码

        String str = "你好啊";
        byte[] bytes = str.getBytes();//使用默认字符集GBK进行编码
        String s = new String(bytes); //使用默认字符集GBK进行解码
      
        //编码和解码的字符集必须一致
        byte[] bUtf =  str.getBytes("UTF-8");//使用UTF-8编码
        String sUtf = new String(bUtf,"UTF-8");//使用UTF-8解码
      

6.6 属性文件 properties

  • 使用背景

    一般来说,一些简单的改动都需要经过修改源码-编译-运行,这样拓展不强,不好维护,灵活性不够.

    我们可以把一些程序中的变量提取出来,放在java代码的外部,用一个文件保存,这个文件是不需要编译的,在程序运行的时候再去动态的读取这些变量信息.

  • 实际应用

    在项目中使用属性文件,文件必须以.properties结尾,在程序运行时用流去读取信息,Java中专门去读取属性文件并解析的类Properties

  • Properties

    Properties extends Hashtable

    • Properties 可以从流中加载数据或者将数据保存在流中,属性列表中的键值都是字符串

    • 构造方法

        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);
      
        //根据属性键获得属性值
        String src = properties.getProperty("src");
        String dest = properties.getProperty("dest");
      

6.7 RandomAccessFile

RandomAccessFile implements DataOutput, DataInput, Closeable

支持对随机访问文件的读取和写入

  • 特征:

    1. 可以读也可以写

    2. 底层是byte[]

    3. 包含一个索引叫文件指针

    4. 发送读或写操作后文件指针会往前移动

  • 构造方法

      RandomAccessFile(String name, String mode)
    
      RandomAccessFile(File file, String mode)
    
      mode参数:
    
          r:表示只支持读,调用write方法会抛出异常
          rw:表示支持读写操作,如文件不存在,则会尝试创建文件
    
  • 常用方法

      long getFilePointer() 获得当前指针索引
    
      seek(long offset) 设置指针位置
    
  • 示例代码

      //创建读写的流对象
      RandomAccessFile rw = new RandomAccessFile("d:/java/test.txt", "rw");
      rw.writeInt(100);
      rw.writeChar(98);
      long index = rw.getFilePointer();//获得指针索引
      //进行读操作前,需要先将指针回到开始位置,因为之前进行写操作,指针已移动至当前写的位置
      rw.seek(0);
      int a = rw.readInt();
      char c = rw.readChar();
      rw.close();
    
  • 实际运用

    可用于断点下载

    操作步骤:

    1. 先获取到要下载的文件的大小
    2. 使用一个随机读写文件记录下载的最新位置
    3. 使用两个随机读取文件对要下载的文件进行关联,一个负责读,一个负责写
    4. 每次操作都记录下文件的最新位置并且存入硬盘
    5. 发送断点后,读取最新的记录,从最新的历史记录继续读取

6.8 正则表达式

  • 使用场景

    使用正确的规则对字符串进行相关操作(匹配/替换/切割)

  • 基本字符

      x       字符x
    
      \\      反斜线字符
    
  • 字符类(多个中匹配1个)

      [abc]           a b 或c
    
      [^abc]          任何字符,除了a,b或c
    
      [a-zA-Z]            a到z,或   A到Z,两头的字母包含在内
    
      [a-d[m-p]]      a到d,或者m到p:[a-dm-p](并集)
    
      [a-z&&[def]]        d,e或者f(交集)
    
  • 特殊意义字符(类似关键字)

      .           任何字符(与行结束符可能匹配也可能不匹配)
    
      \d          数字:[0-9]
    
      \D          非数字:[^0-9]
    
      \s          空白字符:[\t\n\x0B\f\r]
    
      \S          非空白字符:[^\s]
    
      \w          单词字符:[a-zA-Z_0-9]
    
      \W          非单词字符:[^\w]
    
  • 数量词

      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)  判断此字符串是否匹配给定的正则表达式
    
      String[] split(String regex) 根据给定的正则拆分字符串
    
      String replaceAll(String regex,String replacement) 用指定的字符串替换所有匹配正则的内容
    
  • 正则中需要注意的

      匹配文本中含有的正则特殊字符: \\d , \\[ , \\{ , \\S
    
      匹配文本的一个反斜杠: \\\\
    
      匹配文本中的\r\n制表符时: \r\n
    
  • 示例代码

      //1开头,11位数字,第二个数字必须为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,"*")); 
    

你可能感兴趣的:(Java基础 - IO流)