Как читать текстовый файл из classpath в Java

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

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

Поместите каталог файла (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.

Ответ 1

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

// From ClassLoader, all paths are "absolute" already - there 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

Ответ 2

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

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

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

Ответ 3

Вот как я читал все строки текстового файла в моем пути к классам, используя 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, тогда явно укажите charset StandardCharsets.UTF_8

Ответ 4

Попробуйте

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

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

Ответ 5

Чтобы действительно прочитать содержимое файла, мне нравится использовать 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);
}

Ответ 6

Чтобы получить абсолютный путь класса, попробуйте следующее:

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

Ответ 7

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

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

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

Ответ 8

Если вы используете 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();

Ответ 9

Чтобы прочитать содержимое файла в String из 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");

Ответ 10

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

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

Существуют следующие решения:

  • Запустите новую консоль после каждого изменения

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

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

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

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

Ответ 11

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

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

Подробнее см. учебник.

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

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

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

Ответ 12

Мой ответ не совсем то, что задают в вопросе. Скорее я даю решение, как легко мы можем прочитать файл в наше Java-приложение из пути к классам нашего проекта.

Например, предположим, что имя файла конфигурации example.xml находится по следующему пути: -

com.myproject.config.dev

и наш исполняемый файл класса Java находится по следующему пути: -

com.myproject.server.main

Теперь просто проверьте оба указанных выше пути, которые являются ближайшим общим каталогом/папкой, откуда вы можете получить доступ как к dev, так и главной папке/папке (com.myproject.server.main - где существует исполняемый класс java для наших приложений) - мы видим, что это папка/каталог myproject, которая является ближайшей общей папкой/папкой, из которой мы можем получить доступ к нашему файлу example.xml. Поэтому из исполняемого класса java, находящегося в папке/каталоге main, мы должны вернуться на два шага, например ../../, чтобы получить доступ к myproject. Теперь, следуя этому, посмотрим, как мы можем прочитать файл: -

package com.myproject.server.main;

class Example {

  File xmlFile;

  public Example(){
       String filePath = this.getClass().getResource("../../config/dev/example.xml").getPath();
       this.xmlFile = new File(filePath);
    }

  public File getXMLFile() {
      return this.xmlFile;
  }
   public static void main(String args[]){
      Example ex = new Example();
      File xmlFile = ex.getXMLFile();
   }
}

Ответ 13

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

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

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

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

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

Благодаря пользователю "user1695166".

Ответ 14

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

Ответ 15

Сценарий:

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-3 дней, тратя время на разработку, я нашел полное сквозное решение, надеюсь, что это поможет сэкономить ваше время

1. pom.xml of read-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 of 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 создать экземпляр ClassPathResourceReadTest.java class, где он загрузит 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

Ответ 16

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

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

Ответ 17

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();
                    }
                }
            }
        }

    }

}

Ответ 18

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