web-dev-qa-db-ja.com

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行のコードで同じことを試してください。

しかし残念ながらそれらのどれもがうまくいっていないし、私はいつもnullを私のInputStream inに入れています。

336
Chaitanya MSV

クラスパス上のディレクトリで、同じクラスローダーによってロードされたクラスから、次のいずれかを使用できるはずです。

// 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マシンで使っているのと同じようにUnixのパスセパレータを使う):

Java -classpath code:txt dummy.Test

結果:

true
true
554
Jon Skeet

Spring Framework(ユーティリティの集まり または containerとして - 後者の機能を使う必要はありません)を使うときは、Resource _抽象化を簡単に使うことができます。

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

Resourceインタフェースを通じて、リソースにInputStreamURLURI、またはFileとしてアクセスできます。 _。リソースタイプを例えばに変更する。ファイルシステムリソースは、インスタンスを変更するという簡単なことです。

111
yawn

これは、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以降、文字セットを指定する便利な方法の1つは、Java.nio.charset.StandardCharsetsで定義されている定数を使用することです(これらは、 javadocs によると、「Javaプラットフォームのすべての実装で利用できることが保証されます」)。

したがって、ファイルのエンコーディングがUTF-8であることがわかっている場合は、文字セットStandardCharsets.UTF_8を明示的に指定してください。

47
Peter Perháč

してみてください

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

your classesのクラスローダだけがクラスパスからロードできるため、あなたの試みはうまくいきませんでした。 Javaシステム自体にクラスローダを使用しました。

25
tangens

実際にファイルの内容を読むためには、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);
}
18
Pavel

クラスの絶対パスを取得するには、これを試してください。

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

どういうわけか最良の答えは私のために働かない。代わりに少し異なるコードを使用する必要があります。

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

私はこれが同じ問題に遭遇する人々を助けることを願っています。

10
user1695166

あなたがグアバを使うならば:

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();
5
Alexey Simonov

ファイルの内容を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");
2
BullyWiiPlaza

「CLASSPATHシステム変数に設定されているテキストファイルを読み込もうとしています」と言うのです。これはWindows上にあり、あなたは "システム変数"を編集するためにこの見苦しいダイアログを使用していると思います。

これで、コンソールでJavaプログラムを実行しました。そしてそれはうまくいきません:コンソールはシステム変数の値のコピーを取得します once それが started の場合。これは、ダイアログに変更があっても その後 には効果がないことを意味します。

これらの解決策があります:

  1. すべての変更後に新しいコンソールを起動する

  2. コンソールでset CLASSPATH=...を使用してコンソールに変数のコピーを設定し、コードが機能したら最後の値を変数ダイアログに貼り付けます。

  3. Javaへの呼び出しを.BATファイルに入れてダブルクリックします。これは毎回新しいコンソールを作成します(つまりシステム変数の現在の値をコピーします)。

注意:User変数CLASSPATHもある場合、それはあなたのシステム変数を隠します。グローバルシステムやユーザー変数に頼るよりも、(.BATを使用して)Javaプログラムへの呼び出しをset CLASSPATH=ファイルに入れ、そこにクラスパスを設定するほうが通常は良い方法です。

また、クラスパスが異なるため、コンピュータ上で複数のJavaプログラムを動作させることができます。

1
Aaron Digulla

私の答えは、質問で尋ねられたとおりのものではありません。むしろ、プロジェクトクラスパスからJavaアプリケーションにファイルを簡単に読み込むことができるソリューションを正確に提供しています。

たとえば、設定ファイル名example.xmlが以下のようなパスにあるとします:-

com.myproject.config.dev

Java実行可能クラスファイルは以下のパスにあります。

com.myproject.server.main

devmain directory/folder(com.myproject.server.mainの両方にアクセスできる場所から最も近い共通ディレクトリ/フォルダである上記のパスの両方をチェックインするだけです-アプリケーションのJava実行可能クラスが存在する場所)– myproject folder/directoryであることがわかります。これは、サンプルにアクセスできる最も近い共通のディレクトリ/フォルダです。 xmlファイル。したがって、Java実行可能クラスからフォルダ/ディレクトリに存在しますmainアクセスするために../../のような2つのステップに戻る必要があります- 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();
   }
}