• 常用的IO工具类



     

    commons-io 是apache开源的io工具类库,封装了很多IO工具类,使用方便。
     

    依赖

    <dependency>
        <groupId>commons-iogroupId>
        <artifactId>commons-ioartifactId>
        <version>2.11.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

     

    IOUtils 封装IO通用操作

    常用常量

    //路径分隔符,char形式
    
    //unix路径分隔符 /
    IOUtils.DIR_SEPARATOR_UNIX;
    //win路径分隔符 \
    IOUtils.DIR_SEPARATOR_WINDOWS;
    //根据操作系统自动确定
    IOUtils.DIR_SEPARATOR;
    
    
    //换行符,String形式
    
    //unix的换行符 \n
    IOUtils.LINE_SEPARATOR_UNIX;
    //win的换行符 \r\n
    IOUtils.LINE_SEPARATOR_WINDOWS;
    //根据操作系统自动确定 @Deprecated
    IOUtils.LINE_SEPARATOR;
    
    
    //空数组 {}
    IOUtils.EMPTY_BYTE_ARRAY
    
    //代表文件末尾的int值 -1
    IOUtils.EOF;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

     

    读写

    //将普通io流(is、os、reader、writer)转换对应的buffer流,可以指定缓冲区大小,未指定时默认 8192
    BufferedReader buffer1 = IOUtils.buffer(reader);
    BufferedReader buffer2 = IOUtils.buffer(reader, 8192);
    
    
    
    // toString()、toCharArray()、toByteArray() 将输入流、资源的内容转换为String、char[]、byte[],用法相同,以 toString() 为例
    String content1 = IOUtils.toString(reader);
    
    //is需要指定字符集
    String content2 = IOUtils.toString(is, "utf-8");
    
    //从指定URI、URL获取内容,获取到的是源码,网址需要以http、https开头,需要指定Charset|String形式的字符集
    String content3 = IOUtils.toString(URI.create("http://www.baidu.com"), "utf-8");
    String content4 = IOUtils.toString(new URL("http://www.baidu.com"), "utf-8");
    
    //都支持本地资源,但要以 file:/// 开头
    String content5 = IOUtils.toString(URI.create("file:///D:/Users/Desktop/1.txt"), "utf-8");
    String content6 = IOUtils.toString(new URL("file:///D:/Users/Desktop/1.txt"), "utf-8");
    
    
    
    //提供了多个重载方法,可以从is、reader读取到byte[]、char[]中,可以设置读取开始位置的偏移量、读取长度
    IOUtils.read();
    //提供了多个重载方法,可以将byte[]、char[]、字符串写到os、writer中
    IOUtils.write();
    
    //将is、reader的游标移动指定距离,实际调用的是is、reader对应的带偏移量、读取长度的read()重载方法
    //is、reader自身提供了2个方法来移动游标:skip()、重载的read(),skip()方式效率高但不保证移动的准确性(可能有误差)、会返回实际移动的距离,read()方式效率低但移动是准确的
    IOUtils.skip();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    打开文件后,如果已经读取了所有内容,后续再次读取时游标已经在文件尾了,读不到任何内容。

     

    复制

    //如果都是字节流、字符流,无需指定字符集
    IOUtils.copy(is, os);
    IOUtils.copy(reader, writer);
    
    //如果一个是字节流、另一个是字符流,需要指定Charset|String形式的字符集
    IOUtils.copy(is, writer, "utf-8");
    IOUtils.copy(reader, os, "utf-8");
    
    //可以指定缓冲区大小,未指定时默认为 8192
    IOUtils.copy(is, os, 8192);
    
    //从url流复制内容,可实现文件下载,网页得到的是源码
    IOUtils.copy(new URL("http://xxx/xxx.png"), new File("D:/download/xxx.png"));
    IOUtils.copy(new URL("http://xxx/xxx.png"), os);
    
    //如果目标文件已存在,会先删除再写入;如果目标文件不存在,会先创建再写入
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    copy()、copyLarge() 底层都是调用相同的方法,区别在于

    • copyLarge() 可以自定义缓冲区数组,指定读取的开始位置、偏移量。
    • 一些 copy() 方法返回 int,当文件比较大(超过2G)时返回值可能超过 Integer.MAX_VALUE,此时会返回-1;一些 copyLarge() 方法返回 long,可以容纳复制大体积文件时的返回值。

     

    迭代、比较

    //输入流行迭代器,迭代每行。is需要指定 Charset|String 形式的字符集,reader无需指定字符集
    IOUtils.lineIterator(is, "utf-8").forEachRemaining(line -> System.out.println(line));
    IOUtils.lineIterator(is, "utf-8").forEachRemaining(line -> System.out.println(line));
    IOUtils.lineIterator(reader).forEachRemaining(line -> System.out.println(line));
    
    
    //比较输入流的内容是否相同,可用于比较文件内容是否相同
    boolean result = IOUtils.contentEquals(is1|reader1, is2|reader2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

     

    FileUtils 文件操作工具

    常用常量

    单位都是 byte

    //long型
    long oneKb = FileUtils.ONE_KB;
    long oneMb = FileUtils.ONE_MB;
    long oneGb = FileUtils.ONE_GB;
    long oneTb = FileUtils.ONE_TB;
    
    //BigInteger类型
    BigInteger oneTbBi = FileUtils.ONE_TB_BI;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

     

    系统路径

    //获取系统临时文件夹,形如 C:\Users\chy\AppData\Local\Temp\
    File tempDirectory = FileUtils.getTempDirectory();
    String tempDirectoryPath = FileUtils.getTempDirectoryPath();
    
    //获取用户目录,形如 C:\Users\chy
    File userDirectory = FileUtils.getUserDirectory();
    String userDirectoryPath = FileUtils.getUserDirectoryPath();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

     

    文件体积

    //获取文件或文件夹的体积,byte
    long size1 = FileUtils.sizeOf(file);
    BigInteger size2 = FileUtils.sizeOfAsBigInteger(file);
    
    //获取文件夹的体积
    long size3 = FileUtils.sizeOfDirectory(dir);
    BigInteger size4 = FileUtils.sizeOfDirectoryAsBigInteger(dir);
    
    
    //将字节数转换为对用户更友好、可读性更强的字符串,结果只是一个大概的值,不100%精确
    String str1 = FileUtils.byteCountToDisplaySize(1024);
    String str2 = FileUtils.byteCountToDisplaySize(new BigInteger("10240000000"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

     

    创建、删除

    //创建文件,此方法只能创建文件,不能创建文件夹
    //如果文件已存在则不再重新创建,如果路径中的文件夹不存在会自动创建
    FileUtils.touch(file);
    
    
    //删除文件或目录,目录要是空目录才能被删除,否则会抛出 DirectoryNotEmptyException 异常
    FileUtils.delete(file);
    //强制删除文件或目录,删除失败时会抛出异常
    FileUtils.forceDelete(file);
    //在jvm退出时强制删除文件或目录
    FileUtils.forceDeleteOnExit(file);
    //静默删除文件或目录,不要求目录为空(目录不为空也能被删除),删除失败时不会抛出异常
    FileUtils.deleteQuietly(dir);
    
    //删除目录(会删除目录自身)
    FileUtils.deleteDirectory(dir);
    //清空目录(不删除目录自身)
    FileUtils.cleanDirectory(dir);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

     

    文件读写

    //打开文件作为输入流
    FileInputStream fis = FileUtils.openInputStream(file);
    //打开文件作为输出流,可指定是否为追加模式
    FileOutputStream fosWithAppend = FileUtils.openOutputStream(file, true);
    //默认false 直接覆盖
    FileOutputStream fos = FileUtils.openOutputStream(file);
    
    
    
    //读取所有内容到byte[]中
    byte[] bytes = FileUtils.readFileToByteArray(file);
    //读取所有内容到String中,需要指定String|Charset形式的字符集
    String content = FileUtils.readFileToString(file, "utf-8");
    //读取每行,一行对应一个String,空行对应空串,文件没有内容时返回空集合
    List<String> lineList = FileUtils.readLines(file, "utf-8");
    
    //都是先调用openInputStream()打开文件,进行读取,再关闭文件
    
    
    
    //写入字符序列 CharSequence,需要指定String|Charset形式的字符集,可指定是否为追加模式
    FileUtils.write(file, "xxx", "utf-8", true);
    //默认false 直接覆盖
    FileUtils.write(file, "xxx", "utf-8");
    
    
    //写入字符串,需要指定String|Charset形式的字符集,可指定是否为追加模式
    FileUtils.writeStringToFile(file, "xxx", "utf-8", true);
    //默认false 直接覆盖
    FileUtils.writeStringToFile(file, "xxx", "utf-8");
    
    
    //写入byte[],需要指定String|Charset形式的字符集,可指定是否为追加模式
    FileUtils.writeByteArrayToFile(file, "xxx".getBytes(StandardCharsets.UTF_8), true);
    //默认false 直接覆盖
    FileUtils.writeByteArrayToFile(file, "xxx".getBytes("utf-8"));
    
    
    //写入多行,一个元素作为一行写入(自动在元素末尾加上换行符),可指定字符集、是否为追加模式
    FileUtils.writeLines(file, "utf-8", list, true);
    //缺省字符集时使用jvm默认字符集
    FileUtils.writeLines(file, list, true);
    //默认false 直接覆盖
    FileUtils.writeLines(file, list);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    都是先调用openOutputStream()打开文件,进行写入,再关闭文件;如果指定路径、文件不存在,会先创建再写入。

    覆盖:先删除原有全部内容,再写入。

     

    复制、剪切

    //从网络输入流复制内容,可实现网络资源(包括网页源码)的下载,后2个参数分别是连接超时、建立连接后得读取超时(从连接中读取不到内容的等待时间)
    FileUtils.copyURLToFile(new URL("https://xxx/xxx.png"), new File("D:/download/xxx.png"), 30000, 30000);
    FileUtils.copyURLToFile(new URL("https://www.baidu.com"), new File("D:/download/baidu.html"), 30000, 30000);
    
    //不指定连接超时、读取超时时,默认为不限制、永远等待,可能出现永远阻塞的情况,一般不用
    FileUtils.copyURLToFile(new URL("https://xxx/xxx.png"), new File("D:/download/xxx.png"));
    FileUtils.copyURLToFile(new URL("https://www.baidu.com"), new File("D:/download/baidu.html"));
    
    
    //复制文件(只能复制文件,不能复制目录)
    FileUtils.copyFile(srcFile, destFile);
    FileUtils.copyFile(srcFile, os);
    
    //从is复制到文件
    FileUtils.copyToFile(is, destFile);
    FileUtils.copyInputStreamToFile(is, destFile);
    
    
    //复制目录(递归复制),目标目录名可与源目录名不同,可以指定过滤器,只复制满足要求的文件、目录
    FileUtils.copyDirectory(srcDir, destDir, FileFilterUtils.suffixFileFilter(".jpg"));
    FileUtils.copyDirectory(srcDir, destDir);
    
    
    //复制目录到指定目录下
    FileUtils.copyDirectoryToDirectory(srcDir, destDir);
    
    //复制文件到指定目录下
    FileUtils.copyFileToDirectory(srcFile, destDir);
    FileUtils.copyToDirectory(srcFile, destDir);
    FileUtils.copyToDirectory(Iterable<File>, destDir);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    //剪切文件(只能是文件,不能是文件夹)
    FileUtils.moveFile(srcFile, destFile);
    //剪切目录
    FileUtils.moveDirectory(srcDir, destDir);
    
    
    //剪切到指定目录下,最后一个参数指定destDir不存在时是否自动创建,如果设置为false,destDir不存在时会直接抛出异常
    
    //剪切文件到指定目录下
    FileUtils.moveFileToDirectory(srcFile, destDir, true);
    //剪切目录到指定目录下
    FileUtils.moveDirectoryToDirectory(srcDir, destDir, true);
    //剪切文件或目录到指定目录下
    FileUtils.moveToDirectory(src, destDir, true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 复制、剪切操作,都可以指定 CopyOption 当目标已存在时如何操作,默认直接替换。
    • 复制、剪切到目录时,如果 destDir 已存在,会覆盖其中的同名文件、文件夹,不是先删除整个 destDir 再复制。
    • 写入类型的操作,指定目标路径不存在时,会自动创建。

     

    迭代遍历

    //列出满足条件的文件,都是针对文件的(返回值只需要文件、不需要目录)
    
    //第二个参数指定要保留的扩展名数组,第三个数组指定是否递归遍历
    Collection<File> files = FileUtils.listFiles(dir, new String[]{"png", "md"}, true);
    //后2个参数分别是文件过滤器、目录过滤器,只过滤直接子文件、满足目录过滤器的子目录中的文件
    Collection<File> files1 = FileUtils.listFiles(dir, FileFilterUtils.suffixFileFilter(".md"), FileFilterUtils.suffixFileFilter("总结"));
    
    // iterateFiles() 的作用和 listFiles() 相同,只是返回的数据形式不同
    Iterator<File> fileIterator1 = FileUtils.iterateFiles(dir, new String[]{"png", "md"}, true);
    Iterator<File> fileIterator2 = FileUtils.iterateFiles(dir, FileFilterUtils.suffixFileFilter(".md"), FileFilterUtils.suffixFileFilter("总结"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

     

    文件内容比对

    //比较文件内容是否相等,会逐行比较
    boolean contentEquals = FileUtils.contentEquals(file1, file2);
    //忽略EOL字符
    boolean contentEqualsIgnoreEOL = FileUtils.contentEqualsIgnoreEOL(file1, file2, "utf-8");
    
    • 1
    • 2
    • 3
    • 4

     

    FilenameUtils 文件名工具

    常用常量

    //扩展名分隔符.  char、String形式
    char extensionSeparator = FilenameUtils.EXTENSION_SEPARATOR;
    String extensionSeparatorStr = FilenameUtils.EXTENSION_SEPARATOR_STR;
    
    • 1
    • 2
    • 3

     

    文件名、扩展名

    //获取文件名(带扩展名)
    String name = FilenameUtils.getName("D:/image/xxx.png");
    //获取基本文件名(不带扩展名)
    String baseName = FilenameUtils.getBaseName("D:/image/xxx.png");
    
    
    //获取文件扩展名(不带.),如果是目录之类没有扩展名的,返回空串
    String extension1 = FilenameUtils.getExtension("D:/image/xxx.png");
    String extension2 = FilenameUtils.getExtension("xxx.png");
    
    
    //判断文件扩展名是否是指定值,第一个参数可以是文件路径,也可以是文件名;第二个参数可以是 String String... Collection 形式,不带.
    boolean isExtension1 = FilenameUtils.isExtension("D:/image/xxx.png", "png");
    boolean isExtension2 = FilenameUtils.isExtension("D:/image/xxx.png", "png", "jpg", "gif");
    boolean isExtension3 = FilenameUtils.isExtension("D:/image/xxx.png", Arrays.asList("png", "jpg", "gif"));
    
    boolean isExtension4 = FilenameUtils.isExtension("xxx.png", "png");
    boolean isExtension5 = FilenameUtils.isExtension("xxx.png", "png", "jpg", "gif");
    boolean isExtension6 = FilenameUtils.isExtension("xxx.png", Arrays.asList("png", "jpg", "gif"));
    
    
    //移除扩展名(会移除.),原串不变,在副本上操作
    String filenameOfNoExtension = FilenameUtils.removeExtension("xxx.png");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

     

    路径

    //获取扩展名.对应的下标,参数可以是文件路径、文件名
    int indexOfExtension1 = FilenameUtils.indexOfExtension("xxx.png");
    int indexOfExtension2 = FilenameUtils.indexOfExtension("D:/image/xxx.png");
    
    //获取最后一个路径分隔符对应的下标,会匹配unix、win的分隔符
    int indexOfLastSeparator = FilenameUtils.indexOfLastSeparator("D:/image/xxx.png");
    
    //返回的index是自然数下标(>=0),如果没有匹配的字符,返回-1
    
    
    
    //获取所在目录,末尾带\(只有盘符的除外)
    String fullPath1 = FilenameUtils.getFullPath("D:/image/xxx.png");
    String fullPath2 = FilenameUtils.getFullPath("D:/image/upload");
    
    //获取所在目录,末尾不带\(只有盘符的除外)
    String fullPathNoEndSeparator1 = FilenameUtils.getFullPathNoEndSeparator("D:/image/xxx.png");
    String fullPathNoEndSeparator2 = FilenameUtils.getFullPathNoEndSeparator("D:/image/upload");
    
    //不管是文件还是文件夹,获取的都是上级目录的路径
    
    
    
    //转换为指定操作系统的文件路径,注意win得到的是 D:\Users\Desktop 这种单斜杠的,不是双斜杠
    String pathOfWin = FilenameUtils.separatorsToWindows("D:/image/xxx.png");
    String pathOfUnix = FilenameUtils.separatorsToUnix("D:\\image\\xxx.png");
    //根据操作系统自动确定
    String pathOfSystem = FilenameUtils.separatorsToSystem("D:/image/xxx.png");
    
    
    
    // 连接2个路径,会自动处理连接处缺少的路径分隔符,路径分隔符会统一为所在操作系统的
    //第二个参数不要以路径分隔符开头,以路径分隔符开头会被理解为unix的根目录
    // win:D:\download\txt\1.txt    unix:D:/download/txt/1.txt
    String concatPath1 = FilenameUtils.concat("D:/download", "txt/1.txt");
    String concatPath2 = FilenameUtils.concat("D:/download/", "txt\\1.txt");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    代码中的win文件路径 "D:\\img\\xxx.png",用 \ 转义字符串中的 \,所以写成 \\,实际返回、输出的是 \

     

    IOFileFilter 文件|目录过滤器

    //后缀过滤器,文件名以指定后缀结尾
    IOFileFilter suffixFileFilter = FileFilterUtils.suffixFileFilter(".xmd", IOCase.INSENSITIVE);
    //前缀过滤器,文件名以指定前缀开头
    IOFileFilter prefixFileFilter = FileFilterUtils.prefixFileFilter("xxx", IOCase.INSENSITIVE);
    //文件名过滤器,文件名为指定值
    IOFileFilter nameFileFilter = FileFilterUtils.nameFileFilter("xxx.md", IOCase.INSENSITIVE);
    
    //以上3个匹配的都是文件名(带扩展名),第二个参数指定匹配时是否区分大小写,为null时区分大小写
    
    
    //均有缺省第二个参数的重载方法,默认第二个参数为null
    IOFileFilter suffixFileFilter1 = FileFilterUtils.suffixFileFilter(".md");
    IOFileFilter prefixFileFilter1 = FileFilterUtils.prefixFileFilter("xxx");
    IOFileFilter nameFileFilter1 = FileFilterUtils.nameFileFilter("xxx.md");
    
    
    //目录过滤器,只接纳目录
    IOFileFilter directoryFileFilter = FileFilterUtils.directoryFileFilter();
    //文件过滤器,只接纳文件
    IOFileFilter fileFileFilter = FileFilterUtils.fileFileFilter();
    
    
    //可以同时使用多个过滤器,过滤器之间可以用and、or连接
    IOFileFilter ioFileFilter = FileFilterUtils.and(prefixFileFilter).and(suffixFileFilter);
    IOFileFilter ioFileFilter1 = FileFilterUtils.and(prefixFileFilter).or(suffixFileFilter);
    
    
    File[] files = new File("D:/xxx/xxx").listFiles();
    
    //过滤,第一个参数指定要使用的过滤器,第二个参数指定要过滤的文件列表,支持arr、迭代器、参数个数不定的形式,返回值支持arr、list、set
    File[] fileArr = FileFilterUtils.filter(suffixFileFilter, files);
    List<File> fileList = FileFilterUtils.filterList(nameFileFilter, files);
    Set<File> fileSet = FileFilterUtils.filterSet(ioFileFilter, files);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

     

    字符集常见的指定方式

    //字符串形式
    String charset = "utf-8";
    
    //jdk nio提供
    Charset charset = StandardCharsets.UTF_8;
    Charset charset = Charset.forName("utf-8");
    
    //apache commons-io提供
    Charset charset = Charsets.toCharset("utf-8");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

     

    byte[] bytes = "xxx".getBytes();
    
    • 1

    未指定字符集时,默认使用jvm默认字符集,jvm默认字符集由jvm启动时根据操作系统设置的地区、字符集确定。

  • 相关阅读:
    法线方程实现最小二乘拟合(Matlab)
    接口幂等性详解
    1044 火星数字 (测试点2.4说明)
    《canvas》之第19章 canvas游戏开发
    商标申请注册交费就一定会下注册证?
    两个手机屏幕的效果对比
    LlamaIndex使用指南
    泛型编程——模板【C++】
    c刷题[6]
    菜鸟踩坑之MybatisPlus查询时过滤不想要的字段
  • 原文地址:https://blog.csdn.net/chy_18883701161/article/details/124402194