じゃじゃ馬ならし

 

df と chmod - File

どのくらいある?

Java ではファイルやディレクトリ、ファイルシステムなどを扱うことができますが、そのメタデータを取得するのは苦手です。

試しに Java だけでファイルマネージャ (ファイルエクスプロラーでも何でもいいんですけど) を作ることを考えて見ましょう。ファイル名はもちろん分かりますよね。サイズも最終更新日も分かります。でも、ファイルの作成日時はどうでしょう。所有者は?

結局、JNI を使わないとこれらのデータは取得できないのです。

これは Java SE 6 でも同じです。でも、ちょっとだけ扱うことのできるメタデータが増えました。

それが、パーティションのサイズと、属性です。

まずはパーティションのサイズです。

サンプルのソースコード FileSample1.java

新しく File クラスに getTotalSpace/getFreeSpace/getUsableSpace メソッドが加わりました。これらを使えばパーティションのサイズを調べることができます。

        File file = new File("C:");
        System.out.println("C:");
        System.out.println("Total:  " + file.getTotalSpace());
        System.out.println("Free:   " + file.getFreeSpace());
        System.out.println("Usable: " + file.getUsableSpace());

 

まずは Windows のルートで実行してみます。まぁ、これでちゃんと出なかったら問題ですけどね。

C:\temp>java FileSample1
C:
Total:  20003876864
Free:   5998415872
Usable: 5998415872

 

単位はバイトです。トータルが約 20GB で 6GB 弱が使えるということですね。

実際には下図のようになっています。空き領域はちょっと違いますが、誤差の範囲でしょう。

C:

さて、次はルート以外のディレクトリと、実際には存在しないディレクトリで試してみました。

        file = new File("C:\\temp");
        System.out.println("\nC:\\temp (exist)");
        System.out.println("Total:  " + file.getTotalSpace());
        System.out.println("Free:   " + file.getFreeSpace());
        System.out.println("Usable: " + file.getUsableSpace());

        file = new File("D:\\temp");
        System.out.println("\nD:\\temp (not exist)");
        System.out.println("Total:  " + file.getTotalSpace());
        System.out.println("Free:   " + file.getFreeSpace());
        System.out.println("Usable: " + file.getUsableSpace());

 

この部分の実行結果は次のようになりました。

C:\temp (exist)
Total:  20003876864
Free:   5998415872
Usable: 5998415872
 
D:\temp (not exist)
Total:  0
Free:   0
Usable: 0

 

ちゃんと存在するならば、どのディレクトリで実行しても OK のようです。逆に存在しない場合は例外が発生するのではなく、単に 0 が戻るようですね。

最後に Windows にはない / を試してみましょう。

        file = new File("/");
        System.out.println("\n/");
        System.out.println("Total:  " + file.getTotalSpace());
        System.out.println("Free:   " + file.getFreeSpace());
        System.out.println("Usable: " + file.getUsableSpace());

 

実行したら次のような結果が得られました。

/
Total:  20003876864
Free:   5998415872
Usable: 5998415872

 

どうやら、カレントディレクトリが存在するパーティションの領域を返すようです。

 

属性を変更

ようするに chmod です。

この用途のために File#setReadable/setWritable/setExecutable メソッドが新たに定義されています。

サンプルのソースコード FileSample2.java

 

import java.io.File;
 
public class FileSample2 {
    public FileSample2(String filename) {
        File file = new File(filename);
 
        System.out.print("+r: ");
        System.out.println(file.setReadable(true, true)? "success": "false");
 
        System.console().readLine();
  
        System.out.print("-r: ");
        System.out.println(file.setReadable(false, true)? "success": "false");
 
        System.console().readLine();
 
        System.out.print("+r (not only owner): ");
        System.out.println(file.setReadable(true, false)? "success": "false");
 
        System.console().readLine();
 
        System.out.print("-r (not only owner): ");
        System.out.println(file.setReadable(false, false)? "success": "false");
    }
 
    public static void main(String[] args) {
        new FileSample2(args[0]);
    }
}

 

これらのメソッド群は引数が 1 つのものと、2 つのものがあります。2 つのものの第 2 引数は boolean でオーナ以外の属性も変更するかどうか指定するようです。true だとオーナだけ、false だとオーナ以外の属性も変更されます。

dummy.txt を引数にして実行してみました。これは Windows で実行してもあまり意味がないので、Linux で実行してます。

途中、入力待ちになっているときに dummy.txt の属性を表示させてみると、 次のようになりました。

[sakuraba@dhcp189 ~]$ ls -l dummy.txt
--w--w----  1 sakuraba sakuraba 0 10月 26 22:05 dummy.txt
[sakuraba@dhcp189 ~]$ ls -l dummy.txt
-rw--w----  1 sakuraba sakuraba 0 10月 26 22:05 dummy.txt
[sakuraba@dhcp189 ~]$ ls -l dummy.txt
--w--w----  1 sakuraba sakuraba 0 10月 26 22:05 dummy.txt
[sakuraba@dhcp189 ~]$ ls -l dummy.txt
-rw-rw-r--  1 sakuraba sakuraba 0 10月 26 22:05 dummy.txt
[sakuraba@dhcp189 ~]$ ls -l dummy.txt
--w--w----  1 sakuraba sakuraba 0 10月 26 22:05 dummy.txt
[sakuraba@dhcp189 ~]$

 

ちゃんと属性が変更されています。

 

おわりに

この機能追加は本来は New I/O に含まれているはずだと思います。というのも JSR-51 の Request のところに

と書いてあるからです。

でも、Merline では取りいれられず、Tiger かと思ったら全然その話題はなく、ようやく Java SE 6 で少しだけ取りいれられたということのようです。

JSR-51 でスリップしてしまったので、JSR-203 NIO 2 では Request のトップに new filesystem interface がきています。でも、これも Call for Expert で止まっているようです。

やっぱり Dolphin なのかなぁ。

 

(Nov. 2005)