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

问题描述 投票:333回答:16

我正在尝试读取在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");

在CLASSPATH中放置文件(D:\myDir\SomeTextFile.txt)的完整路径并尝试上面3行代码。

但不幸的是,他们没有工作,我总是把null放入我的InputStream in

java classpath
16个回答
551
投票

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

// 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系统变量中设置的文本文件。”我猜这是在Windows上你正在使用这个丑陋的对话框来编辑“系统变量”。

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

有这些解决方案:

  1. 每次更改后都启动一个新控制台
  2. 在控制台中使用set CLASSPATH=...在控制台中设置变量的副本,当代码工作时,将最后一个值粘贴到变量对话框中。
  3. 将对Java的调用放入.BAT文件并双击它。这将每次创建一个新控制台(从而复制系统变量的当前值)。

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

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


-1
投票

我使用的是websphere应用服务器,我的Web模块是基于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
投票

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


-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.jarsrc/main/resources/sample.txt

这是我准备的工作示例代码,在浪费了我的开发时间2-3天后,我找到了完整的端到端解决方案,希望这有助于节省您的时间

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>

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

3.pom.xmlclient-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类,它将加载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可执行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

-2
投票

不要使用getClassLoader()方法并在文件名前使用“/”。 “/“ 非常重要

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

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

    }

}

-5
投票

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


111
投票

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

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

通过Resource接口,您可以将资源作为InputStream,URL,URI或File访问。将资源类型更改为例如文件系统资源是更改实例的简单问题。


47
投票

这就是我使用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


25
投票

请试试

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

您的尝试不起作用,因为只有类的类加载器能够从类路径加载。您使用了类加载器来为java系统本身。


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

15
投票

要获得类绝对路径,请尝试以下操作:

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

10
投票

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

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

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


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

2
投票

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

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");
© www.soinside.com 2019 - 2024. All rights reserved.