Developer

【はじめてのJava】Fileクラス【入出力処理編】
2022.10.31
Lv1

【はじめてのJava】Fileクラス【入出力処理編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


入出力処理編

入出力処理編では、Javaプログラムを外部ファイル等と連携する「入出力処理」について扱っていきます。
今回の記事は、java.ioパッケージのFileクラスを使った入出力処理について解説していきます。なお、この内容はJava Silverよりも少し高度な内容です。


目次


Fileクラス

Fileクラスとは、java.ioパッケージに含まれる入出力処理に関するクラスです。プログラム中でのこのクラスのオブジェクトはファイルを表し、OSに依存することなくファイルシステムを操作することが出来るようになります。
Fileクラスでファイルを指定する際は、ファイルのパス名を指定することになります。
Javaではこのファイルのパス名を抽象パスで取り扱っています。


抽象パス

上述の通り、Javaではファイルのパス名を抽象パスで取り扱っています。
抽象パスは、各OSで取り扱われているパス名を以下のように変換したものです。

・パスの先頭に使われる文字列を除外する。
 (Unixであればルートディレクトリを表す「/」、Windowsであればドライブを表す「c:」等の文字列のことです。)
・上記の文字列を除外した後、ディレクトリ名かファイル名を並べた名前の列でパス名を表す。
 (並べられた名前の列の最後の名前は、ファイル名かディレクトリ名を表しています。それ以外の名前は全てディレクトリ名を表しています。)

以下に通常のパス名から抽象パス名へと変換した例を記載しておきます。
●Windowsの場合
パス名:C:¥pleiades¥workspace¥project¥src
抽象パス名:pleiades/workspace/project/src

上記のように、抽象パスを使用してOS特有のパス表記を省いているため、OSに依存することなくファイルシステムを操作することが出来るようになっています。

また、必要に応じてシステム依存のファイルセパレータを取得することもできます。
システム依存のファイルセパレータを取得したい場合は、
System.getProperty(“file.separator”);
とすることで文字列でファイルセパレータを取得することが出来ます。取得したファイルセパレータはStringクラスの変数に代入して使うと良いでしょう。
(※ファイルセパレータとは、Windowsにおける「¥」のようなパス表記する際にフォルダ名やファイル名同士を区切る記号のことです。)

何らかの理由でWindowsベースのファイルセパレータを使用したい場合は、「C:¥¥pleiades¥¥workspace」のようにエスケープシーケンスの¥でファイルセパレータの¥をエスケープする。という書き方をする必要があります。
結果として¥が2つずつ並ぶことになります。


Fileクラスのコンストラクタ

Fileクラスを使用するためにはパス名が必要となります。Fileクラスには複数のコンストラクタが用意されており、インスタンス化の際に引数としてパス名を渡すことが出来ます。
コンストラクタにパス名を渡すことで、指定したファイルをFileクラスのオブジェクトとして取り扱うことが出来るようになります。
以下にFileクラスのコンストラクタの一部を紹介します。

コンストラクタ 説明
File(String pathname) String型のpathnameを抽象パス名に変換して、Fileクラスのオブジェクトを作成する
File(String parent, String child) 親パス名および子パス名をもとにFileクラスのオブジェクトを生成する。Parentがnullの場合、childをもとにオブジェクトを生成するため、上で説明した引数を1つとるコンストラクタの呼び出しと同じふるまいをする。そうでない場合、parentはディレクトリを表し、childはディレクトリまたはファイルを表す
File(File parent, String child) File型のparent抽象パス名とString型のchildパス名から抽象パス名を構築して、Fileクラスのオブジェクトを作成する

サンプルコード

以下にFileクラスを使った簡単なサンプルコードを紹介します。
ソースコード内でファイル名・ディレクトリ名を指定している部分がありますが、サンプルコードを実行する前に指定したファイル・ディレクトリを作成しておく必要はありません。理由は後ほど説明します。

import java.io.File;
import java.io.IOException;

public class Sample {
	public static void main(String[] args) {
		try {
			File f1 = new File("C:¥¥sample");
			File f2 = new File(".", "temp/log.txt");
			File f3 = new File(f1,"./Sample.txt");

			System.out.println("path for f1: " + f1.getCanonicalPath());

			System.out.println("path for f2: " + f2.getCanonicalPath());

			System.out.println("path for f3: " + f3.getCanonicalPath());

		}catch(IOException e) {
			e.printStackTrace();
		}
	}

}

筆者の環境で実行すると以下のような結果が出力されました。

今回のソースコードでは、3種類のコンストラクタを使用してFileクラスのオブジェクトをインスタンス化しています。

今回使用しているgetCanonicalPath()メソッドは、そのオブジェクトが参照しているパスを、システム依存のセパレータを使った絶対パスで返すメソッドです。こちらのメソッドを使用して、各オブジェクトが参照するファイルの絶対パスを出力しています。
Fileクラスの主なメソッドとその解説は次回記事にて解説します。

実行結果では3つのファイル・ディレクトリの絶対パスが出力されていますが、今回のソースコードではこれらのファイル・ディレクトリが実在するかどうかは実は関係ありません。

サンプルコードの処理は、あくまでファイル・ディレクトリにアクセスする準備を整えたようなイメージです。
パス名を指定してFileクラスのオブジェクトをインスタンス化することで「これらのパスへアクセスします」という宣言をしただけであり、まだ実際にはアクセスしていないので指定したファイル・ディレクトリが存在しておらずとも特に問題はないという状態です。
この状態から、Fileクラスのメソッドを呼び出すことで実際に指定したファイル・ディレクトリに対して操作をしていくことになります。
この段階になって初めて、指定したファイルが存在しない場合に予期せぬ動作が起こるといった事態に陥ります。

(※今回使用したFileクラスのメソッドは、例外処理が必須のチェック例外であるIOExceptionクラスをスローする可能性があるため、try-catch文を使用して例外処理を記述する必要があります。)


はじめてのJavaシリーズの目次はこちら