本文介紹了ClassLoader.getResourceAsStream是如何工作的?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我已經用Maven創建了一個JAR文件。當我打開這個罐子時,我可以找到以下內容:
my.jar
|_text1.txt
|_folder
|_ ... some other stuff
當我在Eclipse中運行此代碼片段時,";ext1.txt";的內容以及輸出的文件夾內容中的所有文件名
String tmp = IOUtils.toString(App.class.getClassLoader().getResourceAsStream("text1.txt"), StandardCharsets.UTF_8);
System.err.println(tmp);
tmp = IOUtils.toString(App.class.getClassLoader().getResourceAsStream("folder"), StandardCharsets.UTF_8);
System.err.println(tmp);
當我將此代碼作為獨立程序運行時,也將打印來自";ext1.txt";的內容,但文件夾的第二部分返回空。
我做錯了什么?
推薦答案
App.class.getClassLoader().getResourceAsStream
不要這樣做。正確的方式是App.class.getResourceAsStream
。有些時候getCLassLoader()
返回NULL;在這種情況下,您的策略失敗了,上面的方法可以很好地工作。此外,您的方式是更多的調用和更多的代碼,而不會獲得任何好處。
IOUtils.toString(App.class.getClassLoader().getResourceAsStream("folder")
您無法獲取”文件夾”。你覺得這會有什么用呢?設計到資源加載器系統中的抽象(這就是您在這里使用的)不允許您以任何方式獲取文件夾,也不允許您列出文件夾的內容。(您可能正在尋找SPI:服務提供商接口)。
IOUtils
您不需要這個;java.nio.file.Files
是內置的,并且同樣有一個toString方法。它甚至默認為UTF-8
,因此您不必指定它。
App.class.getResourceAsStream("text1.txt")
這將在與App.class完全相同的位置查找t1.txt。甚至是相同的包裝結構。如果您想從App.class所在位置的”根”開始(因此,通常是-classpath
上的內容),請在前面加一個斜杠:例如,請求"/text1.txt"
。
假設您的ext1.txt位于根目錄中,而不是com/foo/pkg/MyApp.class
旁邊的com/foo/pkg
中,則需要指定"/text1.txt"
才能找到它。
如果您不確定此內容的位置,請輸出此調用的結果:
App.class.getResource("App.class");
這會打印一個URL,您的眼球將能夠從它看到它的位置。
和打印出的文件夾內容中的所有文件名
那很好。這不起作用–eclipse在運行時為您提供了這是一種怪異,但規范基本上沒有對此進行抽象。ClassLoader實現可以做他們想做的任何事情(這是一個可插拔的系統),它們需要實現的唯一方法是”在這個位置找到資源“。如果您請求一個‘文件夾’,則沒有義務返回文件名字符串,而且大多數類加載器(包括讀取JAR文件的類加載器)根本不需要這樣做。
解決方案是SPI:在編譯時創建一個列出路徑或類名的文件,然后在運行時使用資源系統加載該文件,然后加載其中列出的每個類/每個資源。作為編譯的一部分,注釋處理器可以自動生成此文件的過程,從而使整個測試過程無縫進行。在Web上搜索SPI Java以了解更多信息。
這篇關于ClassLoader.getResourceAsStream是如何工作的?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,