是否可以在.jar中获取类包的目录?

时间:2017-09-24 19:30:51

标签: java jar uri java-io csvjdbc

我试图在我的.jar中将类包的目录作为File(层次结构为/controller/core):

File directory_file_of_package = new File(getClass().getResource("/controller/core").toURI());

当我在IDE中运行程序时,哪个有效,但是当我以独立的.jar运行它时,它会给我这个错误:

java.lang.IllegalArgumentException: URI is not hierarchical

查看这些问题(why my URI is not hierarchical?Java Jar file: use resource errors: URI is not hierarchical)对我没有帮助,因为这些问题涉及在.jar中获取File作为资源(getResourceAsStream()) ,但我想要获得的是一个目录。

此外,接受的答案说明了这一点:

  

通常,IDE会分离文件系统类和资源。但是当创建jar时,它们就会被放在一起。

那么,有没有办法获取/controller/core目录?

我的XY问题:

我正在尝试使用CSVJDBC(http://csvjdbc.sourceforge.net/)读取.CSV文件,以及DriverManager引用CSV文件的方式,就像 包含文件夹 数据库 CSV文件 表< / EM>

public class SearchData {

    void SearchData() {
        try {
            Class.forName("org.relique.jdbc.csv.CsvDriver");

            File directory_file_of_package_containing_csv = new File(getClass().getResource("/controller/core").toURI());

            // Driver points to directory which contains the CSV file as if it is the database
            Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + directory_file_of_package_containing_csv.toString());
            System.out.println("Connection established.");
            Statement stmt = conn.createStatement();
            System.out.println("Statement created.");

            // CSV is named "data.csv" so the CsvDriver sees "data" as the table name
            String sql = "SELECT id,name FROM data";

            ResultSet results = stmt.executeQuery(sql);

            ...

        } catch (ClassNotFoundException | SQLException | URISyntaxException e) {
            e.printStackTrace();            
        }
    }
}

如何将CsvJdbc指向.jar中包含的csv文件?

1 个答案:

答案 0 :(得分:1)

JAR中根本没有包的目录。它在IDE中工作,因为您的类尚未打包在JAR文件中并驻留在某个目录中。但JAR并非如此。

因此,如果您使用的某些库需要包含文件的目录,则通常无法使用类路径资源实现此目的。其中一个选项是将资源副本创建为临时目录中的文件。

或者您可能想要研究CsvJDBC documentation更接近:

  

要读取保存在Java应用程序内部(例如,在JAR文件中)或远程访问(例如,使用HTTP请求)的数据,请创建一个实现接口org.relique.io.TableReader的Java类并提供连接URL中的此类名称。然后,CsvJdbc创建此类的实例,并调用getReader方法为正在读取的每个数据库表获取java.io.Reader

所以你应该能够在没有临时目录的情况下为CsvJDBC解决这个问题。