Javaでsrc/main/resources
にあるファイルを読み込むのに少し手間取ったので備忘録です。
##1. ルートからの絶対パスで取得
sample1
public void sample1() {
String path = "src/main/resources/sample1.txt";
try (BufferedReader br = Files.newBufferedReader(Paths.get(path))) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
sample1
##2. クラスパスからの相対パスで取得
sample2
public void sample2() {
String path = "/sample2.txt";
// staticメソッドの場合はFoo.class.getResourceAsStreamのように書く(Fooはクラス名)
try (InputStream is = getClass().getResourceAsStream(path);
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
sample2
##注意点
1.と2.では、テストの際、src/test/resources
に同名ファイルが有るときの動きが異なります。
test1
test2
public class FooTest {
@Test
public void testInput() throws Exception {
Foo foo = new Foo();
foo.sample1(); // src/main/resources/sample1.txtを読み込む
foo.sample2(); // src/test/resources/sample2.txtを読み込む
}
}
sample1
test2
1.の場合は、パスを直書きしているので当たり前ですが、src/main/resources
ディレクトリ下のsample1.txt
を読み込みます。
2.の場合は、src/main/resources
に優先してsrc/test/resources
ディレクトリ下のsample2.txt
を読み込んでいます。
なお、src/test/resources
ディレクトリにsample2.txt
がなければ、そのままsrc/main/resources
ディレクトリ下のsample2.txt
が読み込まれます。
##まとめ
とりあえずClass#getResourceAsStream
を使っておけば良いかと。
何か問題があれば教えていただけると助かります。
参考:
リソースの取得
【Java】クラスパス上のファイルを取得する方法の違いについて
##余談
Class#getResourceAsStream
ではなく、Class#getResource
経由で絶対パスを取得し、Paths#get
に渡したところ java.nio.file.InvalidPathException
となりました。
String filename= "/sample2.txt";
String filepath = getClass().getResource(filename).getPath();
Path path = Paths.get(filepath); // java.nio.file.InvalidPathException
どうもWindows環境ではドライブレター部分のエスケープが必要なようで、以下のように置換したところ取得できました。
String filename= "/sample2.txt";
String filepath = getClass().getResource(filename).getPath();
Path path = Paths.get(filepath .replaceFirst("^/(.:/)", "$1")); // OK
参考: create Java NIO ファイル・パスの問題
最後までお読み頂きありがとうございました。 質問や不備についてはコメント欄か[Twitter](https://twitter.com/ka2_kamaboko)までお願いします。