如何在Java中从classpath中真正读取文本文件

时间:2009-09-23 06:38:19

标签: java classpath

我正在尝试读取在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行代码。

但遗憾的是,他们中没有人正在工作,我总是将null收到我的InputStream in

18 个答案:

答案 0 :(得分:556)

使用类路径上的目录,从同一个类加载器加载的类中,您应该能够使用以下任何一个:

// 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 :(得分:113)

使用Spring框架(作为实用程序容器的集合 - 您不需要使用后者功能)时,您可以轻松使用资源抽象。

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

通过资源界面,您可以以 InputStream URL URI 的形式访问资源文件的。将资源类型更改为例如文件系统资源是更改实例的简单问题。

答案 2 :(得分:49)

这是我使用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());

注意这是一个如何完成它的例子。你必须根据需要进行改进。此示例仅在文件实际存在于类路径中时才有效,否则当getResource()返回null并且在其上调用.toURI()时,将抛出NullPointerException。

此外,从Java 7开始,指定字符集的一种便捷方法是使用java.nio.charset.StandardCharsets中定义的常量 (根据他们的javadocs,这些是“保证在Java平台的每个实现都可用。”。)。

因此,如果您知道文件的编码为UTF-8,则明确指定charset StandardCharsets.UTF_8

答案 3 :(得分:25)

请尝试

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

您的尝试无效,因为只有您的类的类加载器能够从类路径加载。您已经将类加载器用于java系统本身。

答案 4 :(得分:18)

要实际读取文件的内容,我喜欢使用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);
}

答案 5 :(得分:15)

要获得类绝对路径,请尝试以下方法:

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

答案 6 :(得分:10)

不知何故,最好的答案对我不起作用。我需要使用略有不同的代码。

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

我希望这可以帮助那些遇到同样问题的人。

答案 7 :(得分:5)

如果你使用番石榴:

import com.google.common.io.Resources;

我们可以从CLASSPATH获取URL:

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

或InputStream:

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

答案 8 :(得分:2)

要从classpath将文件内容读入字符串,您可以使用:

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

注意:
IOUtilsCommons IO的一部分。

这样称呼:

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

答案 9 :(得分:1)

如果在jar文件中编译项目: 您可以将文件放在resources / files / your_file.text或pdf中;

并使用以下代码:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;

public class readFileService(){
    private static final Logger LOGGER = LoggerFactory.getLogger(readFileService.class);


    public byte[] getFile(){
        String filePath="/files/your_file";
        InputStream inputStreamFile;
        byte[] bytes;
        try{
            inputStreamFile = this.getClass().getResourceAsStream(filePath);
            bytes = new byte[inputStreamFile.available()];
            inputStreamFile.read(bytes);    
        } catch(NullPointerException | IOException e) {
            LOGGER.error("Erreur read file "+filePath+" error message :" +e.getMessage());
            return null;
        }
        return bytes;
    } 
}

答案 10 :(得分:1)

您说“我正在尝试读取在CLASSPATH系统变量中设置的文本文件。”我猜这是在Windows上你正在使用这个丑陋的对话框来编辑“系统变量”。

现在您在控制台中运行Java程序。这不起作用:当启动时,控制台会获取系统变量的值的副本。这意味着对话框之后的任何更改都没有任何效果。

有以下解决方案:

  1. 每次更改后启动新控制台

  2. 在控制台中使用set CLASSPATH=...在控制台中设置变量的副本,当代码工作时,将最后一个值粘贴到变量对话框中。

  3. 将对Java的调用放入.BAT文件并双击它。这将每次创建一个新控制台(从而复制系统变量的当前值)。

  4. 当心:如果您还有一个用户变量CLASSPATH,那么它将影响您的系统变量。这就是为什么通常最好将对Java程序的调用放入.BAT文件并在那里设置类路径(使用set CLASSPATH=)而不是依赖于全局系统或用户变量。

    这也确保您可以在计算机上运行多个Java程序,因为它们必然具有不同的类路径。

答案 11 :(得分:0)

我的答案并不完全是问题中要问的内容。确切地说,我正在提供一种解决方案,确切地讲,我们可以很容易地从项目类路径将文件读取到Java应用程序中。

例如,假设配置文件名称 example.xml 位于以下路径中:-

com.myproject.config.dev

,我们的Java可执行类文件在以下路径中:-

com.myproject.server.main

现在只需检查以上路径,这是最近的公用目录/文件夹,从中可以访问 dev main 目录/文件夹(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();
   }
}

答案 12 :(得分:-1)

我正在使用webshpere应用程序服务器,而我的Web模块是基于Spring MVC构建的。 Test.properties位于资源文件夹中,我尝试使用以下内容加载此文件:

  1. this.getClass().getClassLoader().getResourceAsStream("Test.properties");
  2. this.getClass().getResourceAsStream("/Test.properties");
  3. 以上代码均未加载文件。

    但是在以下代码的帮助下,属性文件已成功加载:

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

    感谢用户“user1695166”

答案 13 :(得分:-1)

使用org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));

答案 14 :(得分:-1)

情景:

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天后,我找到了完整的端到端解决方案,希望这有助于节省您的时间

  

pom.xml 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>

ClassPathResourceReadTest.java

2. 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()); } } 类加载类路径资源文件内容。

pom.xml

3. client-service-1.0-SNAPSHOT.jar的{​​{1}}

<?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类,其中,它将加载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.运行可执行jar如下:

[ravibeli@localhost 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

答案 15 :(得分:-2)

不要使用getClassLoader()方法并使用&#34; /&#34;在文件名之前。 &#34; /&#34;非常重要

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

答案 16 :(得分:-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();
                    }
                }
            }
        }

    }

}

答案 17 :(得分:-5)

你必须把你的'系统变量'放在java类路径上。