2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Java】環境に依らずjar内のファイルを取得する

Last updated at Posted at 2019-06-11

はじめに

例えばテキストのテンプレートを取得したい時。
開発環境と本番が違う場合(というかほぼ違うと思いますが)、絶対パスって環境依存ですよね。
環境ごとの配置場所をプロパティに書き出してもいいですが設定値は少ないほうがいいし、できればjarに含めたい。
ということで、今回はjar内のリソースを取得するユーティリティです。

実装

環境

  • Windows10
  • Java7
  • Maven

FileUtilクラス

FileUtil.java
package jp.demo.util;

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 class FileUtil {
	private static final String CHARSET_UTF8 = "UTF-8";
	private static final String LF = "\n";

	/**
	 * 1行ずつListに詰めて返す。(改行文字除く)
	 * @param string
	 * @return
	 * @throws IOException
	 */
	public static List<String> getTextLines(String string) throws IOException {
		List<String> list = new ArrayList<>();
		try (InputStream is = ClassLoader.getSystemResourceAsStream(string);
				BufferedReader br = new BufferedReader(new InputStreamReader(is, CHARSET_UTF8))) {
			String line;
			while ((line = br.readLine()) != null) {
				list.add(line);
			}
		}
		return list;
	}

	/**
	 * Stringにして返す。(改行コードはLF)
	 * @param string
	 * @return
	 * @throws IOException
	 */
	public static String getTextStr(String string) throws IOException {
		StringBuilder sb = new StringBuilder();
		try (InputStream is = ClassLoader.getSystemResourceAsStream(string);
				BufferedReader br = new BufferedReader(new InputStreamReader(is, CHARSET_UTF8))) {
			String line;
			while ((line = br.readLine()) != null) {
				sb.append(line + LF);
			}
		}
		return sb.toString();
	}
}

Mainクラス

Main.java
package jp.demo;

import java.io.IOException;
import java.util.List;

import jp.demo.util.FileUtil;

public class Main {
	public static void main(String[] args) {
		System.out.println("### START ###");
		List<String> list = null;
		String str = null;
		try {
			list = FileUtil.getTextLines("jp/demo/text1.txt");
			str = FileUtil.getTextStr("jp/demo/text1.txt");
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("getTextLines:");
		list.forEach(System.out::println);
		System.out.println("\ngetTextStr:");
		System.out.println(str);

		System.out.println("### END ###");
	}
}

テキストファイル

文字コード:UTF-8、改行コード:CRLF
で以下をsrc/main/resources/jp/demo/text1.txtに保存しています。

text1.txt
row1 test test
row2 あああ
row3 山田さん

実行

maven installしてjarを作成する。

実行結果

どちらのメソッドでもテキストファイルを取得できました。

実行結果
C:\sts\workspace\simple_maven\target>java -jar test-0.0.1-SNAPSHOT.jar
### START ###
getTextLines:
row1 test test
row2 あああ
row3 山田さん

getTextStr:
row1 test test
row2 あああ
row3 山田さん

### END ###

C:\sts\workspace\simple_maven\target>

文字コードSJISでテキストを保存した場合はこうなります。↓

実行結果
C:\sts\workspace\simple_maven\target>java -jar test-0.0.1-SNAPSHOT.jar
### START ###
getTextLines:
row1 test test
row2 ??????
row3 ?R?c????

getTextStr:
row1 test test
row2 ??????
row3 ?R?c????

### END ###

C:\sts\workspace\simple_maven\target>

SJISのテキストをUTF-8で読み込んだので文字化けしましたね。
それから、SJISに存在しない文字(有名なのは髙橋の「髙」など)を文字セットSJISでファイル出力したときも「?」に置き変わります。

余談

Eclipse上だと、Mavenプロジェクトはsrc/main/java、src/main/resources
に分かれますが、ビルドしてしまえば一緒になるのでどちらにテキストを保存しても同じです。

jarを展開してjp/demo/の下を見てみる
C:\Users\xxx\Desktop\test-0.0.1-SNAPSHOT\jp\demo のディレクトリ

2019/06/12  00:57    <DIR>          .
2019/06/12  00:57    <DIR>          ..
2019/06/12  00:27             1,815 Main.class
2019/06/11  01:39                26 text1.txt
2019/06/12  00:57    <DIR>          util
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?