日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

在 Java 中,如何批量读取本项目资源目录下的所有文件

發布時間:2024/4/13 java 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在 Java 中,如何批量读取本项目资源目录下的所有文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 Java 中,如何批量讀取本項目資源目錄下的所有文件

  • 讀取資源目錄下的指定文件
  • 方法 1:使用 JDK 中原始 API
  • 方法 2:借助 Spring
  • 附錄
    • 將 InputStream 轉化為 byte 數組
    • 將 File 轉化為 byte 數組
    • 將 byte 數組轉化為 InputStream

今天筆者遇到一個需求,如何讀取本項目資源目錄下的所有文件。讀取資源目錄下的指定的文件很容易,這只需要給出路徑即可。

讀取資源目錄下的指定文件

/*** 方法 getResourceAsStream 的路徑是以資源目錄 resources 為基準的,* 且不受 Maven 模塊的限制。這于 xxx.class 中 xxx 是哪個模塊的哪個類無關*/ var inputStream = XXX.class.getClassLoader().getResourceAsStream("path/filename.suffix");

但是現在,需要讀取資源目錄下的所有文件。也就是說,不能指定資源目錄下的文件名,最多可以指定基路徑。

筆者梳理了一下,這種需求可以分為以下幾個實現步驟:

  • 讀取本目錄下的本級文件與文件夾。

  • 遞歸讀取本目錄下本級文件夾內的文件。

這樣梳理之后,實現方案就有了。

方法 1:使用 JDK 中原始 API

/*** 讀取資源目錄中路徑 path 下的所有文件。path 不需要以斜杠 / 開頭** @since 2022-1-16*/public static void readAllResFiles(String path) throws IOException, URISyntaxException {var urlEnumeration = ReadAllResFiles.class.getClassLoader().getResources(path);// 正常來講,此循環應該只會進行一次while (urlEnumeration.hasMoreElements()) {var url = urlEnumeration.nextElement();var fileDir = new File(new URI(url.toString()));recursiveReadFile(fileDir);}}/*** 讀取文件或遞歸讀取文件夾內的文件** @since 2022-1-16*/public static void recursiveReadFile(File fileOrDir) {// 如果一開始傳入的 fileOrDir 就為空,直接返回if (fileOrDir == null) {System.out.println("fileOrDir 為空"); // FIXME:日志return;}if (fileOrDir.isFile()) {// 子遞歸函數將在此處終止System.out.println("文件路徑:" + fileOrDir); // TODO:對 fileOrDir 進行處理} else {for (var file : Objects.requireNonNull(fileOrDir.listFiles())) {recursiveReadFile(file); // 如果不需要遞歸遍歷子文件夾,可將此處改為對 fileOrDir 的直接處理}}}

??在上面的代碼中,方法 readAllResFiles 中入口方法,然后對于具體的業務,可以在方法 recursiveReadFile 中添加。如果使用函數式編程的技術,對外暴露一個需使用者實現的函數式接口,這里都可以直接在無需提前知道具體業務的情況下,以開閉原則完成本方法的實現。關于函數式編程,可見筆者的另一篇博客:

Java 函數式編程入門:
https://blog.csdn.net/wangpaiblog/article/details/122762637

方法 2:借助 Spring

??筆者正當為自己的聰明機智洋洋得意的時候,突然想到一個問題。掃描項目中某目錄下的所有文件,這不是 Spring 的基本功能嗎?(因為 Spring 支持掃描項目某目錄及其子目錄下的所有文件,并按要求選擇將其注冊為 Bean。)也就是說,Spring 應該已經實現了這種功能。

??為了打消這個顧慮,筆者不斷查看 Spring 源碼,終于發現了這個功能的實現。為了便于閱讀,筆者將源碼解析的部分置于文末,對源碼有興趣的讀者可以看看。

??筆者已經幫讀者在源碼中找到了這個類,讀者可以不用花大量的時間來找了,這個類就是 PathMatchingResourcePatternResolver。它有一個方法 getResources 可以實現此功能。具體代碼如下:

/*** @since 2022-1-16*/public static void readAllResFiles() throws IOException {var resolver = new PathMatchingResourcePatternResolver();// 可根據需要進行選擇var resources = resolver.getResources("classpath:path/*"); // 遍歷指定目錄下的文件與文件夾,但不把文件夾當做文件處理,不進行深層遍歷 // var resources = resolver.getResources("classpath:path/*.*"); // 遍歷目錄下所有有文件后綴的文件 // var resources = resolver.getResources("classpath:path/**"); // 遞歸遍歷目錄下的所有文件與文件夾for (var resource : resources) {// TODO:對 resource 進行處理System.out.println(resource.getFilename()); // 文件名System.out.println(resource.getURL().getPath()); // 文件絕對路徑System.out.println(resource.getFile()); // File 對象// 如果 resource 不是目錄if (resource.getFile().isFile()) {System.out.println(resource.getInputStream()); // InputStream 對象}}}

??對于 SpringBoot 項目,可以直接使用上述的方法而不需要添加其它依賴。如果項目中原來沒有使用過 Spring,則需要添加如下依賴(以 Maven 為例):

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.9.RELEASE</version> </dependency>

【源碼解析】

??Spring 在啟動時會自動掃描所有的 Bean。對于 Spring Boot,它會使用 Bean 掃描器(ClassPathBeanDefinitionScanner)掃描基包(basePackage)目錄下的所有 Bean。具體來說,它會先生成基包路徑,然后使用上面的 PathMatchingResourcePatternResolver 進行掃描。


附錄

??上面的方法是間接得到了資源文件,通常還需要做進一步的轉化,這里給出一些常用的轉化操作。

將 InputStream 轉化為 byte 數組

/*** 此方法不會重置流,因此經過轉化后,原來的流將不能再使用。* 因此,如果想要反復讀取流,請轉化前對流進行備份** @since 2021-11-24*/public static byte[] inputStream2byteArray(InputStream inputStream) throws IOException {return inputStream.readAllBytes();}

??注意:InputStream 對象中的數據是不能直接被反復讀取的。通常情況下,InputStream 對象在讀取完數據之后將作廢。有一些方法可以解決這個問題,可見筆者的另一篇博客:

如何反復讀取同一個 InputStream 對象:
https://blog.csdn.net/wangpaiblog/article/details/121369433

將 File 轉化為 byte 數組

/*** @since 2021-11-24*/public static byte[] file2byteArray(File file) throws IOException {return inputStream2byteArray(new FileInputStream(file));}

??其中,方法 inputStream2byteArray 是前面已經提供的函數。

將 byte 數組轉化為 InputStream

/*** @since 2021-11-24*/public static InputStream byteArray2InputStream(byte[] bytes) {return new ByteArrayInputStream(bytes);}

總結

以上是生活随笔為你收集整理的在 Java 中,如何批量读取本项目资源目录下的所有文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。