Как прочитать файл из файла JAR? - PullRequest
29 голосов
/ 16 февраля 2010

У меня есть файл в 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 ]

47 голосов
/ 16 февраля 2010

Если ваша банка находится на пути к классам:

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

Если его нет в пути к классам, вы можете получить к нему доступ через:

URL url = new URL("jar:file:/absolute/location/of/yourJar.jar!/1.txt");
InputStream is = url.openStream();
28 голосов
/ 16 февраля 2010

Вы не можете использовать Файл, так как этот файл не существует независимо в файловой системе. Вместо этого вам нужен getResourceAsStream (), например:

...
InputStream in = getClass().getResourceAsStream("/1.txt");
BufferedReader input = new BufferedReader(new InputStreamReader(in));
...
4 голосов
/ 16 февраля 2010

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 голосов
/ 16 февраля 2010

Что-то похожее на этот ответ - это то, что вам нужно.

Вы должны извлечь файл из архива особым образом.

BufferedReader input = new BufferedReader(new InputStreamReader(
         this.getClass().getClassLoader().getResourceAsStream("1.txt")));
2 голосов
/ 10 декабря 2016
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 голос
/ 06 ноября 2013

Это помогло мне скопировать текстовый файл из jar-файла в другой текстовый файл

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();
    }
        }
            }
1 голос
/ 13 октября 2013

Я сталкивался с этой же проблемой несколько раз раньше. В JDK 7 я надеялся, что кто-то напишет файловую систему classpath, но, увы, пока нет.

Spring имеет класс Resource, который позволяет вам очень приятно загружать ресурсы classpath.

Ответы были очень хорошими, но я подумал, что могу добавить к обсуждению пример с файлами и каталогами, которые являются ресурсами classpath.

Я написал небольшой прототип, чтобы решить эту проблему. Прототип не обрабатывает каждый крайний случай, но он обрабатывает поиск ресурсов в каталогах, которые находятся в jar-файлах.

Я довольно давно использовал переполнение стека. Это первый раз, когда я помню, как отвечаю на вопрос, так что прости меня, если я пойду долго (это моя натура).

   <code>

    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>
    * 
* Каждый из jar-файлов имеет файл в / org / node / с именем resource.txt. *
* Это всего лишь прототип того, как будет выглядеть обработчик с classpath: // * У меня также есть resource.foo.txt в моих локальных ресурсах для этого проекта. *
* / открытый класс ClasspathReader { public static void main (String [] args) выдает Exception { / * Этот проект включает в себя два файла JAR, каждый из которых имеет ресурс, расположенный в / org / node / называется resource.txt. * / / * Пространство имен - это просто устройство, которое я использую, чтобы увидеть, есть ли файл в каталоге начинается с пространства имен. Думайте о пространстве имен как о расширении файла но это начало файла, а не конец. * / String namespace = "resource"; // someResource является classpath. Строка someResource = args.length> 0? args [0]: //"classpath:///org/node/resource.txt "; Работает с файлами "Путь к классам: /// орг / узел /"; // Также работает с каталогами URI someResourceURI = URI.create (someResource); System.out.println ("URI ресурса =" + someResourceURI); someResource = someResourceURI.getPath (); System.out.println ("ПУТЬ ресурса =" + someResource); boolean isDir =! someResource.endsWith (". txt"); / ** Ресурс Classpath никогда не может начинаться с начального слеша. * Логически они делают, но на самом деле вы должны раздеть это. * Это известное поведение ресурсов classpath. * Он работает с косой чертой, если ресурс не находится в файле JAR. * Итог, удаляя его, он всегда работает. * / if (someResource.startsWith ("/")) { someResource = someResource.substring (1); } / * Используйте ClassLoader для поиска всех ресурсов, которые имеют это имя. Ищите все ресурсы, которые соответствуют местоположению, которое мы ищем. * / Ресурсы перечисления = ноль; / * Сначала проверьте контекстный загрузчик классов. Всегда используйте это, если доступно. * / пытаться { ресурсы = . Thread.currentThread () getContextClassLoader () GetResources (someResource). } catch (Exex ex) { ex.printStackTrace (); } if (resources == null ||! resources.hasMoreElements ()) { resources = ClasspathReader.class.getClassLoader (). getResources (someResource); } // Теперь перебираем URL ресурсов из пути к классам while (resources.hasMoreElements ()) { URL resource = resources.nextElement (); / * если ресурс представляет собой файл, это просто означает, что мы можем использовать обычный механизм сканировать каталог. * / if (resource.getProtocol (). equals ("file")) { // если это файл, то мы можем обработать его обычным способом. handleFile (ресурс, пространство имен); Продолжить;} System.out.println («Ресурс» + ресурс); / * Разделите строку, которая выглядит следующим образом: баночка: файл! /Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar / орг / узел / в это /Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar и это / Орг / узел / * / String [] split = resource.toString (). Split (":"); String [] split2 = split [2] .split ("!"); String zipFileName = split2 [0]; String sresource = split2 [1]; System.out.printf («Имя файла после разделения zip =% s,» + "\ nresource in zip% s \ n", zipFileName, sresource); / * Откройте zip-файл. * / ZipFile zipFile = новый ZipFile (zipFileName); / * Перебирать записи. * / Записи перечисления = zipFile.entries (); while (records.hasMoreElements ()) { ZipEntry entry = records.nextElement (); / * Если это каталог, пропустите его. * / if (entry.isDirectory ()) { Продолжить; } String entryName = entry.getName (); System.out.printf ("имя записи zip% s \ n", entryName); / * Если он не начинается с нашей строки someResource тогда это не наш ресурс, так что продолжайте. * / if (! entryName.startsWith (someResource)) { Продолжить; } / * часть fileName из имени записи. * где /foo/bar/foo/bee/bar.txt, bar.txt - это файл * / String fileName = entryName.substring (entryName.lastIndexOf ("/") + 1); System.out.printf ("имя_файла% s \ n", имя_файла); / * Посмотрим, начинается ли файл с нашего пространства имен и заканчивается нашим расширением. * / if (fileName.startsWith (namespace) && fileName.endsWith (". txt")) { / * Если вы нашли файл, распечатайте содержимое файла в 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 содержимое файла% s \ n ### \ n", entryName, builder); } catch (Exex ex) { ex.printStackTrace (); } } // используем запись, чтобы увидеть, является ли это файл «1.txt» // Чтение из байта с использованием file.getInputStream (entry) } } } / ** * Файл находился в файловой системе, а не в zip-файле, * это здесь для полноты для этого примера. * иначе. * ресурс @param * @param namespace * Исключения @throws * / приватный статический void handleFile (ресурс URL, пространство имен String) выдает исключение { System.out.println («Обрабатывать этот ресурс как файл» + ресурс); URI uri = resource.toURI (); Файл файл = новый файл (uri.getPath ()); if (file.isDirectory ()) { for (Файл childFile: file.listFiles ()) { if (childFile.isDirectory ()) { Продолжить; }String fileName = childFile.getName (); if (fileName.startsWith (пространство имен) && 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 содержимое файла% s \ n ### \ n", childFile, строитель); } catch (Exex ex) { ex.printStackTrace (); } } } } еще { Строка fileName = file.getName (); if (fileName.startsWith (пространство имен) && fileName.endsWith ("txt")) { try (FileReader Reader = новый FileReader (файл)) { StringBuilder builder = new StringBuilder (); int ch = 0; while ((ch = reader.read ())! = -1) { builder.append ((char) ch); } System.out.printf ("fileName =% s \ n \ n #### \ n содержимое файла% s \ n ### \ n", fileName, строитель); } catch (Exex ex) { ex.printStackTrace (); } } } } }

Здесь вы можете увидеть более полный пример с примером вывода.

0 голосов
/ 18 января 2016
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);
            }

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...