目錄
- 依賴
- IOUtils 封裝IO通用操作
- 常用常量
- 讀寫
- 複制
- 疊代、比較
- FileUtils 檔案操作工具
- 常用常量
- 系統路徑
- 檔案體積
- 建立、删除
- 檔案讀寫
- 複制、剪切
- 疊代周遊
- 檔案内容比對
- FilenameUtils 檔案名工具
- 常用常量
- 檔案名、擴充名
- 路徑
- IOFileFilter 檔案|目錄過濾器
- 字元集常見的指定方式
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();