web-dev-qa-db-ja.com

javaに相対パスを持つリソースを開きます

Javaアプリでは、いくつかのファイルとディレクトリを取得する必要があります。

これはプログラム構造です:

./main.Java
./package1/guiclass.Java
./package1/resources/resourcesloader.Java
./package1/resources/repository/modules/   -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks    -> this is the file I need to get

guiclassは、リソース(ディレクトリとファイル)をロードするresourcesloaderクラスをロードします。

ファイルに関しては、私は試しました

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()

実際のパスを取得するために、この方法は機能しません。

ディレクトリの作り方がわかりません。

73
Giancarlo

ローダーを取得するクラスではなく、クラスローダーに相対的なパスを指定します。例えば:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
42
jonathan.cone

getClass().getResource("filename.txt")メソッドの使用に問題がありました。 Java docsの指示を読んで、リソースがリソースにアクセスしようとしているクラスと同じパッケージにない場合、'/'で始まる相対パスを指定する必要があります。推奨される戦略は、リソースファイルをルートディレクトリの「resources」フォルダの下に置くことです。たとえば、次のような構造がある場合:

src/main/com/mycompany/myapp

次に、mavenの推奨に従ってリソースフォルダーを追加できます。

src/main/resources

さらに、resourcesフォルダーにサブフォルダーを追加できます

src/main/resources/textfiles

そしてあなたのファイルはmyfile.txtと呼ばれているので

src/main/resources/textfiles/myfile.txt

ここで愚かなパスの問題が発生します。com.mycompany.myapp packageにクラスがあり、リソースフォルダーからmyfile.txtファイルにアクセスするとします。いくつかを与える必要があると言う:

"/main/resources/textfiles/myfile.txt" path

または

"/resources/textfiles/myfile.txt"

これらは両方とも間違っています。 mvn clean compileを実行した後、ファイルとフォルダーは次の場所にコピーされます。

myapp/target/classes 

フォルダ。ただし、resourcesフォルダーはありません。resourcesフォルダー内のフォルダーだけです。だからあなたが持っている:

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*

したがって、getClass().getResource("")メソッドに与える正しいパスは次のとおりです。

"/textfiles/myfile.txt"

ここにあります:

getClass().getResource("/textfiles/myfile.txt")

これはもはやnullを返しませんが、あなたのクラスを返します。これが誰かの助けになることを願っています。 "resources"フォルダーもコピーされず、"resources"フォルダー内のサブフォルダーとファイルのみが直接コピーされるのは奇妙なことです。 "resources"フォルダーも"myapp/target/classes"の下にあることは論理的に思えます

139
Johnny

@GianCarlo:Javaプロジェクトのルートを提供するシステムプロパティuser.dirを呼び出して、このパスを相対パスに追加することができます。例:

String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;



// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
9
Vikram

クラスで「getResource」を使用すると、クラスが含まれるパッケージに基づいて相対パスが解決されます。ClassLoaderで「getResource」を使用すると、ルートフォルダーに基づいて相対パスが解決されます。

絶対パスを使用する場合、両方の「getResource」メソッドはルートフォルダーで開始されます。

8
nbeyer

Eclipse + mavenを使用している場合。 images/pic.jpgsrc/main/resourcesファイルにアクセスしようとするとします。このようにする:

ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());

は完全に正しいですが、NULLポインター例外が発生する場合があります。 Eclipseは、mavenディレクトリ構造内のフォルダーをソースフォルダーとしてすぐに認識しないようです。プロジェクトのソースフォルダーリストからsrc/main/resourcesフォルダーを削除して元に戻す(プロジェクト>プロパティ> Javaビルドパス>ソース> remove/addフォルダー)と、これを解決できました。

4
Paul Mira
resourcesloader.class.getClass()

次のように分類できます。

Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();

つまり、bootstrapクラスを使用してリソースをロードしようとしています。

代わりに、おそらく次のようなものが必要です:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

非静的コンテキストでの静的メソッドの呼び出しについてjavacだけが警告した場合...

上記の2つの回答に進みます。最初の1つ

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

同じものでなければなりませんか?

1
manocha_ak

次の仕事をしますか?

resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")

パッケージを含むフルパスを指定できない理由はありますか?

1
RichH

これを使って:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
0

ファイルへの実際のパスを取得するには、これを試すことができます:

URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;    

リソースローダーはここではクラス名です。 「resources/repository/SSL-Key/cert.jks」はファイルへの相対パスです。 ./package1/Javaにguiclassがあり、残りのフォルダー構造が残っている場合、「../ resources/repository/SSL-Key/cert.jks」を相対パスとして定義するため、相対パスを定義します。

このようにして、BufferedReaderでファイルを読み取ることができます。ストリングを使用してファイルへのパスを識別しないでください。パスにスペースや英語以外のアルファベットの文字が含まれている場合、問題が発生し、ファイルが見つからないためです。

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));
0
Nikto

Nullポインタ例外を回避し、データディレクトリへのパスを設定するために、@ jonathan.coneの1つのライナーを少し変更しました(.getFile()を追加して)。私のために働いたものは次のとおりです:

String realmID = new Java.util.Scanner(new Java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
0
Alferd Nobel