首页 文章

如何从jar文件中读取文件?

提问于
浏览
29

我在JAR文件中有一个文件 . 例如,它是 1.txt .

我该如何访问它?我的源代码是:

Double result=0.0;
File file = new File("1.txt")); //how get this file from a jar file
BufferedReader input = new BufferedReader(new FileReader(file));
String line;
while ((line = input.readLine()) != null) {
  if(me==Integer.parseInt(line.split(":")[0])){
    result= parseDouble(line.split(":")[1]);
  }
}
input.close();
return result;

8 回答

  • 4
    private String loadResourceFileIntoString(String path) {
        //path = "/resources/html/custom.css" for example
        BufferedReader buffer = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(path)));
        return buffer.lines().collect(Collectors.joining(System.getProperty("line.separator")));
    }
    
  • 1

    我以前曾多次遇到同样的问题 . 我希望在JDK 7中有人会写一个类路径文件系统,但还没有 .

    Spring有Resource类,它允许你很好地加载类路径资源 .

    答案非常好,但我想我可以在讨论中添加一个可以处理类路径资源的文件和目录的示例 .

    我写了一个小原型来解决这个问题 . 原型不处理每个边缘情况,但它确实处理查找jar文件中的目录中的资源 .

    我已经使用Stack Overflow很长一段时间了 . 这是我第一次记得回答一个问题,请原谅我,如果我长途跋涉(这是我的天性) .

    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.
        * 
    * 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. *
    */ 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.

  • 47

    类似于this answer的东西就是你所需要的 .

    您需要以特殊方式将文件从存档中提取出来 .

    BufferedReader input = new BufferedReader(new InputStreamReader(
             this.getClass().getClassLoader().getResourceAsStream("1.txt")));
    
  • 1

    Jar文件是一个zip文件.....

    所以要读取一个jar文件,试试吧

    ZipFile file = new ZipFile("whatever.jar");
    if (file != null) {
       ZipEntries entries = file.entries(); //get entries from the zip file...
    
       if (entries != null) {
          while (entries.hasMoreElements()) {
              ZipEntry entry = entries.nextElement();
    
              //use the entry to see if it's the file '1.txt'
              //Read from the byte using file.getInputStream(entry)
          }
        }
    }
    

    希望这可以帮助 .

  • 4

    您无法使用File,因为此文件在文件系统上不是独立存在的 . 相反,你需要getResourceAsStream(),如下所示:

    ...
    InputStream in = getClass().getResourceAsStream("/1.txt");
    BufferedReader input = new BufferedReader(new InputStreamReader(in));
    ...
    
  • 2

    如果你的jar在classpath上:

    InputStream is = YourClass.class.getResourceAsStream("1.txt");
    

    如果它不在类路径上,那么您可以通过以下方式访问它:

    URL url = new URL("jar:file:/absolute/location/of/yourJar.jar!/1.txt");
    InputStream is = url.openStream();
    
  • -1

    这有助于我将一个txt文件从jar文件复制到另一个txt文件

    public static void copyTextMethod() throws Exception{
        String inputPath = "path/to/.jar";
        String outputPath = "Desktop/CopyText.txt";
    
        File resStreamOut = new File(outputPath);
    
         int readBytes;
         JarFile file = new JarFile(inputPath);
    
         FileWriter fw = new FileWriter(resStreamOut);
    
        try{
            Enumeration<JarEntry> entries = file.entries();
            while (entries.hasMoreElements()){
                JarEntry entry = entries.nextElement();
            if (entry.getName().equals("readMe/tempReadme.txt")) {
    
                    System.out.println(entry +" : Entry");
                InputStream is = file.getInputStream(entry);
                BufferedWriter output = new BufferedWriter(fw);
                     while ((readBytes = is.read()) != -1) {
                        output.write((char) readBytes);
                     }
                    System.out.println(outputPath);
                    output.close();
                } 
            }
        } catch(Exception er){
            er.printStackTrace();
        }
            }
                }
    
  • 28
    InputStream inputStreamLastName = this.getClass().getClassLoader().getResourceAsStream("path of file");
    
    
        try {
    
            br  = new BufferedReader(new InputStreamReader(inputStreamLastName, "UTF-8"));
            String sCurrentLine;
            ArrayList<String> lastNamesList = new ArrayList<String>();
            while ((sCurrentLine = br.readLine()) != null) {
    
                if(sCurrentLine.length()>=min && sCurrentLine.length()<=max){
                    lastNamesList.add(sCurrentLine);
                }
    
            }
    

相关问题