読者です 読者をやめる 読者になる 読者になる

感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

実行環境が変わってもファイルを読み込めるように工夫してみる

Java SE
<スポンサーリンク>

Javaでファイルを読み込もうとすると、IOExceptionが出て、ファイルが開けない。
LinuxやWindowsで環境が変わると、ファイルのセパレータが変わるからまたファイルが見つからない。

環境が変わると、ファイルの場所も変わってしまう。結果、ファイルが見つからない。
Eclipseを使って、開発しているとそもそも配置したファイルの場所がよくわからない。

そういう悩みはよくある。個人的に。

たとえば何かのテスト用のデータファイルを置いたとして。
OSが変わっても、環境が変わっても、そのファイルを読み込めるようにしたい。
(本当に大事な業務用ファイルだったら、ちゃんとしたパスを決めて読み込むべきだ)

でも、テスト用のファイルなんかは、とりあえずテスト前に作って、テスト後に消したりするだろう。
そういうファイルの場所を、ちゃんと特定したい。

で、使ったのがダミークラスだ。

フォルダ構成はこんな感じ。

f:id:sho322:20140627014438j:plain

Dummy.javaと同じパッケージに、test.txtという読み込みたいファイルが置いてあることに注目。
test.txtにはこんな風に書いてある。

僕の名前はやんぼー
僕の名前はまーぼー
二人合わせてヤンマーだ!
君と僕とでヤンマーだ

で、Dummyクラスには、クラスファイル(.class)が格納されている場所の絶対パスを返すメソッドを用意する。
これで、Dummy.javaと同じ場所に配置したtest.txtの場所を特定しようってわけだ。

package dummy;

import java.io.File;
import java.net.URL;

public class Dummy {

	public String getDummyPath() {
		URL dummy = Dummy.class.getResource("Dummy.class");

		//jarとかになってたらダメ
		if (!"file".equalsIgnoreCase(dummy.getProtocol()))
			throw new IllegalStateException("Dummyクラスはファイルとして保存されていません");

		File path = new File(dummy.getPath());
		return path.getParent();
	}
}

こうすると、クラスファイルがある場所のパスを返すので、このパスをたよりに、読み込みたいファイルのパスを指定すればいいってわけだ。

じゃあ、実際に読み込んでみよう。

package action;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import dummy.Dummy;

public class Main {

	private final String FILE_NAME = "test.txt";

	public static void main(String[] args) {
		Main main = new Main();
		main.express();
	}

	private void express() {
		Dummy dummy = new Dummy();
		String path = dummy.getDummyPath();

		String fileFullPath = path + File.separator + FILE_NAME;

		File file = new File(fileFullPath);
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(file));
			String str = br.readLine();
			while(str != null) {
				System.out.println(str);
				str = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
	}
}

File.separatorというプロパティを使っているため、セパレータはLinuxでもWindowsでも対応できる。
ファイルの置き場所はDummy.classが格納されているディレクトリの中なので、このやり方でパスを取得すれば、環境に左右されることなく、ファイルを読み込むことができる。

実際に読み込むことができた。

僕の名前はやんぼー
僕の名前はまーぼー
二人合わせてヤンマーだ!
君と僕とでヤンマーだ

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)