How to get a path to a resource in a Java JAR file

前端 未结 16 2116
时光说笑
时光说笑 2020-11-22 09:23

I am trying to get a path to a Resource but I have had no luck.

This works (both in IDE and with the JAR) but this way I can\'t get a path to a file, only the file

相关标签:
16条回答
  • 2020-11-22 09:41

    You need to understand the path within the jar file.
    Simply refer to it relative. So if you have a file (myfile.txt), located in foo.jar under the \src\main\resources directory (maven style). You would refer to it like:

    src/main/resources/myfile.txt
    

    If you dump your jar using jar -tvf myjar.jar you will see the output and the relative path within the jar file, and use the FORWARD SLASHES.

    0 讨论(0)
  • 2020-11-22 09:42

    follow code!

    /src/main/resources/file

    streamToFile(getClass().getClassLoader().getResourceAsStream("file"))
    
    public static File streamToFile(InputStream in) {
        if (in == null) {
            return null;
        }
    
        try {
            File f = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
            f.deleteOnExit();
    
            FileOutputStream out = new FileOutputStream(f);
            byte[] buffer = new byte[1024];
    
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
    
            return f;
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
            return null;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:44

    Inside your ressources folder (java/main/resources) of your jar add your file (we assume that you have added an xml file named imports.xml), after that you inject ResourceLoader if you use spring like bellow

    @Autowired
    private ResourceLoader resourceLoader;
    

    inside tour function write the bellow code in order to load file:

        Resource resource = resourceLoader.getResource("classpath:imports.xml");
        try{
            File file;
            file = resource.getFile();//will load the file
    ...
        }catch(IOException e){e.printStackTrace();}
    
    0 讨论(0)
  • 2020-11-22 09:47

    Maybe this method can be used for quick solution.

    public class TestUtility
    { 
        public static File getInternalResource(String relativePath)
        {
            File resourceFile = null;
            URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
            String codeLocation = location.toString();
            try{
                if (codeLocation.endsWith(".jar"){
                    //Call from jar
                    Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
                    resourceFile = path.toFile();
                }else{
                    //Call from IDE
                    resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
                }
            }catch(URISyntaxException ex){
                ex.printStackTrace();
            }
            return resourceFile;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:48

    When loading a resource make sure you notice the difference between:

    getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
    

    and

    getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
    

    I guess, this confusion is causing most of problems when loading a resource.


    Also, when you're loading an image it's easier to use getResourceAsStream():

    BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
    

    When you really have to load a (non-image) file from a JAR archive, you might try this:

    File file = null;
    String resource = "/com/myorg/foo.xml";
    URL res = getClass().getResource(resource);
    if (res.getProtocol().equals("jar")) {
        try {
            InputStream input = getClass().getResourceAsStream(resource);
            file = File.createTempFile("tempfile", ".tmp");
            OutputStream out = new FileOutputStream(file);
            int read;
            byte[] bytes = new byte[1024];
    
            while ((read = input.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.close();
            file.deleteOnExit();
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    } else {
        //this will probably work in your IDE, but not from a JAR
        file = new File(res.getFile());
    }
    
    if (file != null && !file.exists()) {
        throw new RuntimeException("Error: File " + file + " not found!");
    }
    
    0 讨论(0)
  • 2020-11-22 09:48

    The one line answer is -

    String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
    

    Basically getResource method gives the URL. From this URL you can extract the path by calling toExternalForm()

    References:

    getResource(), toExternalForm()

    0 讨论(0)
提交回复
热议问题