常用的IO工具类
Posted mb5861ee280b600
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用的IO工具类相关的知识,希望对你有一定的参考价值。
目录
commons-io 是apache开源的io工具类库,封装了很多IO工具类,使用方便。
依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
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;
读写
//将普通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();
打开文件后,如果已经读取了所有内容,后续再次读取时游标已经在文件尾了,读不到任何内容。
复制
//如果都是字节流、字符流,无需指定字符集
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);
//如果目标文件已存在,会先删除再写入;如果目标文件不存在,会先创建再写入
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);
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;
系统路径
//获取系统临时文件夹,形如 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();
文件体积
//获取文件或文件夹的体积,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"));
创建、删除
//创建文件,此方法只能创建文件,不能创建文件夹
//如果文件已存在则不再重新创建,如果路径中的文件夹不存在会自动创建
FileUtils.touch(file);
//删除文件或目录,目录要是空目录才能被删除,否则会抛出 DirectoryNotEmptyException 异常
FileUtils.delete(file);
//强制删除文件或目录,删除失败时会抛出异常
FileUtils.forceDelete(file);
//在jvm退出时强制删除文件或目录
FileUtils.forceDeleteOnExit(file);
//静默删除文件或目录,不要求目录为空(目录不为空也能被删除),删除失败时不会抛出异常
FileUtils.deleteQuietly(dir);
//删除目录(会删除目录自身)
FileUtils.deleteDirectory(dir);
//清空目录(不删除目录自身)
FileUtils.cleanDirectory(dir);
文件读写
//打开文件作为输入流
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);
都是先调用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);
//剪切文件(只能是文件,不能是文件夹)
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);
- 复制、剪切操作,都可以指定 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("总结"));
文件内容比对
//比较文件内容是否相等,会逐行比较
boolean contentEquals = FileUtils.contentEquals(file1, file2);
//忽略EOL字符
boolean contentEqualsIgnoreEOL = FileUtils.contentEqualsIgnoreEOL(file1, file2, "utf-8");
FilenameUtils 文件名工具
常用常量
//扩展名分隔符. char、String形式
char extensionSeparator = FilenameUtils.EXTENSION_SEPARATOR;
String extensionSeparatorStr = FilenameUtils.EXTENSION_SEPARATOR_STR;
文件名、扩展名
//获取文件名(带扩展名)
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");
路径
//获取扩展名.对应的下标,参数可以是文件路径、文件名
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");
代码中的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);
字符集常见的指定方式
//字符串形式
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");
byte[] bytes = "xxx".getBytes();
未指定字符集时,默认使用jvm默认字符集,jvm默认字符集由jvm启动时根据操作系统设置的地区、字符集确定。
以上是关于常用的IO工具类的主要内容,如果未能解决你的问题,请参考以下文章