ファイルへのアクセス方式
ファイル
へのアクセス
方式は以下の2通り。
方式 | メリット | デメリット |
---|---|---|
ランダムアクセス(random access) |
・高速アクセス | ・読み書き速度が低速 ・大容量ファイルの操作に不向き |
シーケンシャルアクセス(sequential access) |
・読み書き速度が高速 ・大容量のファイル操作も可能 |
・低速アクセス |
なお、ランダムアクセス
方式を用いる場合はRandomAccessFile
クラスを用いてバイトデータ
を読み書きしたり、
MappedByteBuffer
クラスを用いてバイト配列
を読み書きすることができる。
ファイルの分類
ファイル
はテキストファイル(text file)
とバイナリファイル(binary file)
に分類され、それぞれ以下の特徴をもつ。
ファイル | 内容 | アクセス用API |
---|---|---|
テキストファイル |
文字解釈が可能な文字列 データ |
FileReader /FileWriter
|
バイナリファイル |
文字解釈が不可能なバイト列 データ |
FileInputStream /FileOutputStream
|
テキストファイルの操作
テキストファイル
は文字ストリーム
を経由し、FileReader
を用いた読み込み
、FileWriter
を用いた書き込み
が可能。
なお、それぞれオブジェクト
の利用後に必ずオブジェクト
の解放(close)
処理を実行する必要がある。
FileReader
定義
// FileReaderオブジェクトの生成
FileReader(String fileName)
// パラメータ
// file: 読み込む「テキストファイル」のファイルパス
// 単一文字(char型)の読み込み
// -> 読み込み可能な文字が存在しない場合は"-1"を返却
// => 出力する場合はint型 -> char型 への変換が必要
// <- FileReaderはInputStreamReaderを継承
int InputStreamReader.read()
// 単一文字のスキップ
// <- FileReaderはReaderを間接的に継承
long Reader.skip(long n)
// パラメータ
// long: スキップする文字数
// FileReaderオブジェクトの解放
void InputStreamReader.close()
FileWriter
定義
// FileWriterオブジェクトの生成
FileWriter(String fileName, boolean append)
// パラメータ
// fileName: 書き込む「テキストファイル」のファイルパス(存在しない場合は新規作成)
// append: 末尾への追記フラグ
// -> trueの場合は末尾に追記、false(,省略)の場合は先頭に挿入
// 単一文字(char型)の書き込み
// <- FileWriterはOutputStreamReaderを継承
void OutputStreamWriter.write(int c)
// パラメータ
// c: 文字リテラルまたは「文字」を表すバイトコード
// 文字列の書き込み
// <- FileWriterはWriterを間接的に継承
void Writer.write(String str)
// パラメータ
// str: 書き込む文字列
// バッファリング文字列の強制書き出し
void OutputStreamWriter.flush()
// FileWriterオブジェクトの解放
void OutputStreamWriter.close()
バイナリファイルの操作
バイナリファイル
はバイトストリーム
を経由し、FileInputStream
を用いた読み込み
、FileOutputStream
を用いた書き込み
が可能。
なお、それぞれオブジェクト
の利用後に必ずオブジェクト
の解放(close)
処理を実行する必要がある。
FileInputStream
定義
// FileInputStreamオブジェクトの生成
FileInputStream(String name)
// パラメータ
// name: 読み込む「バイナリファイル」のファイルパス
// バイトデータの読み込み
int FileInputStream.read()
// FileInputStreamオブジェクトの解放
void FileInputStream.close()
FileOutputStream
// FileOutputStreamオブジェクトの生成
FileOutputStream(String name, boolean append)
// パラメータ
// name: 書き込む「バイナリファイル」のファイルパス(存在しない場合は新規作成)
// append: 末尾への追記フラグ
// -> trueの場合は末尾に追記、false(,省略)の場合は先頭に挿入
// バイト列データの書き込み
void FileOutputStream.write(byte[] b)
// パラメータ
// b: 書き込むバイト列データ
// バイトデータの書き込み
void FileOutputStream.write(int b)
// パラメータ
// b: 書き込むバイトデータを表す10進数整数
ストリーム(stream)
細分化したデータ
の送受信を可能にするストリーム
には、以下の種類が存在する。
クラス | 接続先 |
---|---|
System.out |
標準出力(standard out) |
System.err |
標準エラー出力(standard error) |
System.in |
標準入力(standard in) |
StringReader |
String型 文字列 |
ByteArrayOutputStream |
byte[]型 バイト配列 |
バッファリングフィルタ(buffering filter)
ストリーム
をバッファリング
しながら入出力を行うバッファリングフィルタ
は、以下の4種類。
フィルタ | 対応するファイル形式 | 継承元 |
---|---|---|
BufferedReader |
文字データ | Reader |
BufferedWriter |
文字データ | Writer |
BufferedInputStream |
バイトデータ | FilterInputStream |
BufferedOutputStream |
バイトデータ | FilterOutputStream |
定義
// BufferedReaderオブジェクトの生成
BufferedReader(Reader in)
// パラメータ
// in: 「文字ストリーム」を読み込むReaderオブジェクト
// BufferedWriterオブジェクトの生成
BufferedWriter(Writer out)
// パラメータ
// in: 「文字ストリーム」に書き込むWriterオブジェクト
// BufferedInputStreamオブジェクトの生成
BufferedInputStream(InputStream in)
// パラメータ
// in: 「バイトストリーム」を読み込むInputStreamオブジェクト
// BufferedOutputStreamオブジェクトの生成
BufferedOutputStream(OutputStream out)
// パラメータ
// in: 「バイトストリーム」に書き込むOutputStreamオブジェクト
ファイルの操作
File
クラスのメソッドを用いることで、ファイル
を操作することができる。
また、Path
インタフェースの実装クラスであるPaths
クラスのメソッドを用いてファイルの格納パス
(=Path
オブジェクト)を特定し、
Files
クラスのクラスメソッド(静的メソッド)
を用いて、柔軟かつ多機能なファイル操作
を行うことができる。
さらに、Class
クラスやClassLoader
クラスのgetResourceAsStream()
メソッドを用いることで、
クラスパス
を基準とした相対パス
でファイルを操作することができる。
定義(java.io.File)
// Fileオブジェクトの生成
File(String pathname)
// パラメータ
// pathname: ファイルパス
// ファイルの削除
boolean File.delete()
// ファイル名の変更
boolean File.renameTo(File dest)
// パラメータ
// dest: 変更後のファイルパスを保持するFileオブジェクト
// ファイルが存在する場合はtrueを返却
boolean File.exists()
// Fileオブジェクトが「ファイル」であればtrueを返却
boolean File.isFile()
// Fileオブジェクトが「フォルダ」であればtrueを返却
boolean File.isDirectory()
// ファイルサイズの取得
long File.length()
// Fileオブジェクトが保持する「フォルダ」のファイル一覧の取得
File[] File.listFiles()
定義(java.nio.file.Paths)
Path Path.get(
定義(java.nio.file.Files)
// ファイルのコピー
Path Files.copy(Path source, Path target, CopyOption... options)
// パラメータ
// source: 「コピー先ファイルパス」を表すPathオブジェクト
// target: 「コピー元ファイルパス」を表すPathオブジェクト
// options: 「コピー方法」を表すCopyOptionオブジェクト
// -> CopyOptionインタフェースを実装したLinkOptionまたはStandardCopyOptionのクラス定数を利用
// ファイルの移動または名前の変更
Path Files.move(Path source, Path target, CopyOption... options)
// パラメータ
// source: 「移動(変更)先ファイルパス」を表すPathオブジェクト
// target: 「移動(変更)元ファイルパス」を表すPathオブジェクト
// options: 「移動(変更)方法」を表すCopyOptionオブジェクト
// ファイルの削除
void Files.delete(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// ファイルが存在する場合はtrueを返却
boolean Files.exists(Path path, LinkOption... options)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// options: 「シンボリックリンクの不探査」を表すLinkOptionのクラス定数
// -> 既定ではシンボリックリンクを辿ってファイルの実体まで走査
// フォルダであればtrueを返却
boolean Files.isDirectory(Path path, LinkOption... options)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// options: 「シンボリックリンクの不探査」を表すLinkOptionのクラス定数
// ファイルサイズの取得
long Files.size(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// ファイルの「バイトデータ」を全て読み込む
byte[] Files.readAllBytes(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// ファイルの「全行(文字列データ)」をList型で読み込む
List<String> Files.readAllLines(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// ファイルの「全行(文字列データ)」をString型で読み込む
String Files.readString(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// BufferedReaderオブジェクトの取得
BufferedReader Files.newBufferedReader(Path path)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// BufferedWriterオブジェクトの取得
BufferedWriter Files.newBufferedWriter(Path path, OpenOption... options)
// パラメータ
// path: 「ファイルパス」を表すPathオブジェクト
// options: 「ファイルの展開方法」を表すOpenOptionオブジェクト
// -> OpenOptionインタフェースを実装したLinkOptionまたはStandardOpenOptionのクラス定数を利用
サンプルコード
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ReadAndWrite {
public static void main(String[] args) {
// try-with-resource文を利用したリソース生成
try (
// FileWriterオブジェクトの生成
// -> ファイルの新規作成(末尾に追記)
FileWriter fw = new FileWriter("src/test.txt", true);
// BufferedWriterオブジェクト(バッファリングフィルタ)の生成
BufferedWriter bw = new BufferedWriter(fw);
) {
// ファイルへの書き込み
// -> 改行する場合は改行文字(\n)を挿入
bw.write("1st sentence is written by BufferedWriter.\n");
bw.write("2nd sentence is appended.");
// 強制書き出し
bw.flush();
}
// 例外処理
catch (IOException e) {
System.out.println("Output Exception occurred.");
}
try (
// FileReaderオブジェクトの生成
FileReader fr = new FileReader("src/test.txt");
// BufferedReaderオブジェクトの生成
BufferedReader br = new BufferedReader(fr);
) {
// 入力ストリームが利用可能であればファイルを読み込む
if (br.ready()) {
// 読み込んだ文字列をnullで初期化(null安全の保証)
String line = null;
System.out.println("-- Output by BufferedReader --");
// 読み込んだ文字列がnullでない限り、コンソールに出力
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
//例外処理
catch (IOException e) {
System.out.println("Input Exception occurred.");
}
// try節中で定義するとcatch, finally節からは"見えない"ため、
// tryブロック外でnullで初期化しておく必要がある
BufferedReader br2 = null;
// Paths/Filesクラスを用いたテキストファイルの読み込み
try {
// Pathオブジェクトの取得
Path p = Paths.get("src/test.txt");
// ファイルのコピー
Files.copy(p, Paths.get("src/test_cp.txt"));
Files.copy(p, Paths.get("src/test_cp_delete.txt"));
Path pd = Paths.get("src/test_cp_delete.txt");
// ファイル名の変更
Files.move(p, Paths.get("src/test_renamed.txt"));
Path pr = Paths.get("src/test_renamed.txt");
// ファイルが存在する場合はファイルを削除
if (Files.exists(pd)) {
Files.delete(pd);
}
System.out.println("-- Output by Paths and Files --");
// ファイルの読み込み・出力(BufferedReaderを利用しない場合)
String str = Files.readString(pr);
System.out.println(str);
System.out.println("-- Output by Files and BufferedReader --");
// ファイルの読み込み・出力(BufferedReaderを利用する場合)
br2 = Files.newBufferedReader(pr);
if (br2.ready()) {
String line = null;
while ((line = br2.readLine()) != null ) {
System.out.println(line);
}
}
// ファイルサイズの取得
System.out.print("File size: ");
System.out.printf("%7.2f[KB]\n", ((double) Files.size(pr)) / 1024.0);
}
// 例外処理
catch (Exception e) {
System.out.println("Some exceptions occurred.");
}
finally {
try {
// BufferedReaderオブジェクトの解放処理
// <- close()メソッドも例外送出の可能性があるため、「finally節内」でtry節を用いて記述
br2.close();
}
catch (Exception e) {
System.out.println("BufferedReader br2 cannot be closed.");
}
}
}
}
-- Output by BufferedReader --
1st sentence is written by BufferedWriter.
2nd sentence is appended.
-- Output by Paths and Files --
1st sentence is written by BufferedWriter.
2nd sentence is appended.
-- Output by Files and BufferedReader --
1st sentence is written by BufferedWriter.
2nd sentence is appended.
File size: 0.07[KB]
1st sentence is written by BufferedWriter.
2nd sentence is appended.
用語集
用語 | 内容 |
---|---|
リダイレクト(redirect) |
プログラム の標準出力結果をファイル に転送する機能。 |
パイプ(pipe) |
プログラム の標準出力結果を別プログラムの標準入力に転送する機能。 |
フィルタ(filter) |
ストリーム 内のデータに変換処理 を行う機能。 |
シンボリックリンク(symbolic link) |
UNIX系OS におけるショートカット の呼称。 |