Programing

Java의 클래스 경로에서 텍스트 파일을 실제로 읽는 방법

lottogame 2020. 3. 2. 13:00
반응형

Java의 클래스 경로에서 텍스트 파일을 실제로 읽는 방법


CLASSPATH 시스템 변수에 설정된 텍스트 파일을 읽으려고합니다. 사용자 변수가 아닙니다.

아래와 같이 파일에 입력 스트림을 가져 오려고합니다.

D:\myDirCLASSPATH 에 파일 ( ) 의 디렉토리를 배치 하고 아래에서 시도하십시오.

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.txtCLASSPATH 에 파일 ( ) 의 전체 경로를 배치 하고 위의 3 줄의 코드를 동일하게 시도하십시오.

그러나 불행히도 그들 중 아무도 작동하지 않으며 항상 nullInputStream에 들어가고 in있습니다.


동일한 클래스 로더가로드 한 클래스에서 클래스 경로의 디렉토리를 사용하여 다음 중 하나를 사용할 수 있어야합니다.

// 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

그런 다음 (Linux 상자에서 유닉스 경로 구분 기호를 사용하여) :

java -classpath code:txt dummy.Test

결과 :

true
true

스프링 프레임 워크를 사용할 때 (유틸리티 또는 컨테이너 의 모음으로 -후자의 기능을 사용할 필요가 없음) 자원 추상화를 쉽게 사용할 수 있습니다 .

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

Resource 인터페이스를 통해 InputStream , URL , URI 또는 File 로 리소스에 액세스 할 수 있습니다 . 예를 들어 파일 시스템 리소스로 리소스 유형을 변경하는 것은 인스턴스를 변경하는 간단한 문제입니다.


다음은 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 이것은 어떻게 할 수 있는지의 예입니다. 필요에 따라 개선해야합니다. 이 예제는 파일이 실제로 클래스 경로에있는 경우에만 작동합니다. 그렇지 않으면 getResource ()가 null을 반환하고 .toURI ()가 호출 될 때 NullPointerException이 발생합니다.

또한 Java 7부터 문자 세트를 지정하는 편리한 방법 중 하나는에 정의 된 상수를 사용하는 것입니다 java.nio.charset.StandardCharsets(이는 javadocs 에 따라 "Java 플랫폼의 모든 구현에서 사용 가능함").

따라서 파일의 인코딩이 UTF-8임을 알고 있으면 명시 적으로 문자 세트를 지정하십시오. StandardCharsets.UTF_8


시도하십시오

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

만 클래스 로더 때문에 귀하의 시도가 작동하지 않았다 당신의 클래스는 클래스 경로에서로드 할 수 있습니다. Java 시스템 자체에 클래스 로더를 사용했습니다.


실제로 파일의 내용을 읽으려면 Commons IO + Spring Core를 사용하는 것이 좋습니다. 자바 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);
}

클래스 절대 경로를 얻으려면 다음을 시도하십시오.

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

어쨌든 가장 좋은 대답은 효과가 없습니다. 대신 약간 다른 코드를 사용해야합니다.

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

나는 이것이 같은 문제가 발생하는 사람들에게 도움이되기를 바랍니다.


구아바를 사용하는 경우 :

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

에서 파일의 내용을 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");

"CLASSPATH 시스템 변수에 설정된 텍스트 파일을 읽으려고합니다." 내 생각에 이것은 Windows에 있으며이 추악한 대화 상자를 사용하여 "시스템 변수"를 편집하고 있습니다.

이제 콘솔에서 Java 프로그램을 실행하십시오. 그리고 그것은 작동하지 않습니다 : 콘솔은 시스템 변수 시작될한 번 시스템 변수 값의 사본을 얻습니다 . 이것은 나중에 대화 상자를 변경해 도 아무런 영향 이 없음을 의미합니다 .

다음과 같은 해결책이 있습니다.

  1. 모든 변경 후 새로운 콘솔을 시작

  2. 사용 set CLASSPATH=...콘솔에서, 당신의 코드가 작동 콘솔에서 때 변수의 사본을 설정 한 변수 대화 상자에 마지막 값을 붙여 넣습니다.

  3. Java 호출을 .BAT파일에 넣고 두 번 클릭하십시오. 이것은 매번 새로운 콘솔을 생성합니다 (따라서 시스템 변수의 현재 값을 복사합니다).

주의 : 사용자 변수 CLASSPATH도 있으면 시스템 변수가 어두워집니다. 그렇기 때문에 일반적으로 전역 프로그램이나 사용자 변수에 의존하기보다는 Java 프로그램에 대한 호출을 .BAT파일에 넣고 클래스 경로를 설정하는 set CLASSPATH=것이 좋습니다.

또한 컴퓨터에서 다른 클래스 경로를 갖도록 바인딩 된 둘 이상의 Java 프로그램을 컴퓨터에서 사용할 수 있습니다.


내 대답은 질문에서 정확히 묻는 것이 아닙니다. 오히려 프로젝트 클래스 경로에서 Java 응용 프로그램으로 파일을 얼마나 쉽게 읽을 수 있는지 정확하게 솔루션을 제공하고 있습니다.

예를 들어 설정 파일 이름 example.xml 이 아래와 같은 경로에 있다고 가정 합니다.

com.myproject.config.dev

우리의 자바 실행 가능 클래스 파일은 아래 경로에 있습니다 :-

com.myproject.server.main

이제 devmain 디렉토리 / 폴더 모두에 액세스 할 수있는 가장 가까운 공통 디렉토리 / 폴더 인 위의 경로를 모두 확인하십시오 (com.myproject.server.main-애플리케이션의 Java 실행 가능 클래스가 존재 함) – 우리는 볼 수 있습니다 그것은이다 MyProject를 우리가 우리의 example.xml 파일에 액세스 할 수있는 곳에서 가장 가까운 공통 디렉토리 / 폴더입니다 폴더 / 디렉토리. 따라서 자바 실행 파일 클래스는 folder / directory 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();
   }
}

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" 사용자에게 감사합니다 .


사용하다 org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));


대본:

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.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인스턴스화 합니다.ClassPathResourceReadTest.javasample.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();
    }
}

다음과 같이 실행 가능한 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

getClassLoader () 메소드를 사용하지 말고 파일 이름 앞에 "/"를 사용하십시오. "/"는 매우 중요합니다

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

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

    }

}

자바 클래스 경로에 '시스템 변수'를 넣어야합니다.

참고 URL : https://stackoverflow.com/questions/1464291/how-to-really-read-text-file-from-classpath-in-java



반응형