2013-02-02 129 views
-1

在Java中,我嘗試了讀取jar中文件的不同技巧。我已經得到一個在另一個程序內工作,但不是這個。我從classname.class.getClassLoader()。getResourceAsStream(filenamestring)獲得的InputStream;方法返回null。從jar中讀取文件不工作

package mainpkg; 

import java.awt.GridLayout; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 

public class MainClass extends JFrame{ 
JTextField jtf = new JTextField(); 
boolean isInstalling = false; 
public MainClass(){ 
    super("StringThatTitleWillBe"); 
} 
public void initiate(){ 
    setLookAndFeel(); 
    setSize(550, 400); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    GridLayout bl = new GridLayout(2, 1, 10, 10); 
    setLayout(bl); 

    JButton b = new JButton("Install"); 
    b.addMouseListener(new MouseListener(){ 

     @Override 
     public void mouseClicked(MouseEvent arg0) { 
      if(!isInstalling){ 
      isInstalling = true; 
      install(); 
      } 
     } 

     @Override 
     public void mouseEntered(MouseEvent arg0) { 

     } 

     @Override 
     public void mouseExited(MouseEvent arg0) { 

     } 

     @Override 
     public void mousePressed(MouseEvent arg0) { 

     } 

     @Override 
     public void mouseReleased(MouseEvent arg0) { 

     } 

    }); 
    add(b); 
    jtf.setEditable(false); 
    add(jtf); 
    //show 
    setVisible(true); 
} 
private void setLookAndFeel() { 
    try { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    } catch (Exception exc) { 
     System.out.print("failed to load look and feel"); 
    } 
} 
public static void main(String[] args){ 
    MainClass m = new MainClass(); 
    m.initiate(); 
} 

public void install() { 
    String files = "name of jarfile inside the jar to be read"; 
    InputStream stream = MainClass.class.getClassLoader().getResourceAsStream(files); 
    File f = new File(files); 
    if(stream == null) 
     System.out.println("stream is null"); 
    try { 
     int val = stream.read(); 
     BufferedWriter br = new BufferedWriter(new FileWriter(f)); 
     while(val != -1){ 
     br.write(val); 
     val = stream.read(); 
     } 
     stream.close(); 
     br.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    isInstalling = false; 
    } 
} 

它打印「流爲空」,並給出錯誤的行:stream.read(); 我知道這意味着該文件沒有正確轉換爲InputStream。 我犯了一個愚蠢的錯誤?請幫忙。在此先感謝 編輯:我想要在jar文件相同的目錄中複製的文件直接在jar中。它不在包或任何這樣的附加目錄中。

+3

所有的GUI代碼與這個問題完全無關。 – EJP

+0

無法建立指向Jar中資源的「文件」。檔案不包含任何文件。但是,它們包含可以通過URL或InputStream訪問的資源。 –

回答

4

如果getResourceAsStream(String)返回null,這意味着類加載器無法找到具有您給它的名稱的資源。要麼是明顯錯誤的,要麼是您使用了相對名稱,並且該資源不在JAR的「/」目錄中。

有關詳細信息,請閱讀的Javadoc ClassLoader.getResourceAsStream,仔細注意:

  • 返回的值,並
  • 相對路徑的處理(按照getResource鏈接!!)。

如果要加載使用解決相關的類包相對名稱的資源,你應該這樣寫:

MainClass.class.getResourceAsStream(files); 

Class.getResource...方法解決相對於類相對名稱。因此,上述內容將會解析"foo.txt""/mainpkg/foo.txt" ......您的版本可能會將其解析爲"/foo.txt"

+0

該文件直接在項目文件夾中,我嘗試了/之前,但它仍然無法正常工作。它在沒有斜槓的另一個項目中工作,並且該文件位於/ foo中。txt,所以我不明白我應該怎麼做才能使它適用於第二個項目。感謝您的想法,但可能是我錯誤地引用了它。我試圖添加/和\\在它之前,但都沒有工作 – user2016463

+0

我想通過InputStream stream = MainClass.class.getResourceAsStream(files);是我唯一的選擇,我必須將該罐放入該包裝中。沒有其他選擇正在工作。謝謝您的幫助! – user2016463

1

我知道這意味着該文件不被轉換成一個InputStream正確

不,它不需要。這意味着找不到名爲的資源。檢查Javadoc。

然後根據JAR的列表檢查您的帖子中有用的資源名稱。

如果'stream'爲空,那麼您將不會繼續嘗試閱讀並獲取NPE。這只是糟糕的編程。

此外,JAR文件中的資源不是文件,並且用其名稱構造文件是無意義的活動。

+0

對錯誤溝通感到抱歉。該文件直接在jar中。我將文件名設置爲「filename.extension」。我需要在它前面添加「\\」嗎?我試圖將文件放在jar文件中,並將其複製到jar所在的同一目錄中。 – user2016463

+0

@ user2016463您需要在其前面添加「/」。 – EJP