21

有没有办法从与 .jar 文件位于同一文件夹中的文件中读取?我正在尝试创建一个在提交作业时必须从文件中读取的 java 程序。一旦我把文件或程序翻过来,我不知道文件或程序将保存在哪里,所以我认为我不能对保存文件的目录进行编码。这可能吗?问题是我必须将文件上传到作为 linux 服务器的 CSX 主机服务器并从那里运行它。如果我没有在文件之前放置路径,它只会搜索其当前文件夹位置吗?

4

8 回答 8

25

您可以通过以下方式获取包含任何特定类的 JAR 文件的位置:

URL url = thisClass.getProtectionDomain().getCodeSource().getLocation();

从那里很容易将 URL 相对化到所需的文件。

于 2013-02-20T09:24:30.983 回答
20

如评论中所述,这仅在您从 jar 所在的目录运行命令时才有效。

(在桌面应用程序的上下文中)
要访问当前目录中的文件jar,您path的文件前面应该有一个点。例子:

String path = "./properties.txt";
FileInputStream fis = new FileInputStream(path);
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
// Read the file contents...

在此示例中,properties.txt在与jar.
该文件将被包含在jar.

编辑:您说文件名不会改变,并且这个答案适用于您事先知道名称,当然,如果您更喜欢硬编码它。

于 2013-02-19T21:47:09.870 回答
3

如果输入文件名可以被硬编码,并且您知道它将始终与包含您的代码的 jar 位于同一目录中,那么这应该可以工作:

public static void main(String[] args) {

    try {
        // Determine where the input file is; assuming it's in the same directory as the jar
        String fileName = "input.txt";
        File jarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        String inputFilePath = jarFile.getParent() + File.separator + fileName;         
        FileInputStream inStream = new FileInputStream(new File(inputFilePath));

        try {

            // Read in the contents of the input file in a single gulp
            FileChannel fc = inStream.getChannel();
            MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
                    fc.size());

            // Do something with the read in data
            System.out.println(Charset.defaultCharset().decode(bb)
                    .toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            inStream.close();
        }

    } catch (IOException | URISyntaxException e) {
        e.printStackTrace();
    }

}
于 2013-02-19T22:30:57.923 回答
2

@kcpr - 感谢您提供的解决方案。下面一个对我有用。

private static String CONFIG_FILE_LOCATION = "lib"+ File.separator + "Config.properties";

static {
    File jarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
    String inputFilePath = jarFile.getParent() + File.separator + CONFIG_FILE_LOCATION; 
    propConfig = new PropertiesConfiguration(new File(inputFilePath));
    propConfig.load();
}
于 2018-03-06T06:57:01.390 回答
1

要使其“自包含”,请将资源放在Jar 中。然后它成为一个(只读)嵌入式资源,我们可以使用以下内容获取它的 URL:

URL url = this.getClass().getResource("/path/to/the.resource");
于 2013-02-20T01:14:52.963 回答
1

以下是获取 jar 文件的干净目录路径的方法(基于 EJP 的回答):

URL url = IssueInfoController.class.getProtectionDomain().getCodeSource().getLocation();
String urlString = url.toString();
int firstSlash =  urlString.indexOf("/");
int targetSlash = urlString.lastIndexOf("/", urlString.length() - 2) + 1;

return urlString.substring(firstSlash, targetSlash) + YOUR_FILE;
于 2015-03-09T13:16:33.600 回答
0

根据您的评论,我认为您最好的解决方案是将上传文件的绝对路径传递到 jar 中。

您可以将路径作为命令行参数传递到 jar 中。由于路径和文件名没有改变,并且您从 linux 运行它,您可以创建一个 .sh 脚本来运行它。

#!/bin/bash    
java -jar myjar.jar /path/to/file/filename.txt

这也使您无需在文件路径中进行硬编码,或将文件名放入 jar 中。

于 2013-02-19T21:14:38.703 回答
-1
public class TestClassLoaderAccess {
    public static void main(String[] argv) {
        TestClassLoaderAccess me = new TestClassLoaderAccess();
        ClassLoader myLoader = me.getClass().getClassLoader();
        System.out.println(myLoader.getClass().getSuperclass().getName());
        java.net.URLClassLoader myUrlLoader = (java.net.URLClassLoader) myLoader;
        java.net.URL resource = myUrlLoader.findResource("TestClassLoaderAccess.class");
        System.out.println(resource.toString());
    }
}

运行它:

C:\JavaTools>javac TestClassLoaderAccess.java

C:\JavaTools>java TestClassLoaderAccess
java.net.URLClassLoader
file:/C:/JavaTools/TestClassLoaderAccess.class

C:\JavaTools>

(第一个 println 只是为了证明类加载器是 URLClassLoader 的子类。)

于 2013-02-19T22:03:42.417 回答