未来エンジニア養成所Blog

月単価180万以上のプログラミング講師がプログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】オブジェクト指向の応用問題3-1

title


問題3-1

FileCopyPracticeクラスのmainメソッドは未完成です。

あるテキストファイルの内容を、別のテキストファイルにコピーするプログラムを作成してください。


その方法は、コピー元ファイルからFileReaderクラスとBufferedReaderクラスをうまく使ってデータを読み取り、そのデータをコピー先ファイルにFileWriterクラスとBufferedWriterクラスとPrintWriterクラスをうまく使って書き込みます。


コピー元ファイル名およびコピー先ファイル名の指定にはコマンドライン引数を使用してください。


【実行例】

> java FileCopyPractice コピー元ファイル名 コピー先ファイル名


コマンドラインが不正(2つの文字列が渡ってこない)の場合は「2つのファイル名を正しく指定してください」と表示してプログラムを終了します。


コピー元ファイルが見つからない場合はFileNotFoundExceptionがスローされます。
その際は「ファイル名の指定が不正です」と表示してプログラムを終了します。


それ以外にIOExceptionがスローされますので、そのときは「入出力エラーです」と表示してプログラムを終了します。


オープンしたファイルは適切にクローズしてください。


【FileCopyPractice.java】

public class FileCopyPractice {
    public static void main(String[] args) {

        // ここにファイルコピー処理を記述してください

    }
}


解答例

【ExceptionInheritancePractice.java】

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class FileCopyPractice {
    public static void main(String[] args) {

        BufferedReader br = null;
        PrintWriter pw = null;

        if(args.length != 2) {
            System.out.println("2つのファイル名を正しく指定してください");
            return;
        }

        try {
            // コピー元ファイル名のオープン
            br = new BufferedReader(new FileReader(args[0]));

            // コピー先ファイル名のオープン
            pw = new PrintWriter(new BufferedWriter(new FileWriter(args[1])));

            String str;

            // コピー元ファイルから1行分の文字列を取得
            while((str = br.readLine()) != null) {

                // 取得した文字列をコピー先ファイルに書き込み
                pw.println(str);
            }
        } catch(FileNotFoundException e) {
            System.out.println("ファイル名の指定が不正です");
        } catch(IOException e) {
            System.out.println("入出力エラーです");
        } finally {
            try {
                if(br != null) {
                    br.close();
                }
            } catch(IOException e) {
                e.printStackTrace();
            }

            // PrintWriterのcloseメソッドはIOException例外を送出しないため
            if(pw != null) {
                pw.close();
            }
        }
    }
}


解説

今回はファイルIOに関する問題です。


Javaでは、ファイルIOを行うクラス群がjava.ioパッケージに収められています。

ですので、使う際にはまずimport文を記述しましょう。

今回のように同じパッケージのクラスをたくさん使用する場合は、クラス名の部分をアスタリスクにして一括でインポートすることも可能です。
(ただしeclipseを使用している場合には、自動的に完全クラス名に置き換わってしまいます。)

import java.io.*;


これを「オンデマンドインポート」と言います。


しかし、開発現場ではオンデマンドインポートを推奨していないプロジェクトもありますので、その点は意識しておいてください。



今回の問題では、コピー元・コピー先ファイル名の指定にコマンドライン引数を使用します。

コマンドライン引数とは、プログラム実行時に渡すことのできる文字列情報のことです。

半角スペースで区切ることで、String配列の形でmainメソッドの引数に渡されます。

いつも記述しているString配列型引数のargsです。


今回は2つのデータが渡ってこないといけないので、配列オブジェクトが持っているlength属性で要素数をチェックしています。



ファイルの入力にはFileReaderクラス、出力にはFileWriterクラスを使うのが鉄則です。

しかし、この2つのクラスだけではパワーが弱いので、BufferedReaderクラスやBufferedWriterクラス、PrintWriterクラスなどを組み合わせてパワーアップさせています。


実際にデータをコピーしているのは、次のプログラムです。

while((str = br.readLine()) != null) {
    // 取得した文字列をコピー先ファイルに書き込み
    pw.println(str);
}


BufferedReaderクラスのreadLineインスタンスメソッドを呼び出すことで、テキストファイルの1行を取得することができます。

テキストファイルが何行あるかは分からないので、while文を使ってループさせます。


while文の丸括弧の中が少し難しく見えます。

readLineメソッドの戻り値を文字列変数strに格納していますが、Javaというプログラミング言語は、「代入演算も値を返す」ようにできています。

int x;
System.out.println(x = 10);


これはもちろん変数xに10が代入され、かつ「10」が出力されます。


話をreadLineメソッドに戻すと、このメソッドはファイルの終端まで到達するとnullを返します。

つまり、while文の評価の意味は「nullが返ってくるまでデータを取得し続けてください」ということです。



ファイルIO系クラスのほとんどのメソッドは検査例外IOException(とそのサブクラスの例外)をスローします。

ですので、一般的には大きなtryブロックを記述し、その中にファイル入出力処理を記述します。



そして、ファイルIOで特に重要なのは、ファイルを使える状態(オープンと言います)にしたら、最後は必ず後始末(クローズと言います)しなければいけないということです。

そして、ファイルのクローズ処理はfinallyブロックに記述して、必ず実行されるようにするのがベストです。

オープンしたファイルをクローズするにはcloseメソッドを実行するのですが、このcloseメソッドも検査例外IOExceptionをスローするので、finallyブロックに小さくtry-catchを記述します。



ちなみに、Java7からはリソースのクローズを自動的に行ってくれる「try-with-resources文」という新しい文法が追加されました。

tryの後ろに丸括弧を記述し、そこにクローズが必要なオブジェクトのインスタンス化と参照変数の宣言・代入を行うことで、自動的にcloseメソッドを呼び出してくれます。


参考図書



LINE公式アカウント

仕事が辛くてたまらない人生が、仕事が楽しくてたまらない人生に変わります。
【登録いただいた人全員に、無料キャリア相談プレゼント中!】


LineOfficial

友だち追加