从jar内部读取文件不工作

时间:2013-02-02 01:30:32

标签: java jar io inputstream embedded-resource

在Java中,我尝试了在jar中读取文件的不同技术。我有一个人在另一个程序中工作,但不是这个。我从classname.class.getClassLoader()得到的InputStream .getResourceAsStream(filenamestring); method返回null。

 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 is null”并在行上给出错误:stream.read(); 我知道这意味着文件没有正确转换为InputStream。 我犯了一个愚蠢的错误吗?请帮忙。提前致谢 编辑:我想要在与jar相同的目录中复制的文件直接在jar中。它不在包或任何此类附加目录中。

2 个答案:

答案 0 :(得分:4)

如果getResourceAsStream(String)返回null,则表示类加载器找不到具有您提供的名称的资源。要么是明白错误,要么您使用了相对名称,而且资源不在JAR的“/”目录中。

有关详细信息,请阅读ClassLoader.getResourceAsStream的javadoc,注意:

  • 返回的值,
  • 处理相对路径名(按照getResource链接!!)。

如果要使用相对于类包解析的相对名称加载资源,则应该写下:

    MainClass.class.getResourceAsStream(files);

Class.getResource...方法解析相对于类的相对名称。因此,上述内容会将"foo.txt"解析为"/mainpkg/foo.txt" ...您的版本会将其解析为"/foo.txt"

答案 1 :(得分:1)

  

我知道这意味着文件没有正确转换为InputStream

不,不。这意味着找不到名为的资源。检查Javadoc。

然后根据JAR列表检查您的帖子中有帮助遗漏的资源名称。

如果'stream'为null,则您无法继续尝试阅读并获取NPE。这只是糟糕的编程。

此外,JAR文件中的资源不是文件,并且使用其名称构建文件是无意义的活动。