Javaでファイルを読み取る方法
1. 前書き
この記事では、標準Javaクラスを使用して、クラスパス、URL、またはJARファイル内からファイルを読み取る方法を説明します。
参考文献:
2. セットアップ
コアJavaクラスのみを使用する一連のテスト例を使用し、テストでは、Hamcrestマッチャーを使用するアサーションを使用します。
テストは、結果のアサートを容易にするためにInputStream をStringに変換する共通のreadFromInputStream メソッドを共有します。
private String readFromInputStream(InputStream inputStream)
throws IOException {
StringBuilder resultStringBuilder = new StringBuilder();
try (BufferedReader br
= new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null) {
resultStringBuilder.append(line).append("\n");
}
}
return resultStringBuilder.toString();
}
同じ結果を達成する他の方法があることに注意してください。 いくつかの代替案については、this articleを参照できます。
3. クラスパスからファイルを読み取る
このセクションでは、クラスパスで使用可能なファイルの読み取り方法について説明します。 src/main/resourcesで利用可能な「fileTest.txt」を読みます。
@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Class clazz = FileOperationsTest.class;
InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
上記のコードスニペットでは、現在のクラスを使用してgetResourceAsStream methodを使用してファイルをロードし、ロードするファイルの絶対パスを渡しました。
同じメソッドがClassLoader インスタンスでも使用できます。
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);
getClass().getClassLoader()を使用して、現在のクラスのclassLoader を取得します。
主な違いは、getResourceAsStream をClassLoader インスタンスで使用する場合、パスはクラスパスのルートから始まる絶対パスとして扱われることです。
Class instance, に対して使用する場合、パスはパッケージからの相対パス、または先頭のスラッシュで示される絶対パスである可能性があります。
この例のInputStreamなどのOf course, note that in practice, open streams should always be closed:
InputStream inputStream = null;
try {
File file = new File(classLoader.getResource("fileTest.txt").getFile());
inputStream = new FileInputStream(file);
//...
}
finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. JDK7でファイルを読む
JDK7では、NIOパッケージが大幅に更新されました。 FilesクラスとreadAllBytesメソッドを使用した例を見てみましょう。 readAllBytesメソッドはPath. Pathクラスを受け入れますが、いくつかの追加操作が行われたjava.io.Fileのアップグレードと見なすことができます。
@Test
public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Path path = Paths.get(getClass().getClassLoader()
.getResource("fileTest.txt").toURI());
byte[] fileBytes = Files.readAllBytes(path);
String data = new String(fileBytes);
Assert.assertEquals(expectedData, data.trim());
}
このメソッドは、ファイルの内容をString.に読み込む便利な方法も提供します。
5. JDK8でファイルを読む
JDK8は、Filesクラス内にlines()メソッドを提供します。 文字列要素のStreamを返します。
データをバイトに読み取り、UTF-8文字セットを使用してデコードする方法の例を見てみましょう。
@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Path path = Paths.get(getClass().getClassLoader()
.getResource("fileTest.txt").toURI());
Stream lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();
Assert.assertEquals(expectedData, data.trim());
}
ファイル操作のようにIOチャネルでStreamを使用するには、close()メソッドを使用してストリームを明示的に閉じる必要があります。
ご覧のとおり、Files APIは、ファイルの内容をString.に読み込む別の簡単な方法を提供します。
6. でファイルを読む FileUtils
もう1つの一般的なオプションは、commonsパッケージのFileUtilsクラスを使用することです。 次の依存関係を追加する必要があります。
commons-io
commons-io
2.5
必ず最新の依存関係バージョンhereを確認してください。
ファイル読み取りコードは次のようになります。
@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileTest.txt").getFile());
String data = FileUtils.readFileToString(file, "UTF-8");
Assert.assertEquals(expectedData, data.trim());
}
ここでは、FileオブジェクトをFileUtilsクラスのメソッドreadFileToString()に渡します。 このユーティリティクラスは、InputStreamインスタンスを作成してデータを読み取るための定型コードを記述しなくても、コンテンツをロードすることができます。
7. IOUtilsでファイルを読み取る
もう1つの一般的なオプションは、commonsパッケージのIOUtils classを使用することです。 前のFileUtilsの例で説明したのと同じcommon-io依存関係を追加する必要があります。
使用例を見てみましょう。
@Test
public void givenFileName_whenUsingIOUtils_thenFileData() {
String expectedData = "This is a content of the file";
FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt");
String data = IOUtils.toString(fis, "UTF-8");
assertEquals(expectedData, data.trim());
}
ここでは、FileInputStreamオブジェクトをIOUtilsクラスのメソッドtoString()に渡します。 このユーティリティクラスは、InputStreamインスタンスを作成してデータを読み取るための定型コードを記述しなくても、コンテンツをロードすることができます。
8. URLからコンテンツを読む
URLからコンテンツを読み取るために、この例では「/」URLを次のように使用します。
@Test
public void givenURLName_whenUsingURL_thenFileData() {
String expectedData = "example";
URL urlObject = new URL("/");
URLConnection urlConnection = urlObject.openConnection();
InputStream inputStream = urlConnection.getInputStream();
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
URLに接続する別の方法もあります。 ここでは、標準SDKで使用可能なURLクラスとURLConnectionクラスを使用しました。
9. JARからファイルを読み取る
JARファイル内にあるファイルを読み取るには、ファイルが含まれるJARが必要です。 この例では、「hamcrest-library-1.3.jar」ファイルから「LICENSE.txt」を読み取ります。
@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
String expectedData = "BSD License";
Class clazz = Matchers.class;
InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
ここでは、HamcrestライブラリにあるLICENSE.txtをロードするため、リソースの取得に役立つMatcher’sクラスを使用します。 同じファイルをクラスローダーを使用してロードすることもできます。
10. 結論
このチュートリアルでは、クラスパス、URL、jarファイルなどのさまざまな場所からファイルを読み取る方法を説明しました。
また、ファイルからコンテンツを読み取るいくつかの方法を見ました
ソースコードは次のGitHub repoにあります。