简体   繁体   中英

Java Convert Jar URL to File

I am trying to achieve the following: From a given Class object, I want to be able to retrieve the folder or file in which it is located. This should also work for System classes like java.lang.String (which would return the location of rt.jar ). For 'source' classes, the method should return the root folder:

- bin
  - com
    - test
      - Test.class

would return the location of the bin folder for file(com.test.Test.class) . This is my implementation so far:

public static File getFileLocation(Class<?> klass)
{
    String classLocation = '/' + klass.getName().replace('.', '/') + ".class";
    URL url = klass.getResource(classLocation);
    String path = url.getPath();
    int index = path.lastIndexOf(classLocation);
    if (index < 0)
    {
        return null;
    }

    // Jar Handling
    if (path.charAt(index - 1) == '!')
    {
        index--;
    }
    else
    {
        index++;
    }

    int index1 = path.lastIndexOf(':', index);
    String newPath = path.substring(index1 + 1, index);

    System.out.println(url.toExternalForm());
    URI uri = URI.create(newPath).normalize();

    return new File(uri);
}

However, this code fails because the File(URI) constructor throws an IllegalArgumentException - "URI is not absolute". I already tried to use the newPath to construct the file, but this failed for directory structures with spaces, like this one:

- Eclipse Workspace
  - MyProgram
    - bin
      - Test.class

This is due to the fact that the URL representation uses %20 to denote a whitespace, which is not recognized by the file constructor.

Is there an efficient and reliable way to get the (classpath) location of a Java class, which works for both directory structures and Jar files?

Note that I don't need the exact file of the exact class - only the container! I use this code to locate rt.jar and the language library for using them in a compiler.

Slight modification in your code should work here. You can try below code:

public static File getFileLocation(Class<?> klass)
{
    String classLocation = '/' + klass.getName().replace('.', '/') + ".class";
    URL url = klass.getResource(classLocation);
    String path = url.getPath();
    int index = path.lastIndexOf(classLocation);
    if (index < 0)
    {
        return null;
    }

    String fileCol = "file:";
    //add "file:" for local files
    if (path.indexOf(fileCol) == -1)
    {
        path = fileCol + path;
        index+=fileCol.length();
    }

    // Jar Handling
    if (path.charAt(index - 1) == '!')
    {
        index--;
    }
    else
    {
        index++;
    }

    String newPath = path.substring(0, index);

    System.out.println(url.toExternalForm());
    URI uri = URI.create(newPath).normalize();

    return new File(uri);
}

Hope this will help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM