2015-10-16 106 views
2

我在獲取文件路徑(資產文件夾中的sh文件)時獲取了NPE。 我試圖從下面的線索讀到關於NPE的詳細信息,但是這實際上無法解決我的問題。在Java中獲取文件路徑時發生java.lang.NullPointerException(通過jar文件執行)

What is a NullPointerException, and how do I fix it?

以下是我的代碼片段:

File absPathofBash; 

    url = ClassLoader.class.getResource("assets/forbackingup.sh"); 
    absPathofBash = new File(url.getPath()); 

後來我用它在一個的ProcessBuilder,作爲

ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3) 

我還試圖獲得絕對直接路徑,如

absPathofBash = new File("assets/forbackingup.sh").getAbsolutePath(); 

使用後一種方式,我可以處理它,但如果我創建了一個罐子那麼該文件無法找到。 (儘管Jar包含相應文件夾內的文件資產

如果有人能幫助我,我會很感激。

+3

你不能使用'File'來訪問'Jar'文件中的嵌入式資源,它們不是文件系統看到它們的「文件」,它們是一堆壓縮字節在一個zip文件(基本上)。在你的情況下,如果你想執行這個文件,你需要從Jar文件中提取文件(你可以使用'Class#getResourceAsStream')然後執行它 – MadProgrammer

回答

2

一旦你已經打包你的代碼作爲一個罐子,你不能加載使用文件路徑,讓罐子裏面的文件,相反,他們是一流的資源,你必須使用此加載:

this.getClass().getClassLoader().getResource("assets/forbackingup.sh"); 

這方式你加載assets/forbackingup.sh作爲你的罐子裏面的絕對路徑。你也可以使用this.getClass().getResource()但這種方式的路徑必須是相對於this裏面的jar類路徑。

getResource方法給你一個網址,如果你想直接得到InputStream可以使用getResourceAsStream

希望它能幫助!

+0

如何在ProcessBuilder中管理InputStream? – pallavi

+0

'ProcessBuilder'是爲了創建操作系統進程,通常你使用args list作爲命令運行。因此,您不能運行jar中的shell腳本。如果你想這樣做,我認爲你必須從'InputStream'創建一個臨時文件,然後使用這個tmpFile繼續'ProcessBuilder'。 – malaguna

+0

我已經有了這個工作,即通過jar執行一個shell腳本。我被卡住的地方是,我試圖直接執行此jar而不改變終端中的當前目錄。如果我將** **放到jar的目錄下,然後執行這個jar文件,它就可以很好地工作。但除此之外(根據我的要求),它無法找到我的** sh文件**。 – pallavi

-1

您可以使用Path類,如:

Path path = Paths.get("data/test-write.txt"); 
if(!Files.exists(path)){ 
    // can handle null pointer exception 
} 
+1

雖然這可能在理論上回答這個問題,但它不是一個很好的答案,因爲它沒有教導OP。相反,它給出了一個沒有解釋的替代方案這通常會導致OP沒有學習,並且在發生類似問題時回到問一個新問題。你介意添加一些解釋嗎? – Vogel612

0

由於文件本身是在jar文件,你可以嘗試使用:

InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileNameFromJar); 
0

我通過創建一個臨時文件來完成它。雖然它並不難,但我張貼代碼補丁在這裏:

InputStream stream = MyClass.class.getClassLoader(). 
      getResourceAsStream("assets/forbackingup.sh"); 

     File temp = File.createTempFile("forbackingup", ".sh"); 



     OutputStream outputStream = 
       new FileOutputStream(temp); 

     int read = 0; 

     byte[] bytes = new byte[1024]; 

     while ((read = stream.read(bytes)) != -1) { 

      outputStream.write(bytes, 0, read); 
      outputStream.close(); 

     } 

現在,我們在這裏有這個臨時文件,我們可以管到ProcessBuilder一樣,

String _filePath=temp.getPath(); 
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3) 

謝謝大家爲了您的考慮。