Powered by Google App Engine

Google guava-libraries

 

Files

Filesについての検証です。apache commons-ioに負けず劣らずなライブラリです。超便利メソッドの宝庫なので、絶対マスターしましょう。

新サイト、tree-mapsを公開しました!!

tree-maps: 地図のWEB TOOLの事ならtree-mapsにお任せ!

地図に関するWEB TOOL専門サイトです!!

大画面で大量の緯度経度を一気にプロット、ジオコーディング、DMS<->DEGの相互変換等ができます!

◯ 広告

ファイルの読み込みでよく使うBufferedReaderを簡単に生成できます。

public void newReader() throws FileNotFoundException {
	BufferedReader br = Files.newReader(new File("files.txt"), Charsets.UTF_8);
}

かなり短いコードになりましたね。チェック例外も1個だけです。

public void newReader() throws FileNotFoundException, UnsupportedEncodingException {
	BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("files.txt"), "UTF-8"));
}

ファイルを1行づつ読み込む際によく見るこのコード、長いうえチェック例外が2個もあります。

BufferedReaderはfinallyでCloseable.closeQuietlyで安全にcloseできます。

ファイルの読み込みでよく使うBufferedReaderを簡単に生成できます。

public void newWriter_1() throws FileNotFoundException {
	BufferedWriter bw = Files.newWriter(new File("files.txt"), Charsets.UTF_8);
}

ファイルを1行づつ書き込む際によく見るこのコード、長いうえチェック例外が2個もあります。

public void newWriter_2() throws UnsupportedEncodingException, FileNotFoundException {
	BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("files.txt"), "UTF-8"));
}

よく見るこのコード、長いうえチェック例外が2個もあります。

BufferedWriterはfinallyでCloseable.closeQuietlyで安全にcloseできます。

必ず一意のフォルダ名になるtempフォルダを生成してくれます。

tempフォルダといっても自動削除されないので注意。

public void createTempDir() {
	File f = Files.createTempDir();
	System.out.println(f.getAbsolutePath());
	=> /var/folders/sm/z3m8wgfn45gc_tt0pc_7lgn00000gn/T/1348066891908-0
}

自動で一意になるフォルダ名でフォルダを生成してくれるので、非常に楽です。

public void createTempDir() {
	File f = new File("/tmp/temp_" + System.currentTimeMillis());
	System.out.println(f.getAbsolutePath());
	=> /tmp/temp_1348067249455
}

自動で一意になるフォルダ名でフォルダを生成してくれないので、自力でフォルダ名を生成する必要があります。

例ではタイムスタンプを使いましたが、ミリ秒単位で同じタイミングでフォルダが生成される事もあるでしょう。

BufferedWriterはfinallyでCloseable.closeQuietlyで安全にcloseできます。

public void write() throws IOException {
	Files.write("fuga", new File("/tmp/fuga.txt"), Charsets.UTF_8);
}

$ cat /tmp/fuga.txt 
fuga$

簡易的にファイルに文字列を上書きします。

public void write() throws IOException {
	BufferedWriter bw = null;
	try {
		bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("fuga.txt"), "UTF-8"));
		bw.write("fuga");
	} finally {
		Closeables.closeQuietly(bw);
	}
}

$ cat /tmp/fuga.txt 
fuga$
public void append() throws IOException {
	Files.append("hoge", new File("/tmp/test.txt"), Charsets.UTF_8);
}

$ cat /tmp/test.txt 
hoge$

簡易的にファイルに文字列を追記します。

public void append() throws IOException {
	printHeader();
	BufferedWriter bw = null;
	try {
		bw = new BufferedWriter(new FileWriter(new File("/tmp/append.txt"), true));
		bw.write("hoge");
		bw.newLine();
	} finally {
		Closeables.closeQuietly(bw);
	}
}

$ cat /tmp/append.txt 
hoge
hoge
$

お馴染みのこのコード、文字コード指定で文字列を書き込むのにこのコード量。面倒ですね。

超簡単にファイルコピーができます。これは便利。

public void copy() throws IOException {
	Files.copy(new File("/tmp/test1.txt"), new File("/tmp/test2.txt"));
}

$ cat test1.txt 
hoge
$ cat test2.txt 
hoge

例ではファイルへコピーしてますが、OutputStreamにコピーすることもできます。

public void copy() throws IOException  {
	FileInputStream fis = new FileInputStream(new File("/tmp/test1.txt"));
	FileOutputStream fos = new FileOutputStream(new File("/tmp/test2.txt"));
	try {
		byte[] buffer = new byte[1024];
		int i = 0;
		while ((i = fis.read(buffer)) != -1) {
			fos.write(buffer, 0, i);
		}
	} finally {
		Closeables.closeQuietly(fis);
		Closeables.closeQuietly(fos);
	}
}

$ cat test1.txt 
hoge
$ cat test2.txt 
hoge

酷い・・酷すぎる。ファイルコピーだけでこんな感じのコードが必要です。

public void getChecksum() throws IOException {
	long checkSum = Files.getChecksum(new File("/tmp/test.txt"), new CRC32());
	System.out.println(checkSum);
	=> 2335827034
}

ファイルの転送等が成功したかどうか等、ファイルの誤り検出符号、チェックサムを取得する事ができます。

public void getFileExtension() {
	String extension = Files.getFileExtension(new File("test.log.20120920").getName());
	System.out.println(extension);
	=> 20120920
}

ファイルの拡張子を取得します。標準機能というところがいいですね。

チェック例外もありません。

public void getFileExtension() {
	printHeader();
	String[] array = new File("test.log.20120920").getName().split("\\.");
	System.out.println(array[array.length - 1]);
	=> 20120920
}

splitして配列の末尾を取得しています。splitのエスケープ忘れや配列でエラーを誘発しそうです。

public void readLines() throws IOException {
	List<String> list = Files.readLines(new File("/tmp/test.txt"), Charsets.UTF_8);
	System.out.println(list);
	=> [hoge1, hoge2, 3, hoge4, hoge5, hogehogehoge]
}

行のフィルタ処理が不要なら、これだけリストが取得できてしまいます。

但しメモリの圧迫に注意。

public void readLines() throws IOException {
	List<String> lines = Files.readLines(new File("/tmp/test.txt"),
		Charsets.UTF_8, new LineProcessor<ImmutableList<String>>() {
			final ImmutableList.Builder<String> builder = ImmutableList
					.builder();

			@Override
			public boolean processLine(String line) {
				if (line.matches("hoge.*"))
					builder.add(line);
				return true;
			}

			@Override
			public ImmutableList<String> getResult() {
				return builder.build();
			}
		});
}

フィルタを通した結果の行をリストで取得しています。

public void readLines() throws IOException {
	BufferedReader br = null;
	List<String> list = new ArrayList<String>();
	try {
		br = new BufferedReader(new InputStreamReader(new FileInputStream(
				"/tmp/test.txt"), "UTF-8"));
		String line;
		while ((line = br.readLine()) != null) {
			if (line.matches("hoge.*"))
				list.add(line);
		}
	} finally {
		Closeables.closeQuietly(br);
	}
}

そんなに悪くはありませんが、closeが必要だったりwhileの部分が醜悪です。

public void readFirstLine() throws IOException {
	String firstLine = Files.readFirstLine(new File("/tmp/test.txt"), Charsets.UTF_8);
	System.out.println(firstLine);
	=> hoge1
}

おお、先頭行を1行読み込む処理がこんな簡単に実現できました。凄い。

public void readFirstLine() throws IOException {
	BufferedReader br = null;
	String firstLine = null;
	try {
		br = new BufferedReader(new InputStreamReader(new FileInputStream("/tmp/test.txt"), "UTF-8"));
		String line;
		while ((line = br.readLine()) != null) {
			firstLine = line;
			break;
		}
	} finally {
		Closeables.closeQuietly(br);
	}
	System.out.println(firstLine);
	=> hoge1
}

やはり醜悪です。先頭行だけ読むのにいちいちBufferedReaderが出てきます。

public void equal() throws IOException {
	boolean isSame = Files.equal(new File("/tmp/test1.txt"), new File("/tmp/test2.txt"));
	System.out.println(isSame);
	=> true
}

ファイルの中身が同一かどうかをチェックできます。

public void equal() throws IOException {
	BufferedReader br1 = null;
	BufferedReader br2 = null;
	boolean isDiff = true;
	try {
		br1 = new BufferedReader(new InputStreamReader(new FileInputStream("/tmp/test1.txt"), "UTF-8"));
		br2 = new BufferedReader(new InputStreamReader(new FileInputStream("/tmp/test2.txt"), "UTF-8"));
		String line1;
		String line2;
		while ((line1 = br1.readLine()) != null) {
			line2 = br2.readLine();
			if (!line1.equals(line2)) {
				isDiff = false;
				break;
			}
		}
	} finally {
		Closeables.closeQuietly(br1);
		Closeables.closeQuietly(br2);
	}
	System.out.println(isDiff);
}

これも中々の酷さですね。こんなコード書きたくないですね。

public void move() throws IOException {
	Files.move(new File("/tmp/test.txt"), new File("/tmp/TEST.txt"));
}
public void move() throws IOException {
	new File("/tmp/test.txt").renameTo(new File("/tmp/TEST.txt"));
}
public void simplifyPath() throws IOException {
	String path = Files.simplifyPath(new File("//tmp//test.text/").getAbsolutePath());
	System.out.println(path);
	=> /tmp/test.text
}

使い道がイマイチ不明な謎メソッド、simplifyPathです。

public void touch() throws IOException {
	Files.touch(new File("/tmp/touch1.txt"));
}
public void touch() throws IOException {
	new File("/tmp/touch2.txt").createNewFile();
}

あまり変わりませんが、touchというのがlinux/unixユーザにはお馴染みで解りやすい。

$ cat ./test.txt 
111
222
333
$ 

public void toString() throws IOException {
	String s = Files.toString(new File("/tmp/test.txt"), Charsets.UTF_8);
	System.out.println(s);
	=>
111
222
333
}

ファイル中の行を文字列に改行コード付きで出力します。たった1行でこれが実現できます。

これはSplitterと組み合わせれば更に有用に使えますね。

$ cat ./test.txt 
111
222
333
$ 

public void toString() throws IOException {
	BufferedReader br = null;
	StringBuilder sb = new StringBuilder();
	try {
		br = new BufferedReader(new InputStreamReader(new FileInputStream("/tmp/test.txt"), "UTF-8"));
		String line;
		while ((line = br.readLine()) != null) {
			sb.append(line).append("\n");
		}
	} finally {
		Closeables.closeQuietly(br);
	}
	System.out.println(sb.toString());
	=>
111
222
333
}

BufferedReaderの存在が醜悪で仕方ありませんね。

treeおすすめの書籍です!
【送料無料】実践ハイパフォ-マンスMySQL第2版

【送料無料】実践ハイパフォ-マンスMySQL第2版
価格:4,830円(税込、送料別)

【送料無料】エキスパ-トのためのMySQL運用+管理トラブルシュ-ティングガイド

【送料無料】エキスパ-トのためのMySQL運用+管理トラブルシュ-ティングガイド
価格:3,465円(税込、送料別)

【送料無料】基礎からのMySQL改訂版

【送料無料】基礎からのMySQL改訂版
価格:3,129円(税込、送料別)

◯ 広告