對于一個嵌套的目錄,獲取目錄下所有的文件,可以使用以下兩種方式:
1. 通過遞歸獲取
File類提供了如下兩個方法:
- file.list():返回目錄下文件和子目錄名;(不會遞歸)
- file.listFiles():返回目錄下文件和子目錄File對象;(不會遞歸)
/**
* 得到文件名稱
*
* @param path 路徑
* @return {@link List}<{@link String}>
*/
private List<String> getFileNames(String path) {
File file = new File(path);
if (!file.exists()) {
return null;
}
List<String> fileNames = new ArrayList<>();
return getFileNames(file, fileNames);
}
/**
* 得到文件名稱
*
* @param file 文件
* @param fileNames 文件名
* @return {@link List}<{@link String}>
*/
private List<String> getFileNames(File file, List<String> fileNames) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory()) {
getFileNames(f, fileNames);
} else {
fileNames.add(f.getName());
}
}
return fileNames;
}
例子中List只是存放了文件夾下所有的文件名,可以根據(jù)需求修改List中存放的元素屬性。比如可以直接將File對象存入。
2. 使用Files.walk()方法
在jdk8中,可以使用walk方法遞歸的去查找目錄下所有文件。
// 路徑
String path = "D:\\xxx";
try (Stream<Path> paths = Files.walk(Paths.get(path))){
List<Path> fileNames = paths
.filter(Files::isRegularFile)
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
walk方法會自動遞歸子目錄。
上例使用了Try with Resources模式,它可以確保無論在什么情況下,流都將關(guān)閉。
解釋:
如果try塊和finally塊中的方法都拋出異常那么try塊中的異常會被抑制(suppress),只會拋出finally中的異常,而把try塊的異常完全忽略。而try-with-resources語句能夠幫你自動調(diào)用資源的close()函數(shù)關(guān)閉資源不用到finally塊。
walk方法解釋:
通過遍歷以給定起始文件為根的文件樹,返回一個用 Path 惰性填充的 Stream。文件樹是深度優(yōu)先遍歷的,流中的元素是 Path 對象,就好像通過解析相對路徑來獲得的一樣。此方法的工作方式就像調(diào)用它等同于評估表達(dá)式: walk(start, Integer.MAX_VALUE, options) 換句話說,它訪問文件樹的所有級別。返回的流封裝了一個或多個 DirectoryStream。如果需要及時處理文件系統(tǒng)資源,則應(yīng)使用 try-with-resources 構(gòu)造來確保在流操作完成后調(diào)用流的 close 方法。對關(guān)閉的流進(jìn)行操作將導(dǎo)致 illegalStateException。
illegalStateException是無效狀態(tài)異常。表示當(dāng)前對客戶端的響應(yīng)已經(jīng)結(jié)束,不能在響應(yīng)已經(jīng)結(jié)束(或說消亡)后再向客戶端(實(shí)際上是緩沖區(qū))輸出任何內(nèi)容。
一般來說無效狀態(tài)異常是因?yàn)榕e了調(diào)用一個方法的流程,
例如:比如在JSP/Servlet編程中,服務(wù)器已經(jīng)開始把數(shù)據(jù)發(fā)客戶端了,卻想改動字符集encoding參數(shù),這個就是錯誤,因?yàn)殚_始復(fù)數(shù)據(jù)到客戶端后就不能再修改任何Http header內(nèi)容,它們已經(jīng)發(fā)出去了,無法再修改了。
maxDepth參數(shù),設(shè)置要遞歸的深度;Files.walk(Paths.get(path),2)
默認(rèn)不會自動跟隨符號鏈接, 設(shè)置options參數(shù)FOLLOW_LINKS選項,則遵循符號鏈接。 Files.walk(Paths.get(path),FileVisitOption.FOLLOW_LINKS)
示例:文章來源:http://www.zghlxwxcb.cn/news/detail-468016.html
String path = "D:\\xxx";
//過濾出目錄
try (Stream<Path> paths = Files.walk(Paths.get(dirName))) {
paths.filter(Files::isDirectory)
.forEach(System.out::println);
}
//按后綴名過濾
try (Stream<Path> paths = Files.walk(Paths.get(dirName), 2)) {
paths.map(path -> path.toString()).filter(f -> f.endsWith(".png"))
.forEach(System.out::println);
}
需求:傳進(jìn)來上傳的文件名通過","分割,檢查文件夾中是否存在,不存在返回缺失的文件名
代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-468016.html
/**
* 校驗(yàn)文件
*
* @param data 文件名數(shù)據(jù)
* @return {@link String}
*/
@Override
public String validationFile(String data) {
List<String> fileNames = new ArrayList<>();
try (Stream<Path> paths = Files.walk(Paths.get(path))) {
fileNames = paths
.filter(Files::isRegularFile)
.map(file -> file.getFileName().toString())
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
//傳進(jìn)來的files
String[] fileNameArr = data.split(",");
List<String> missingFile = new ArrayList<>();
for (String s : fileNameArr) {
if (!fileNames.contains(s)) {
missingFile.add(s);
}
}
if (missingFile.size() == 0) {
return "1";
}
return String.join(",", missingFile);
}
到了這里,關(guān)于java獲取文件夾下所有的文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!