WisdomSoft - for your serial experiences.

10.4 ファイル制御

Java アプリケーションからディスク上のファイルを操作する方法を紹介します。指定したパスにファイルやディレクトリを生成する以外に、ファイルが存在しているかどうかなど情報を得ることもできます。

10.4.1 ファイル情報を得る

Java からファイルを操作する場合は、どこでも動く Java の特性を考慮する必要があります。なぜならば、ファイルシステムはプラットフォームによって異なっているためです。しかし、一般的な概念は共通しているので、パスや操作方法を抽象化すれば、ある程度の要求は実現することができます。

プログラムのソースコード内に文字列リテラルとしてファイルへのパスを指定することは避けなければなりません。パス区切り文字やファイル名として利用できる文字や記号などがシステムに依存する可能性があるからです。

システムに依存するパスを抽象化するには java.io.File クラスを利用します。文字列ではなく、File クラスとしてファイルへのパスを表現することで、システムへの依存を最小限に抑えることができるでしょう。このクラスは、ファイルの操作や情報の取得など、様々な機能を提供しています(表1)。

表1 Fileクラス(抜粋)
フィールド 解説
static String pathSeparator システムに依存するパス区切り文字です。
static char pathSeparatorChar システムに依存するパス区切り文字です。
static String separator システムに依存するデフォルトの名前区切り文字です。
static char separatorChar システムに依存するデフォルトの名前区切り文字です。
コンストラクタ
File(File parent, String child) 親パス名および子パス名文字列から新しい File のインスタンスを生成します。
File(String pathname) 指定されたパス名文字列を抽象パス名に変換して、新しい File のインスタンスを生成します。
File(String parent, String child) 親パス名文字列および子パス名文字列から新しい File のインスタンスを生成します。
File(URI uri) 指定された file: URI を抽象パス名に変換して、新しい File のインスタンスを生成します。
メソッド
boolean canRead() パス名が示すファイルをアプリケーションが読み込めるかどうかを判定します。
boolean canWrite() パス名が示すファイルをアプリケーションが変更できるかどうかを判定します。
boolean createNewFile() パス名が示す空の新しいファイルを不可分 (atomic) に生成します (そのファイルがまだ存在しない場合だけ)。
boolean delete() パス名が示すファイルまたはディレクトリを削除します。
void deleteOnExit() パス名が示すファイルまたはディレクトリが、仮想マシンが終了したときに削除されるように要求します。
boolean exists() パス名が示すファイルが存在するかどうかを判定します。
File getAbsoluteFile() 絶対形式を返します。
String getAbsolutePath() 絶対パス名文字列を返します。
File getCanonicalFile() 正規の形式を返します。
String getCanonicalPath() 正規のパス名文字列を返します。
String getName() パス名が示すファイルまたはディレクトリの名前を返します。
String getParent() 親のパス名文字列を返します。
File getParentFile() 親のパス名を返します。
String getPath() このパス名をパス名文字列に変換します。
boolean isAbsolute() パス名が絶対かどうかを判定します。
boolean isDirectory() パス名が示すファイルがディレクトリであるかどうかを判定します。
boolean isFile() パス名が示すファイルが普通のファイルかどうかを判定します。
boolean isHidden() パス名が示すファイルが隠しファイルかどうかを判定します。
long lastModified() パス名が示すファイルが最後に変更された時刻を返します。
long length() パス名に指定されているファイルの長さをバイト単位で返します。
String[] list() パス名が示すディレクトリにあるファイルおよびディレクトリを示す文字列の配列を返します。
File[] listFiles() パス名が示すディレクトリ内のファイルを示す抽象パス名の配列を返します。
boolean mkdir() パス名が示すディレクトリを生成します。成功すれば true が返ります。
boolean mkdirs() 必要な親ディレクトリも含め、パス名が示すディレクトリを生成します。成功すれば true が返ります。
boolean renameTo(File dest) パス名が示すファイルの名前を変更します。
boolean setReadOnly() パス名が示すファイルまたはディレクトリにマークを設定し、読み込みオペレーションだけが許可されるようにします。

システムに依存する区切り文字は File.separator フィールドから取得できます。パスを表す文字列には、絶対パスと相対パスのいずれも指定することができます。絶対パスとは、パスのフルネームのことで、ルートディレクトリの名前から指定します。一方、相対パスとはユーザーディレクトリを基準に表すパスのことです。ユーザーディレクトリとは、通常、仮想マシンを呼び出した元のディレクトリとなります。

コード1
import java.io.*;

class Test {
	public static void main(String args[]) throws Exception {
		File file = new File(args[0]);
		String strInfo = "絶対パス=" + file.getAbsolutePath() + "\n" +
		"正規パス=" + file.getCanonicalPath() + "\n" +
		"サイズ=" + file.length() + "\n" +
		"読み込み" + (file.canRead() ? "可能" : "不可能") + "\n" +
		"書き込み" + (file.canWrite() ? "可能" : "不可能") + "\n" +
		"パスはディレクトリ" + (file.isDirectory() ? "である" : "でない") + "\n" +
		"パスはファイル" + (file.isFile() ? "である" : "でない") + "\n" +
		"パスの実体は" + (file.exists() ? "存在する" : "存在しない");

		System.out.println(strInfo);
	}
}
実行結果
D:\読本Java1\10_04_00>java Test test
絶対パス=D:\読本Java1\10_04_00\test
正規パス=D:\読本Java1\10_04_00\test
サイズ=0
読み込み可能
書き込み可能
パスはディレクトリである
パスはファイルでない
パスの実体は存在する

D:\読本Java1\10_04_00>java Test test.txt
絶対パス=D:\読本Java1\10_04_00\test.txt
正規パス=D:\読本Java1\10_04_00\test.txt
サイズ=44
読み込み可能
書き込み不可能
パスはディレクトリでない
パスはファイルである
パスの実体は存在する

D:\読本Java1\10_04_00>java Test kitty
絶対パス=D:\読本Java1\10_04_00\kitty
正規パス=D:\読本Java1\10_04_00\kitty
サイズ=0
読み込み不可能
書き込み不可能
パスはディレクトリでない
パスはファイルでない
パスの実体は存在しない

コード1は、コマンドライン引数で指定したパスの情報を出力するプログラムです。File クラスは、名前こそ File となっていますが、ディレクトリを表すこともありますし、存在しないパスを参照していることもあります。

10.4.2 ファイル操作

File クラスを用いれば、ファイルを生成したり削除したりすることも可能です。createNewFile() メソッドを指定することで新しいファイルを作ることができますし、パスがディレクトリを表すようであれば mkdir() メソッドmkdirs() メソッドで新しいディレクトリを作れます。

コード2
import java.io.*;

class Test {
	public static void main(String args[]) throws Exception {
		File file = new File(args[0]);
		if (file.createNewFile()) System.out.println("ファイルを作成しました");
		else System.out.println("ファイルを作成できませんでした");
	}
}
実行結果
>java Test test.txt
ファイルを作成しました

>java Test test.txt
ファイルを作成できませんでした

コード2は、File クラスが提供する機能を利用し空のファイルを生成するプログラムです。コマンドライン引数で指定された名前のファイルを生成します。createNewFile() メソッドは、存在しないディレクトリを指定したり、すでに存在するファイル名を指定した場合はファイルを生成することができません。正常にファイルが作れたかどうかは、メソッドの戻り値を調べることで知ることができます。

この他に、delete() メソッドでファイルやディレクトリを削除したり renameTo() メソッドで名前を変更することができます。ただし、実行システムによってはセキュリティが整備されているかもしれません。その場合はファイルの操作や読み書きができない可能性があるので、実践の開発では十分な例外対策などが必要になるでしょう。