如何从Java jar文件中读取资源文件?

时间:2022-09-25 10:32:40

I'm trying to access an XML file within a jar file, from a separate jar that's running as a desktop application. I can get the URL to the file I need, but when I pass that to a FileReader (as a String) I get a FileNotFoundException saying "The file name, directory name, or volume label syntax is incorrect."

我试图从作为桌面应用程序运行的一个单独的jar中访问jar文件中的XML文件。我可以获取到我需要的文件的URL,但是当我将它传递给一个FileReader(作为字符串)时,我将获得一个FileNotFoundException,表示“文件名、目录名或卷标签语法不正确”。

As a point of reference, I have no trouble reading image resources from the same jar, passing the URL to an ImageIcon constructor. This seems to indicate that the method I'm using to get the URL is correct.

作为参考点,我可以从同一个jar中读取图像资源,将URL传递给ImageIcon构造函数。这似乎表明我用于获取URL的方法是正确的。

URL url = getClass().getResource("/xxx/xxx/xxx/services.xml");
ServicesLoader jsl = new ServicesLoader( url.toString() );

Inside the ServicesLoader class I have

在ServicesLoader类中

XMLReader xr = XMLReaderFactory.createXMLReader();
xr.setContentHandler( this );
xr.setErrorHandler( this );
xr.parse( new InputSource( new FileReader( filename )));

What's wrong with using this technique to read the XML file?

使用这种技术读取XML文件有什么问题?

8 个解决方案

#1


52  

Looks like you want to use java.lang.Class.getResourceAsStream(String), see

看起来您想要使用java.lang. class . getresourcesstream (String),请参见

http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)

http://java.sun.com/javase/6/docs/api/java/lang/Class.html getResourceAsStream(以)

#2


5  

You don't say if this is a desktop or web app. I would use the getResourceAsStream() method from an appropriate ClassLoader if it's a desktop or the Context if it's a web app.

你不会说这是桌面应用还是web应用。如果是桌面应用程序,我会使用getresourcesstream()方法从合适的类加载器中获取,如果是web应用程序,则使用上下文。

#3


4  

It looks as if you are using the URL.toString result as the argument to the FileReader constructor. URL.toString is a bit broken, and instead you should generally use url.toURI().toString(). In any case, the string is not a file path.

看起来您好像在使用URL。将结果作为FileReader构造函数的参数。URL。toString有点破损,应该使用url.toURI().toString()。无论如何,字符串不是文件路径。

Instead, you should either:

相反,你应该:

  • Pass the URL to ServicesLoader and let it call openStream or similar.
  • 将URL传递给ServicesLoader,并让它调用openStream或类似的东西。
  • Use Class.getResourceAsStream and just pass the stream over, possibly inside an InputSource. (Remember to check for nulls as the API is a bit messy.)
  • 使用类。getresour凯撒流,并只是通过流,可能在一个InputSource中。(记住要检查null,因为API有点乱。)

#4


4  

The problem was that I was going a step too far in calling the parse method of XMLReader. The parse method accepts an InputSource, so there was no reason to even use a FileReader. Changing the last line of the code above to

问题是,我在调用XMLReader的解析方法时走得太远了。解析方法接受InputSource,因此甚至没有理由使用FileReader。将上面代码的最后一行更改为

xr.parse( new InputSource( filename ));

works just fine.

工作得很好。

#5


2  

I'd like to point out that one issues is what if the same resources are in multiple jar files. Let's say you want to read /org/node/foo.txt, but not from one file, but from each and every jar file.

我想指出的一个问题是,如果相同的资源存在于多个jar文件中,该怎么办?假设你想读/org/node/foo。txt,但不是来自一个文件,而是来自每个jar文件。

I have run into this same issue several times before. I was hoping in JDK 7 that someone would write a classpath filesystem, but alas not yet.

我以前遇到过好几次同样的问题。在JDK 7中,我希望有人会编写类路径文件系统,但是可惜还没有。

Spring has the Resource class which allows you to load classpath resources quite nicely.

Spring有一个资源类,它允许您很好地加载类路径资源。

I wrote a little prototype to solve this very problem of reading resources form multiple jar files. The prototype does not handle every edge case, but it does handle looking for resources in directories that are in the jar files.

我编写了一个小原型来解决从多个jar文件中读取资源的问题。原型不处理所有的边缘情况,但是它处理在jar文件的目录中查找资源。

I have used Stack Overflow for quite sometime. This is the second answer that I remember answering a question so forgive me if I go too long (it is my nature).

我使用栈溢出已经有一段时间了。这是我记得回答一个问题的第二个答案,如果我走得太久(这是我的本性),请原谅我。

This is a prototype resource reader. The prototype is devoid of robust error checking.

这是一个原型资源阅读器。该原型缺乏健壮的错误检查。

I have two prototype jar files that I have setup.

我已经安装了两个原型jar文件。

 <pre>
         <dependency>
              <groupId>invoke</groupId>
              <artifactId>invoke</artifactId>
              <version>1.0-SNAPSHOT</version>
          </dependency>

          <dependency>
               <groupId>node</groupId>
               <artifactId>node</artifactId>
               <version>1.0-SNAPSHOT</version>
          </dependency>

The jar files each have a file under /org/node/ called resource.txt.

jar文件在/ /org/node/下都有一个名为resource.txt的文件。

This is just a prototype of what a handler would look like with classpath:// I also have a resource.foo.txt in my local resources for this project.

这只是一个处理程序在类路径://我还有一个resource.foo的原型。txt在我的本地资源为这个项目。

It picks them all up and prints them out.

它把它们都拿起来,打印出来。

   

    package com.foo;

    import java.io.File;
    import java.io.FileReader;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.net.URI;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;

    /**
    * Prototype resource reader.
    * This prototype is devoid of error checking.
    *
    *
    * I have two prototype jar files that I have setup.
    * <pre>
    *             <dependency>
    *                  <groupId>invoke</groupId>
    *                  <artifactId>invoke</artifactId>
    *                  <version>1.0-SNAPSHOT</version>
    *              </dependency>
    *
    *              <dependency>
    *                   <groupId>node</groupId>
    *                   <artifactId>node</artifactId>
    *                   <version>1.0-SNAPSHOT</version>
    *              </dependency>
    * </pre>
    * The jar files each have a file under /org/node/ called resource.txt.
    * <br />
    * This is just a prototype of what a handler would look like with classpath://
    * I also have a resource.foo.txt in my local resources for this project.
    * <br />
    */
    public class ClasspathReader {

        public static void main(String[] args) throws Exception {

            /* This project includes two jar files that each have a resource located
               in /org/node/ called resource.txt.
             */


            /* 
              Name space is just a device I am using to see if a file in a dir
              starts with a name space. Think of namespace like a file extension 
              but it is the start of the file not the end.
            */
            String namespace = "resource";

            //someResource is classpath.
            String someResource = args.length > 0 ? args[0] :
                    //"classpath:///org/node/resource.txt";   It works with files
                    "classpath:///org/node/";                 //It also works with directories

            URI someResourceURI = URI.create(someResource);

            System.out.println("URI of resource = " + someResourceURI);

            someResource = someResourceURI.getPath();

            System.out.println("PATH of resource =" + someResource);

            boolean isDir = !someResource.endsWith(".txt");


            /** Classpath resource can never really start with a starting slash.
             * Logically they do, but in reality you have to strip it.
             * This is a known behavior of classpath resources.
             * It works with a slash unless the resource is in a jar file.
             * Bottom line, by stripping it, it always works.
             */
            if (someResource.startsWith("/")) {
                someResource = someResource.substring(1);
            }

              /* Use the ClassLoader to lookup all resources that have this name.
                 Look for all resources that match the location we are looking for. */
            Enumeration resources = null;

            /* Check the context classloader first. Always use this if available. */
            try {
                resources = 
                    Thread.currentThread().getContextClassLoader().getResources(someResource);
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            if (resources == null || !resources.hasMoreElements()) {
                resources = ClasspathReader.class.getClassLoader().getResources(someResource);
            }

            //Now iterate over the URLs of the resources from the classpath
            while (resources.hasMoreElements()) {
                URL resource = resources.nextElement();


                /* if the resource is a file, it just means that we can use normal mechanism
                    to scan the directory.
                */
                if (resource.getProtocol().equals("file")) {
                    //if it is a file then we can handle it the normal way.
                    handleFile(resource, namespace);
                    continue;
                }

                System.out.println("Resource " + resource);

               /*

                 Split up the string that looks like this:
                 jar:file:/Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar!/org/node/
                 into
                    this /Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar
                 and this
                     /org/node/
                */
                String[] split = resource.toString().split(":");
                String[] split2 = split[2].split("!");
                String zipFileName = split2[0];
                String sresource = split2[1];

                System.out.printf("After split zip file name = %s," +
                        " \nresource in zip %s \n", zipFileName, sresource);


                /* Open up the zip file. */
                ZipFile zipFile = new ZipFile(zipFileName);


                /*  Iterate through the entries.  */
                Enumeration entries = zipFile.entries();

                while (entries.hasMoreElements()) {
                    ZipEntry entry = entries.nextElement();
                    /* If it is a directory, then skip it. */
                    if (entry.isDirectory()) {
                        continue;
                    }

                    String entryName = entry.getName();
                    System.out.printf("zip entry name %s \n", entryName);

                    /* If it does not start with our someResource String
                       then it is not our resource so continue.
                    */
                    if (!entryName.startsWith(someResource)) {
                        continue;
                    }


                    /* the fileName part from the entry name.
                     * where /foo/bar/foo/bee/bar.txt, bar.txt is the file
                     */
                    String fileName = entryName.substring(entryName.lastIndexOf("/") + 1);
                    System.out.printf("fileName %s \n", fileName);

                    /* See if the file starts with our namespace and ends with our extension.        
                     */
                    if (fileName.startsWith(namespace) && fileName.endsWith(".txt")) {


                        /* If you found the file, print out 
                           the contents fo the file to System.out.*/
                        try (Reader reader = new InputStreamReader(zipFile.getInputStream(entry))) {
                            StringBuilder builder = new StringBuilder();
                            int ch = 0;
                            while ((ch = reader.read()) != -1) {
                                builder.append((char) ch);

                            }
                            System.out.printf("zip fileName = %s\n\n####\n contents of file %s\n###\n", entryName, builder);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }

                    //use the entry to see if it's the file '1.txt'
                    //Read from the byte using file.getInputStream(entry)
                }

            }


        }

        /**
         * The file was on the file system not a zip file,
         * this is here for completeness for this example.
         * otherwise.
         *
         * @param resource
         * @param namespace
         * @throws Exception
         */
        private static void handleFile(URL resource, String namespace) throws Exception {
            System.out.println("Handle this resource as a file " + resource);
            URI uri = resource.toURI();
            File file = new File(uri.getPath());


            if (file.isDirectory()) {
                for (File childFile : file.listFiles()) {
                    if (childFile.isDirectory()) {
                        continue;
                    }
                    String fileName = childFile.getName();
                    if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {

                        try (FileReader reader = new FileReader(childFile)) {
                            StringBuilder builder = new StringBuilder();
                            int ch = 0;
                            while ((ch = reader.read()) != -1) {
                                builder.append((char) ch);

                            }
                            System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", childFile, builder);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }

                    }

                }
            } else {
                String fileName = file.getName();
                if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {

                    try (FileReader reader = new FileReader(file)) {
                        StringBuilder builder = new StringBuilder();
                        int ch = 0;
                        while ((ch = reader.read()) != -1) {
                            builder.append((char) ch);

                        }
                        System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", fileName, builder);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }

            }
        }

    }


   

You can see a fuller example here with the sample output.

您可以在这里看到一个更完整的示例输出。

#6


0  

Outside of your technique, why not use the standard Java JarFile class to get the references you want? From there most of your problems should go away.

除了技术之外,为什么不使用标准的Java JarFile类来获取所需的引用呢?从那时起,你的大部分问题都应该解决。

#7


0  

If you use resources extensively, you might consider using Commons VFS.

如果您大量使用资源,您可以考虑使用Commons VFS。

Also supports: * Local Files * FTP, SFTP * HTTP and HTTPS * Temporary Files "normal FS backed) * Zip, Jar and Tar (uncompressed, tgz or tbz2) * gzip and bzip2 * resources * ram - "ramdrive" * mime

还支持:*本地文件* FTP、SFTP * HTTP和HTTPS *临时文件“正常FS支持”)* Zip、Jar和Tar(未压缩、tgz或tbz2) * gzip和bzip2 * resources * ram -“ramdrive”* mime

There's also JBoss VFS - but it's not much documented.

还有JBoss VFS,但是没有太多的文档说明。

#8


0  

I have 2 CSV files that I use to read data. The java program is exported as a runnable jar file. When you export it, you will figure out it doesn't export your resources with it.

我有两个CSV文件用来读取数据。java程序被导出为可运行的jar文件。当你导出它时,你会发现它并没有导出你的资源。

I added a folder under project called data in eclipse. In that folder i stored my csv files.

我在项目下添加了一个名为eclipse中的data的文件夹。在那个文件夹中我存储了我的csv文件。

When I need to reference those files I do it like this...

当我需要引用那些文件时,我会这样做……

private static final String ZIP_FILE_LOCATION_PRIMARY = "free-zipcode-database-Primary.csv";
private static final String ZIP_FILE_LOCATION = "free-zipcode-database.csv";

private static String getFileLocation(){
    String loc = new File("").getAbsolutePath() + File.separatorChar +
        "data" + File.separatorChar;
    if (usePrimaryZipCodesOnly()){              
        loc = loc.concat(ZIP_FILE_LOCATION_PRIMARY);
    } else {
        loc = loc.concat(ZIP_FILE_LOCATION);
    }
    return loc;
}

Then when you put the jar in a location so it can be ran via commandline, make sure that you add the data folder with the resources into the same location as the jar file.

然后,当您将jar放在一个位置,以便它可以通过命令行运行时,请确保将资源添加到与jar文件相同位置的数据文件夹。

#1


52  

Looks like you want to use java.lang.Class.getResourceAsStream(String), see

看起来您想要使用java.lang. class . getresourcesstream (String),请参见

http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)

http://java.sun.com/javase/6/docs/api/java/lang/Class.html getResourceAsStream(以)

#2


5  

You don't say if this is a desktop or web app. I would use the getResourceAsStream() method from an appropriate ClassLoader if it's a desktop or the Context if it's a web app.

你不会说这是桌面应用还是web应用。如果是桌面应用程序,我会使用getresourcesstream()方法从合适的类加载器中获取,如果是web应用程序,则使用上下文。

#3


4  

It looks as if you are using the URL.toString result as the argument to the FileReader constructor. URL.toString is a bit broken, and instead you should generally use url.toURI().toString(). In any case, the string is not a file path.

看起来您好像在使用URL。将结果作为FileReader构造函数的参数。URL。toString有点破损,应该使用url.toURI().toString()。无论如何,字符串不是文件路径。

Instead, you should either:

相反,你应该:

  • Pass the URL to ServicesLoader and let it call openStream or similar.
  • 将URL传递给ServicesLoader,并让它调用openStream或类似的东西。
  • Use Class.getResourceAsStream and just pass the stream over, possibly inside an InputSource. (Remember to check for nulls as the API is a bit messy.)
  • 使用类。getresour凯撒流,并只是通过流,可能在一个InputSource中。(记住要检查null,因为API有点乱。)

#4


4  

The problem was that I was going a step too far in calling the parse method of XMLReader. The parse method accepts an InputSource, so there was no reason to even use a FileReader. Changing the last line of the code above to

问题是,我在调用XMLReader的解析方法时走得太远了。解析方法接受InputSource,因此甚至没有理由使用FileReader。将上面代码的最后一行更改为

xr.parse( new InputSource( filename ));

works just fine.

工作得很好。

#5


2  

I'd like to point out that one issues is what if the same resources are in multiple jar files. Let's say you want to read /org/node/foo.txt, but not from one file, but from each and every jar file.

我想指出的一个问题是,如果相同的资源存在于多个jar文件中,该怎么办?假设你想读/org/node/foo。txt,但不是来自一个文件,而是来自每个jar文件。

I have run into this same issue several times before. I was hoping in JDK 7 that someone would write a classpath filesystem, but alas not yet.

我以前遇到过好几次同样的问题。在JDK 7中,我希望有人会编写类路径文件系统,但是可惜还没有。

Spring has the Resource class which allows you to load classpath resources quite nicely.

Spring有一个资源类,它允许您很好地加载类路径资源。

I wrote a little prototype to solve this very problem of reading resources form multiple jar files. The prototype does not handle every edge case, but it does handle looking for resources in directories that are in the jar files.

我编写了一个小原型来解决从多个jar文件中读取资源的问题。原型不处理所有的边缘情况,但是它处理在jar文件的目录中查找资源。

I have used Stack Overflow for quite sometime. This is the second answer that I remember answering a question so forgive me if I go too long (it is my nature).

我使用栈溢出已经有一段时间了。这是我记得回答一个问题的第二个答案,如果我走得太久(这是我的本性),请原谅我。

This is a prototype resource reader. The prototype is devoid of robust error checking.

这是一个原型资源阅读器。该原型缺乏健壮的错误检查。

I have two prototype jar files that I have setup.

我已经安装了两个原型jar文件。

 &lt;pre>
         &lt;dependency>
              &lt;groupId>invoke&lt;/groupId>
              &lt;artifactId>invoke&lt;/artifactId>
              &lt;version>1.0-SNAPSHOT&lt;/version>
          &lt;/dependency>

          &lt;dependency>
               &lt;groupId>node&lt;/groupId>
               &lt;artifactId>node&lt;/artifactId>
               &lt;version>1.0-SNAPSHOT&lt;/version>
          &lt;/dependency>

The jar files each have a file under /org/node/ called resource.txt.

jar文件在/ /org/node/下都有一个名为resource.txt的文件。

This is just a prototype of what a handler would look like with classpath:// I also have a resource.foo.txt in my local resources for this project.

这只是一个处理程序在类路径://我还有一个resource.foo的原型。txt在我的本地资源为这个项目。

It picks them all up and prints them out.

它把它们都拿起来,打印出来。

   

    package com.foo;

    import java.io.File;
    import java.io.FileReader;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.net.URI;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;

    /**
    * Prototype resource reader.
    * This prototype is devoid of error checking.
    *
    *
    * I have two prototype jar files that I have setup.
    * <pre>
    *             <dependency>
    *                  <groupId>invoke</groupId>
    *                  <artifactId>invoke</artifactId>
    *                  <version>1.0-SNAPSHOT</version>
    *              </dependency>
    *
    *              <dependency>
    *                   <groupId>node</groupId>
    *                   <artifactId>node</artifactId>
    *                   <version>1.0-SNAPSHOT</version>
    *              </dependency>
    * </pre>
    * The jar files each have a file under /org/node/ called resource.txt.
    * <br />
    * This is just a prototype of what a handler would look like with classpath://
    * I also have a resource.foo.txt in my local resources for this project.
    * <br />
    */
    public class ClasspathReader {

        public static void main(String[] args) throws Exception {

            /* This project includes two jar files that each have a resource located
               in /org/node/ called resource.txt.
             */


            /* 
              Name space is just a device I am using to see if a file in a dir
              starts with a name space. Think of namespace like a file extension 
              but it is the start of the file not the end.
            */
            String namespace = "resource";

            //someResource is classpath.
            String someResource = args.length > 0 ? args[0] :
                    //"classpath:///org/node/resource.txt";   It works with files
                    "classpath:///org/node/";                 //It also works with directories

            URI someResourceURI = URI.create(someResource);

            System.out.println("URI of resource = " + someResourceURI);

            someResource = someResourceURI.getPath();

            System.out.println("PATH of resource =" + someResource);

            boolean isDir = !someResource.endsWith(".txt");


            /** Classpath resource can never really start with a starting slash.
             * Logically they do, but in reality you have to strip it.
             * This is a known behavior of classpath resources.
             * It works with a slash unless the resource is in a jar file.
             * Bottom line, by stripping it, it always works.
             */
            if (someResource.startsWith("/")) {
                someResource = someResource.substring(1);
            }

              /* Use the ClassLoader to lookup all resources that have this name.
                 Look for all resources that match the location we are looking for. */
            Enumeration resources = null;

            /* Check the context classloader first. Always use this if available. */
            try {
                resources = 
                    Thread.currentThread().getContextClassLoader().getResources(someResource);
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            if (resources == null || !resources.hasMoreElements()) {
                resources = ClasspathReader.class.getClassLoader().getResources(someResource);
            }

            //Now iterate over the URLs of the resources from the classpath
            while (resources.hasMoreElements()) {
                URL resource = resources.nextElement();


                /* if the resource is a file, it just means that we can use normal mechanism
                    to scan the directory.
                */
                if (resource.getProtocol().equals("file")) {
                    //if it is a file then we can handle it the normal way.
                    handleFile(resource, namespace);
                    continue;
                }

                System.out.println("Resource " + resource);

               /*

                 Split up the string that looks like this:
                 jar:file:/Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar!/org/node/
                 into
                    this /Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar
                 and this
                     /org/node/
                */
                String[] split = resource.toString().split(":");
                String[] split2 = split[2].split("!");
                String zipFileName = split2[0];
                String sresource = split2[1];

                System.out.printf("After split zip file name = %s," +
                        " \nresource in zip %s \n", zipFileName, sresource);


                /* Open up the zip file. */
                ZipFile zipFile = new ZipFile(zipFileName);


                /*  Iterate through the entries.  */
                Enumeration entries = zipFile.entries();

                while (entries.hasMoreElements()) {
                    ZipEntry entry = entries.nextElement();
                    /* If it is a directory, then skip it. */
                    if (entry.isDirectory()) {
                        continue;
                    }

                    String entryName = entry.getName();
                    System.out.printf("zip entry name %s \n", entryName);

                    /* If it does not start with our someResource String
                       then it is not our resource so continue.
                    */
                    if (!entryName.startsWith(someResource)) {
                        continue;
                    }


                    /* the fileName part from the entry name.
                     * where /foo/bar/foo/bee/bar.txt, bar.txt is the file
                     */
                    String fileName = entryName.substring(entryName.lastIndexOf("/") + 1);
                    System.out.printf("fileName %s \n", fileName);

                    /* See if the file starts with our namespace and ends with our extension.        
                     */
                    if (fileName.startsWith(namespace) && fileName.endsWith(".txt")) {


                        /* If you found the file, print out 
                           the contents fo the file to System.out.*/
                        try (Reader reader = new InputStreamReader(zipFile.getInputStream(entry))) {
                            StringBuilder builder = new StringBuilder();
                            int ch = 0;
                            while ((ch = reader.read()) != -1) {
                                builder.append((char) ch);

                            }
                            System.out.printf("zip fileName = %s\n\n####\n contents of file %s\n###\n", entryName, builder);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }

                    //use the entry to see if it's the file '1.txt'
                    //Read from the byte using file.getInputStream(entry)
                }

            }


        }

        /**
         * The file was on the file system not a zip file,
         * this is here for completeness for this example.
         * otherwise.
         *
         * @param resource
         * @param namespace
         * @throws Exception
         */
        private static void handleFile(URL resource, String namespace) throws Exception {
            System.out.println("Handle this resource as a file " + resource);
            URI uri = resource.toURI();
            File file = new File(uri.getPath());


            if (file.isDirectory()) {
                for (File childFile : file.listFiles()) {
                    if (childFile.isDirectory()) {
                        continue;
                    }
                    String fileName = childFile.getName();
                    if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {

                        try (FileReader reader = new FileReader(childFile)) {
                            StringBuilder builder = new StringBuilder();
                            int ch = 0;
                            while ((ch = reader.read()) != -1) {
                                builder.append((char) ch);

                            }
                            System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", childFile, builder);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }

                    }

                }
            } else {
                String fileName = file.getName();
                if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {

                    try (FileReader reader = new FileReader(file)) {
                        StringBuilder builder = new StringBuilder();
                        int ch = 0;
                        while ((ch = reader.read()) != -1) {
                            builder.append((char) ch);

                        }
                        System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", fileName, builder);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }

            }
        }

    }


   

You can see a fuller example here with the sample output.

您可以在这里看到一个更完整的示例输出。

#6


0  

Outside of your technique, why not use the standard Java JarFile class to get the references you want? From there most of your problems should go away.

除了技术之外,为什么不使用标准的Java JarFile类来获取所需的引用呢?从那时起,你的大部分问题都应该解决。

#7


0  

If you use resources extensively, you might consider using Commons VFS.

如果您大量使用资源,您可以考虑使用Commons VFS。

Also supports: * Local Files * FTP, SFTP * HTTP and HTTPS * Temporary Files "normal FS backed) * Zip, Jar and Tar (uncompressed, tgz or tbz2) * gzip and bzip2 * resources * ram - "ramdrive" * mime

还支持:*本地文件* FTP、SFTP * HTTP和HTTPS *临时文件“正常FS支持”)* Zip、Jar和Tar(未压缩、tgz或tbz2) * gzip和bzip2 * resources * ram -“ramdrive”* mime

There's also JBoss VFS - but it's not much documented.

还有JBoss VFS,但是没有太多的文档说明。

#8


0  

I have 2 CSV files that I use to read data. The java program is exported as a runnable jar file. When you export it, you will figure out it doesn't export your resources with it.

我有两个CSV文件用来读取数据。java程序被导出为可运行的jar文件。当你导出它时,你会发现它并没有导出你的资源。

I added a folder under project called data in eclipse. In that folder i stored my csv files.

我在项目下添加了一个名为eclipse中的data的文件夹。在那个文件夹中我存储了我的csv文件。

When I need to reference those files I do it like this...

当我需要引用那些文件时,我会这样做……

private static final String ZIP_FILE_LOCATION_PRIMARY = "free-zipcode-database-Primary.csv";
private static final String ZIP_FILE_LOCATION = "free-zipcode-database.csv";

private static String getFileLocation(){
    String loc = new File("").getAbsolutePath() + File.separatorChar +
        "data" + File.separatorChar;
    if (usePrimaryZipCodesOnly()){              
        loc = loc.concat(ZIP_FILE_LOCATION_PRIMARY);
    } else {
        loc = loc.concat(ZIP_FILE_LOCATION);
    }
    return loc;
}

Then when you put the jar in a location so it can be ran via commandline, make sure that you add the data folder with the resources into the same location as the jar file.

然后,当您将jar放在一个位置,以便它可以通过命令行运行时,请确保将资源添加到与jar文件相同位置的数据文件夹。