天天看點

常用的IO工具類

目錄

  • ​​依賴​​
  • ​​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();      

繼續閱讀