Java6までは、Javaでファイルエンコーディングの変換を行おうとすると、Readerで開いて一行ずつ読み込みながらWriterで書き込むみたいなコードが必要になってました。
これはJava7のnioで導入されたファイルユーティリティで簡単に書けるようになったのですが、フォルダ以下のファイルをすべて処理しようとすると再帰コードを書く必要があったりして面倒でした。
※追記 7/9 コメントで指摘あるように、walkFileTreeを使うと再帰書かずにファイルツリーの処理ができました。walkだとStreamになって便利、という感じですね。
でも、Java8ではファイルユーティリティにフォルダ以下のファイルをすべて処理するためのwalkメソッドが追加されているので、すべてのファイルを処理するということも楽になりました。
ということで、指定フォルダ以下のファイルのすべての文字コードをWindows-31JからUTF-8に変換するとこんな感じになります。
public class Sjis2Utf8 { public static void main(String[] args) throws IOException { Path dir = Paths.get("C:\\Users\\naoki\\Desktop\\test"); Files.walk(dir) .filter(p -> !Files.isDirectory(p)) .forEach(p -> { try{ Path tmp = Files.createTempFile(dir, "tmp", ".txt"); Files.write(tmp, Files.readAllLines(p, Charset.forName("Windows-31j")), Charset.forName("utf-8")); Files.delete(p); Files.move(tmp, p); }catch(IOException ex){ throw new RuntimeException(ex); } }); } }
ただ、mainメソッドでthrowsを記述しているにもかかわらず、forEachの中でtry〜catchを書く必要があったりして、やっぱイケてないところが残ってしまっています。
forEachにはこういう問題もあるので、for文は使わざるを得なかったりするんですよねぇ。