2013-02-19 97 views
12

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

+0

什么是您的上下文:小程序或桌面?你可以将文件放入JAR中作为资源吗? – Aubin 2013-02-19 21:09:22

+0

你可以让你的程序把文件的路径作为命令行参数吗? – dnault 2013-02-19 21:13:45

+1

使用ClassLoader.findResource查找您的班级。解码生成的URL以找出它的位置。 – 2013-02-19 21:14:02

回答

13

正如在评论中指出,如果从目录中的jar在运行命令这只适用。

(在桌面应用程序的情况下)
要访问一个文件,该文件在jar的当前目录中,该文件的path应该以点开头。例如:

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

在这个例子中,存在在同一目录中jar称为properties.txt的文本文件。
该文件将被包含在jar中的程序读取。

编辑:你说文件名不会改变,这个答案适用,因为你事先知道这个名字,当然,你应该选择硬编码。

+8

这是比我更清洁的解决方案,但它不处理所有情况。有时候当前目录(。)与包含应用程序jar的目录不一样。假设你的jar被称为app.jar并且位于一个名为target的dir中;如果分级人员从目标目录中键入“java -jar app.jar”,那么你的解决方案将会工作。然而,如果分级者在应用程序之外的一个层级上运行java命令,例如“java -jar ./target/app.jar”,那么你的解决方案会在目标目录之外寻找输入文件,因此找不到它。 – Darwyn 2013-02-19 22:49:56

+0

我确信点总是会映射到正在运行的jar的当前位置。感谢您指出了这一点! – afsantos 2013-02-19 23:29:53

+2

将'./'添加到文件名的前面完全没有。 'JAR的当前目录'与'.jar'的文件夹不同。 -1 – EJP 2014-04-12 02:57:48

0

根据你的意见,我认为你最好的解决方案是将上传文件的绝对路径传入jar。

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

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

这也将您从文件路径中的硬编码或文件名解压到jar中。

+0

不回答问题。再读一遍。他不知道文件将在哪里。 – EJP 2014-02-25 22:59:15

+0

在您的年度检查旧的问题? – aglassman 2014-02-26 17:23:16

+2

真相不是时间的功能。 – EJP 2015-11-24 02:48:42

-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的一个子类)。

+0

这会在JAR中查找资源*。它只在这里工作,因为根本没有JAR。不是要求什么。没有答案。 – EJP 2014-02-25 22:36:41

2

如果输入文件名可以是硬编码的,你知道它将永远驻留在与包含您的代码的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(); 
    } 

} 
+2

*“这应该工作:”*它不适用于使用JWS启动的applet或任何应用程序,可能也不是servlet。即使Sun早就告诉我们WTE,“不要试图找到可执行文件 - 它不是应用程序业务。” – 2013-02-20 01:28:08

+0

真的,它会在applet中失败,或者由java web start启动,或者在应用程序服务器(例如OSGi,IBM WebSphere,Oracle WebLogics等)中运行时失败。但它将作为一个普通的桌面Java应用程序。 – Darwyn 2013-02-20 02:52:04

+1

桌面应用程序? *“一个Linux服务器,并从那里运行”*似乎不像我的桌面。 – 2013-02-20 03:00:14

1

为了使它'独立',把的资源放在的罐子里。然后,它变成了(只读)embedded resource我们可以针对其使用的线沿线的东西获得网址:

URL url = this.getClass().getResource("/path/to/the.resource"); 
19

你可以通过包含任何具体类的JAR文件的位置:

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

从那里可以很容易地将URL关联到所需的文件。

0

这里是你如何让你的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; 
+1

应该使用'URL.getPath()'代替所有这些。 – EJP 2016-01-18 22:12:29

0

@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(); 
} 
相关问题