たまには日記の一つでも。

28にしてはじめたバイオリンの記録と、ときどき日曜ハッキング

java.io.File.renameTo()がパーティションを跨げない件

今日始めて知りました。誠に申し訳ない。

File.renameTo()は、Linux上ではrename()システムコールを使って実現されます。rename()システムコールは、ファイル実体はそのままで、ファイルのメタ情報のみを変更してrenameを実現します(故に高速)が、これができるのは同一パーティション上(同一ファイルシステム上)のみです。
ここまではまぁ、知ってみれば成る程合点が行くのですが、気に入らないのは、上記理由で失敗した時のJDKの挙動です。renameTo()の返り値はbooleanで、この場合はfalseが返るのですが、これだけではなぜ失敗したのかわかりません。ここはExceptionをスローすべきだと思うんですが。何か深い理由があるんでしょうか。
とりあえず、.NETのようにjava.io.File.moveTo()メソッドを実装してほしい。こういうところでは.NETの方が使い勝手がいいですね*1

ちなみに、Exceptionがスローされるわけでもないのに、なぜかrenameTo()が失敗する、という状況で、どうやってここまでたどり着いたか、というと、伝家の宝刀straceです。件のJavaプログラムをstraceにかましてやり、straceログをファイル名で検索すると、rename()システムコールで-1が返っているのがわかります。あとは偉大なるgoogle先生に聞けばよろし。偉大なりstraceとgoogle先生

*1:google先生によると、どうもWindows上ではjava.io.File.renameTo()でドライブを跨ぐことができるとかなんとか。へー。そうすると、.NETの方が使い勝手がいい、とか言うのはちょっと違う、ってことになりますねぇ。