2009-09-23 3 views
287

Я пытаюсь прочитать текстовый файл, который установлен в системной переменной CLASSPATH. Не пользовательская переменная.Как читать текстовый файл из classpath в Java

Я пытаюсь получить входной поток в файл, как показано ниже:

Поместите каталог файла (D:\myDir) в CLASSPATH и попробуйте ниже:

InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt"); 
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt"); 
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt"); 

Место полный путь к файлу (D:\myDir\SomeTextFile.txt) в CLASSPATH и попробуйте те же 3 строки кода.

Но, к сожалению, NONE из них работают, и я всегда получаю null в свой InputStream in.

ответ

486

С директории на пути к классам, из класса, загруженного же загрузчиком классов, вы должны быть в состоянии использовать любой из:

// From ClassLoader, all paths are "absolute" already - there's no context 
// from which they could be relative. Therefore you don't need a leading slash. 
InputStream in = this.getClass().getClassLoader() 
           .getResourceAsStream("SomeTextFile.txt"); 
// From Class, the path is relative to the package of the class unless 
// you include a leading slash, so if you don't want to use the current 
// package, include a slash like this: 
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt"); 

Если те не работают, что говорит что-то еще не так.

Так, например, принять этот код:

package dummy; 

import java.io.*; 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     InputStream stream = Test.class.getResourceAsStream("/SomeTextFile.txt"); 
     System.out.println(stream != null); 
     stream = Test.class.getClassLoader().getResourceAsStream("SomeTextFile.txt"); 
     System.out.println(stream != null); 
    } 
} 

и эта структура каталогов:

code 
    dummy 
      Test.class 
txt 
    SomeTextFile.txt 

А затем (используя разделитель пути Unix, как я на коробке Linux):

java -classpath code:txt dummy.Test 

Результаты:

true 
true 
+1

Вы смешивали относительные и абсолютные пути вверх. Путь, начинающийся с «/», является абсолютным (т.е. начинается с того, что указано в CLASSPATH). Все остальные пути относятся к пакету класса, на который вы вызываете 'getResourceAsStream()' –

+0

Я исправил ваши примеры и добавил еще один, чтобы показать, как работает относительный путь. –

+11

Нет, вы * сломали * мой пример. отредактируйте комментарии, чтобы сделать их более четкими, но дело в том, что использование ClassLoader всего пути s считаются абсолютными уже. Для них нет ничего относительного. –

19

Пожалуйста, попробуйте

InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt"); 

Ваши попытки не получились, потому что только загрузчик классов для ваших классов могут загружать из классов. Вы использовали загрузчик классов для самой java-системы.

+0

Не уверен, что о "/", хотя. В этом случае относительный путь может работать лучше. – VonC

+3

Если вы используете его без «/», вы ищете свой файл внутри пакета «this». – tangens

+1

Файл InputStream = this.getClass(). GetResourceAsStream ("SomeTextFile.txt"); InputStream file = this.getClass(). GetResourceAsStream ("/ SomeTextFile.txt"); \t Файл InputStream = this.getClass(). GetResourceAsStream ("// SomeTextFile..txt "); \t Ни один из выше работал :( –

-4

вы должны поместить свою «системную переменную» в путь класса java.

+0

я ставлю саму переменную системы –

+0

„система переменной“* * является разработка приложений Ответ Безразлично – EJP

+0

Полностью верно ... даже не помню, как писал этот ответ :) – Salandur

96

При использовании Spring Framework (либо как набор утилит или контейнер - вам не нужно использовать последнюю функциональность), вы можете легко использовать ресурсов абстракции.

Resource resource = new ClassPathResource("com/example/Foo.class"); 

Через интерфейс ресурсов вы можете получить доступ к ресурсу, как InputStream, URL, URI или Файл. Изменение типа ресурса, например. ресурс файловой системы - это простой вопрос об изменении экземпляра.

+4

Не могли бы вы предоставить пример кода о том, как это можно использовать в файловых вводах/выводах? Я не могу найти способ _decent_, _explicit_ и _straightforward_ как использовать его в Интернете: (((( – 2014-02-11 16:00:48

+0

Работает как шарм. Предоставленный один лайнер - это все, что вам нужно. Используйте синтаксический анализ потока из других примеров, если вы Не знаю, как получить строку из потока. –

+0

У меня было немного проблем с выяснением, что делать с переменной ресурса. Я отредактировал ответ немного подробнее – DavidZemon

1

Вы говорите: «Я пытаюсь прочитать текстовый файл, который установлен в системной переменной CLASSPATH». Я предполагаю, что это в Windows, и вы используете этот уродливый диалог для редактирования «Системных переменных».

Теперь вы запускаете свою программу Java в консоли. И это не работает: консоль получает копию значений системных переменных один раз, когда запущен. Это означает, что любое изменение в диалоге впоследствии не имеет никакого эффекта.

Есть такие решения:

  1. Начать новую консоль после каждого изменения

  2. Использование set CLASSPATH=... в консоли, чтобы установить копию переменной в консоли и когда ваш код работает, паста последнее значение в диалоговом окне переменных.

  3. Положите вызов Java в файл .BAT и дважды щелкните его. Это создаст новую консоль каждый раз (таким образом, копируя текущее значение системной переменной).

BEWARE: Если у вас также есть переменная User CLASSPATH тогда он будет теневым вашим системным переменным. Поэтому обычно лучше поместить вызов вашей программы Java в файл .BAT и установить там путь к классу (используя set CLASSPATH=), а не полагаться на глобальную системную или пользовательскую переменную.

Это также гарантирует, что у вас может быть более одной программы Java, работающей на вашем компьютере, потому что они должны иметь разные пути к классам.

12

Чтобы получить класс абсолютный путь попробовать это:

String url = this.getClass().getResource("").getPath(); 
+0

И что тогда? Эта информация не используется сама по себе. – EJP

+0

Эта информация была идеальной. Мне не хватало getPath()! – Patrick

+0

@Patrick Этот ответ не дает «абсолютный путь класса». Он предоставляет URL-адрес. Совсем не то же самое. – EJP

13

Чтобы реально прочитать содержимое файла, я люблю использовать Commons IO + Spring Core. Если Java 8:

try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) { 
    IOUtils.toString(stream); 
} 

В качестве альтернативы:

InputStream stream = null; 
try { 
    stream = new ClassPathResource("/log4j.xml").getInputStream(); 
    IOUtils.toString(stream); 
} finally { 
    IOUtils.closeQuietly(stream); 
} 
+0

Как насчет закрытия входного потока? – Stephan

36

Это, как я прочитал все строки текстового файла на моем пути к классам, с помощью Java 7 NIO:

... 
import java.nio.charset.Charset; 
import java.nio.file.Files; 
import java.nio.file.Paths; 

... 

Files.readAllLines(
    Paths.get(this.getClass().getResource("res.txt").toURI()), Charset.defaultCharset()); 

NB это пример того, как это можно сделать. Вам придётся внести необходимые улучшения. Этот пример будет работать только в том случае, если файл действительно присутствует в вашем пути к классам, иначе будет выведено исключение NullPointerException, когда getResource() возвращает null, и на него вызывается .toURI().

Кроме того, так как Java 7, один удобный способ задания наборов символов является использование константы, определенные в java.nio.charset.StandardCharsets (они, в соответствии с их javadocs, «гарантированно будет доступна на каждой реализации платформы Java.») ,

Таким образом, если вы знаете, кодирование файла будет UTF-8, а затем явно указать кодовую StandardCharsets.UTF_8

+0

Благодарим вас за решение NIO - так мало людей используют этот отличный API, это позор. – mvreijn

+4

Чтобы прочитать в одной попытке String. new String (Files.readAllBytes (Paths.get (MyClass.class.getResource (resource) .toURI()))); –

+1

Лучшее решение для меня, так как оно не требует каких-либо зависимостей, таких как Spring или Commons IO. – Bernie

10

Как-то лучший ответ не работает для меня. Вместо этого мне нужно использовать несколько иной код.

ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
InputStream is = loader.getResourceAsStream("SomeTextFile.txt"); 

Я надеюсь, что это поможет тем, кто сталкивается с одной и той же проблемой.

+0

спасибо, это помогло мне в Junit –

+0

Это помогло мне и на Android, где класс был загружен загрузчиком приложений, но необходимый ему ключ был ленив загружен в поток пользовательского интерфейса. – asokan

-2

Не используйте метод getClassLoader() и используйте «/» перед именем файла. «/» Очень важно

this.getClass().getResourceAsStream("/SomeTextFile.txt"); 
+0

Использование ведущего '/' имеет тот же эффект, что и метод getClassLoader(). – EJP

-4
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 

public class ReadFile 

{ 
    /** 
    * * feel free to make any modification I have have been here so I feel you 
    * * * @param args * @throws InterruptedException 
    */ 

    public static void main(String[] args) throws InterruptedException { 
     // thread pool of 10 
     File dir = new File("."); 
     // read file from same directory as source // 
     if (dir.isDirectory()) { 
      File[] files = dir.listFiles(); 
      for (File file : files) { 
       // if you wanna read file name with txt files 
       if (file.getName().contains("txt")) { 
        System.out.println(file.getName()); 
       } 

       // if you want to open text file and read each line then 
       if (file.getName().contains("txt")) { 
        try { 
         // FileReader reads text files in the default encoding. 
         FileReader fileReader = new FileReader(
           file.getAbsolutePath()); 
         // Always wrap FileReader in BufferedReader. 
         BufferedReader bufferedReader = new BufferedReader(
           fileReader); 
         String line; 
         // get file details and get info you need. 
         while ((line = bufferedReader.readLine()) != null) { 
          System.out.println(line); 
          // here you can say... 
          // System.out.println(line.substring(0, 10)); this 
          // prints from 0 to 10 indext 
         } 
        } catch (FileNotFoundException ex) { 
         System.out.println("Unable to open file '" 
           + file.getName() + "'"); 
        } catch (IOException ex) { 
         System.out.println("Error reading file '" 
           + file.getName() + "'"); 
         // Or we could just do this: 
         ex.printStackTrace(); 
        } 
       } 
      } 
     } 

    } 

} 
+0

Не отвечает на вопрос в любом случае. – EJP

-1

Я использую сервер приложений webshpere и мой веб-модуль построен на Spring MVC. Test.properties были расположены в папке ресурсов, я пытался загрузить эти файлы, используя следующие:

  1. this.getClass().getClassLoader().getResourceAsStream("Test.properties");
  2. this.getClass().getResourceAsStream("/Test.properties");

Ни один из кода выше не загружен файл.

Но с помощью ниже кода файл свойств был загружен успешно:

Thread.currentThread().getContextClassLoader().getResourceAsStream("Test.properties");

Благодаря пользовательским "user1695166".

+1

Добро пожаловать в переполнение стека! Пожалуйста, не добавляйте «спасибо» в качестве ответов, даже если вы также частично предоставляете свое решение, если ваши решения совпадают с другими сообщениями, которые не нужно добавлять. После того, как вы вложили некоторое время на сайт, вы получите достаточные [привилегии] (// stackoverflow.com/privileges), чтобы вы могли найти ответы, которые вам нравятся, а именно способ переполнения стека сказать спасибо. – SuperBiasedMan

2

Чтобы прочитать содержимое файла в виде строки из classpath, вы можете использовать это:

private String resourceToString(String filePath) throws IOException, URISyntaxException 
{ 
    try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath)) 
    { 
     return IOUtils.toString(inputStream); 
    } 
} 

Примечание:
IOUtils является частью Commons IO.

Зов это следующим образом:

String fileContents = resourceToString("ImOnTheClasspath.txt"); 
2

Если вы используете Guava:

import com.google.common.io.Resources; 

мы можем получить URL из CLASSPATH:

URL resource = Resources.getResource("test.txt"); 
String file = resource.getFile(); // get file path 

или InputStream:

InputStream is = Resources.getResource("test.txt").openStream(); 
+0

Путь к файлу не используется, если ресурс находится в файле JAR или WAR. – EJP

0

Всякий раз, когда вы добавляете каталог в путь к классам, все ресурсы, определенные в нем, будут скопированы непосредственно в папку развертывания приложения (например, б/у).

Для доступа к ресурсу из вашего приложения вы можете использовать префикс '/', который указывает на корневой путь в папке развертывания, остальные части пути зависят от местоположения вашего ресурса (независимо от того, "D: \ myDir" или вложенные подпапки)

Проверьте это tutorial для получения дополнительной информации.

В вашем примере, вы должны быть в состоянии получить доступ к ресурсу через следующее:

InputStream is = getClass().getResourceAsStream("/SomeTextFile.txt"); 

Зная, что "SomeTextFile.txt" существует непосредственно под "D: \ Mydir"

0

Использование org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));

0

Сценарий:

1) client-service-1.0-SNAPSHOT.jar имеет зависимость read-classpath-resource-1.0-SNAPSHOT.jar

2) мы хотим, чтобы прочитать содержание пути класса ресурсов (sample.txt) из read-classpath-resource-1.0-SNAPSHOT.jar через client-service-1.0-SNAPSHOT.jar.

3) read-classpath-resource-1.0-SNAPSHOT.jar имеет src/main/resources/sample.txt

Здесь работает пример кода, я приготовила, после 2-3days тратить мое время разработки, я нашел полное решение от конца до конца, надеюсь, что это помогает сэкономить ваше время

1. pom.xmlread-classpath-resource-1.0-SNAPSHOT.jar из

<?xml version="1.0" encoding="UTF-8"?> 
     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
      <modelVersion>4.0.0</modelVersion> 
      <groupId>jar-classpath-resource</groupId> 
      <artifactId>read-classpath-resource</artifactId> 
      <version>1.0-SNAPSHOT</version> 
      <name>classpath-test</name> 
      <properties> 
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
       <org.springframework.version>4.3.3.RELEASE</org.springframework.version> 
       <mvn.release.plugin>2.5.1</mvn.release.plugin> 
       <output.path>${project.artifactId}</output.path> 
       <io.dropwizard.version>1.0.3</io.dropwizard.version> 
       <commons-io.verion>2.4</commons-io.verion> 
      </properties> 
      <dependencies> 
       <dependency> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-core</artifactId> 
        <version>${org.springframework.version}</version> 
       </dependency> 
       <dependency> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
        <version>${org.springframework.version}</version> 
       </dependency> 
       <dependency> 
        <groupId>commons-io</groupId> 
        <artifactId>commons-io</artifactId> 
        <version>${commons-io.verion}</version> 
       </dependency> 
      </dependencies> 
      <build> 
       <resources> 
        <resource> 
         <directory>src/main/resources</directory> 
        </resource> 
       </resources> 
       <plugins> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-release-plugin</artifactId> 
         <version>${mvn.release.plugin}</version> 
        </plugin> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-compiler-plugin</artifactId> 
         <version>3.1</version> 
         <configuration> 
          <source>1.8</source> 
          <target>1.8</target> 
          <encoding>UTF-8</encoding> 
         </configuration> 
        </plugin> 
        <plugin> 
         <artifactId>maven-jar-plugin</artifactId> 
         <version>2.5</version> 
         <configuration> 
          <outputDirectory>${project.build.directory}/lib</outputDirectory> 
          <archive> 
           <manifest> 
            <addClasspath>true</addClasspath> 
            <useUniqueVersions>false</useUniqueVersions> 
            <addDefaultImplementationEntries>true</addDefaultImplementationEntries> 
            <mainClass>demo.read.classpath.resources.ClassPathResourceReadTest</mainClass> 
           </manifest> 
           <manifestEntries> 
            <Implementation-Artifact-Id>${project.artifactId}</Implementation-Artifact-Id> 
            <Class-Path>sample.txt</Class-Path> 
           </manifestEntries> 
          </archive> 
         </configuration> 
        </plugin> 
        <plugin> 
         <groupId>org.apache.maven.plugins</groupId> 
         <artifactId>maven-shade-plugin</artifactId> 
         <version>2.2</version> 
         <configuration> 
          <createDependencyReducedPom>false</createDependencyReducedPom> 
          <filters> 
           <filter> 
            <artifact>*:*</artifact> 
            <excludes> 
             <exclude>META-INF/*.SF</exclude> 
             <exclude>META-INF/*.DSA</exclude> 
             <exclude>META-INF/*.RSA</exclude> 
            </excludes> 
           </filter> 
          </filters> 
         </configuration> 
         <executions> 
          <execution> 
           <phase>package</phase> 
           <goals> 
            <goal>shade</goal> 
           </goals> 
           <configuration> 
            <transformers> 
             <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> 
             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
              <mainClass>demo.read.classpath.resources.ClassPathResourceReadTest</mainClass> 
             </transformer> 
            </transformers> 
           </configuration> 
          </execution> 
         </executions> 
        </plugin> 
       </plugins> 
      </build> 
     </project> 

2. ClassPathResourceReadTest.java класса в read-classpath-resource-1.0-SNAPSHOT.jar, который загружает содержимое класса путь к файлу ресурсов.

package demo.read.classpath.resources; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.List; 

public final class ClassPathResourceReadTest { 
    public ClassPathResourceReadTest() throws IOException { 
     InputStream inputStream = getClass().getResourceAsStream("/sample.txt"); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
     List<Object> list = new ArrayList<>(); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      list.add(line); 
     } 
     for (Object s1: list) { 
      System.out.println("@@@ " +s1); 
     } 
     System.out.println("getClass().getResourceAsStream('/sample.txt') lines: "+list.size()); 
    } 
} 

3. pom.xml из client-service-1.0-SNAPSHOT.jar

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>client-service</groupId> 
    <artifactId>client-service</artifactId> 
    <version>1.0-SNAPSHOT</version> 

    <dependencies> 
     <dependency> 
      <groupId>jar-classpath-resource</groupId> 
      <artifactId>read-classpath-resource</artifactId> 
      <version>1.0-SNAPSHOT</version> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <artifactId>maven-jar-plugin</artifactId> 
       <version>2.5</version> 
       <configuration> 
        <outputDirectory>${project.build.directory}/lib</outputDirectory> 
        <archive> 
         <manifest> 
          <addClasspath>true</addClasspath> 
          <useUniqueVersions>false</useUniqueVersions> 
          <addDefaultImplementationEntries>true</addDefaultImplementationEntries> 
          <mainClass>com.crazy.issue.client.AccessClassPathResource</mainClass> 
         </manifest> 
         <manifestEntries> 
          <Implementation-Artifact-Id>${project.artifactId}</Implementation-Artifact-Id> 
          <Implementation-Source-SHA>${buildNumber}</Implementation-Source-SHA> 
          <Class-Path>sample.txt</Class-Path> 
         </manifestEntries> 
        </archive> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-shade-plugin</artifactId> 
       <version>2.2</version> 
       <configuration> 
        <createDependencyReducedPom>false</createDependencyReducedPom> 
        <filters> 
         <filter> 
          <artifact>*:*</artifact> 
          <excludes> 
           <exclude>META-INF/*.SF</exclude> 
           <exclude>META-INF/*.DSA</exclude> 
           <exclude>META-INF/*.RSA</exclude> 
          </excludes> 
         </filter> 
        </filters> 
       </configuration> 
       <executions> 
        <execution> 
         <phase>package</phase> 
         <goals> 
          <goal>shade</goal> 
         </goals> 
         <configuration> 
          <transformers> 
           <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> 
           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
            <mainClass>com.crazy.issue.client.AccessClassPathResource</mainClass> 
           </transformer> 
          </transformers> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

4. AccessClassPathResource.java Instantiate ClassPathResourceReadTest.java класса, где он собирается загружать sample.txt и печатает его содержимое также.

package com.crazy.issue.client; 

import demo.read.classpath.resources.ClassPathResourceReadTest; 
import java.io.IOException; 

public class AccessClassPathResource { 
    public static void main(String[] args) throws IOException { 
     ClassPathResourceReadTest test = new ClassPathResourceReadTest(); 
    } 
} 

5.Run Исполняемые банка следующим образом:

[[email protected] lib]$ java -jar client-service-1.0-SNAPSHOT.jar 
**************************************** 
I am in resources directory of read-classpath-resource-1.0-SNAPSHOT.jar 
**************************************** 
3) getClass().getResourceAsStream('/sample.txt'): 3 
Смежные вопросы