首页 文章

如何在Java中从类路径中真正读取文本文件

提问于
浏览
315

我正在尝试读取在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 .

16 回答

  • -5

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

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

    我希望这能帮助那些遇到同样问题的人 .

  • 107

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

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

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

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

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

    以上代码都没有加载文件 .

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

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

    感谢用户"user1695166" .

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

    这就是我使用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,"guaranteed to be available on every implementation of the Java platform.") .

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

  • -1

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

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

  • -2

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

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

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

  • 529

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

    // 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 将文件内容读入字符串,您可以使用:

    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");
    
  • 1

    如果你使用 Guava :

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

    Scenario:

    1) client-service-1.0-SNAPSHOT.jar 有依赖 read-classpath-resource-1.0-SNAPSHOT.jar

    2)我们想要读取 read-classpath-resource-1.0-SNAPSHOT.jarclient-service-1.0-SNAPSHOT.jar 的类路径资源( sample.txt )的内容 .

    3) read-classpath-resource-1.0-SNAPSHOT.jarsrc/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>
    
    1. 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());
        }
    }
    
    1. 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>
    
    1. AccessClassPathResource.java instantiate 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可执行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

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

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

    有这些解决方案:

    • 每次更改后启动新控制台

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

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

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

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

  • 18

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

  • 4

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

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

    请试试

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

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

相关问题