0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Java発展学習6日目】テキストファイルとバイナリファイルについて

Last updated at Posted at 2021-07-06

ファイルへのアクセス方式

ファイルへのアクセス方式は以下の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のクラス定数を利用

サンプルコード

ReadAndWrite.java
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]
src/test_renamed.txt(src/test_cp.txt)
1st sentence is written by BufferedWriter.
2nd sentence is appended.

用語集

用語 内容
リダイレクト(redirect) プログラムの標準出力結果をファイルに転送する機能。
パイプ(pipe) プログラムの標準出力結果を別プログラムの標準入力に転送する機能。
フィルタ(filter) ストリーム内のデータに変換処理を行う機能。
シンボリックリンク(symbolic link) UNIX系OSにおけるショートカットの呼称。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?