[目次] [前回] [次回] [重要語索引]

第11週: ファイル

11. 1 ファイルについて復習
11. 2 ファイルの開け閉め
11. 3 練習問題
11. 4 標準入力
11. 5 練習問題
11. 6 宿題
11. 7 おまけ

11.1 ファイルについて復習

ファイルとは、ディスクに記憶するひとまとまりのデータです。情報処理 Iaで習ったことを復習しておきましょう。

プログラムが動いている間は、データは変数に記憶されていますが、プログラムが終了すると、変数に入っているデータは消えてしまいます。ずっと残しておきたいデータは、ファイルに記憶させなければなりません。例えば emacs では、バッファの内容はファイルに保存しないと消えてしまいます。

11.2 ファイルの開け閉め

プログラムで、ファイルに書いてあるデータを読み取ったり、ファイルに書き込んだりするには、次のような手順が必要です。

  1. 使いたいファイル名を指定して、ファイルを「開く(open)」という操作をします。これは、ディスクの中でそのファイルの置場所を探し出し、データを読み書きする準備を整えます。
  2. ファイルの中身を読んだり、ファイルにデータを書き込んだりします。
  3. 最後に、ファイルを「閉じる(close)」という操作をします。これは、もうこのファイルを使わないという合図をし、後片付けをします。

それでは、Java でテキストファイルの内容を標準出力に出すプログラムを見てみましょう。これは、UNIX コマンドの cat の基本的な機能と同じです。
バイナリファイルの内容を読み書きするには、少し違う方法が必要です。以下ではテキストファイルだけを扱います。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import java.io.*;

public class Cat {
    public static void main(String arg[]) throws FileNotFoundException, IOException {
	BufferedReader in = new BufferedReader(new FileReader(arg[0]));
	while(in.ready()) {
	    String s = in.readLine();
	    System.out.println(s);
	}
	in.close();
    }
}

日本語ファイルを読み書きするときは、どの文字コードを使っているかを指定しなければなりません。上のやり方では、その指定が省略されています。省略した場合のデフォールトは、CNS では EUC-JP になっていますので、ファイルの文字コードを変換しなければいけない場合があります。自分で指定したい場合は、InputStreamReader クラスを使用します。

11.3 練習問題

ファイルの中から、指定した文字列を含む行だけを抜き出して表示するプログラムを作りましょう。これは、UNIX の grep コマンドの基本的な機能と同じです。
% java Grep set SfcTemplate1.java
	t1.setColumns(20);
	t2.setColumns(20);
	t2.setEditable(false);
	setLayout(new BorderLayout());
	t2.setText(s);
% 

11.4 標準入力

標準入力を管理するインスタンスは System.in という変数に入っています。しかし、これはバイト単位の入力しかできないので、使いにくいです。行単位の入力ができるようにするには、次のようにしてください。

    BufferedReader in
        = new BufferedReader(new InputStreamReader(System.in));

それでは、標準入力から読み込んだ文字列を指定されたファイルに書き込むプログラムを見てみましょう。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import java.io.*;

public class Write {
    public static void main(String arg[]) throws FileNotFoundException, IOException {
	BufferedReader in = 
	    new BufferedReader(new InputStreamReader(System.in));
	PrintWriter out = 
	    new PrintWriter(new BufferedWriter(new FileWriter(arg[0])));
	while (true) {
	    String s = in.readLine();
	    if ( s == null ) {
		break;
	    }
	    out.println(s);
	}
	out.close();
    }
}

11.5 練習問題

標準入力から数値をいくつか読み込んで、その合計を標準出力に出すプログラムを書いてみましょう。

数値を読み込むとき、画面に何も出ないと、ユーザは何をしていいか分かりません。そこで、「キーボードから何か入力してください」という意味の文字列を表示します。このような文字列を入力促進記号(プロンプト)と呼びます。ここでは、number? という文字列を表示することにしましょう。ユーザが数値を入力すれば、また次のプロンプトを出します。C-d を入力すれば、それまでの数値の合計を表示します。
% java Sum 
number? 1
number? 2
number? 3
number? 
sum = 6
% 

  1. 合計を記憶する int 型の変数を用意しましょう。最初の値は0 です。
  2. 標準出力に "number? " を出力してから、標準入力から1行読み込みます。
  3. 入力が null なら繰り返しを終了します。
  4. 入力が null でなければ、文字列から整数に変換して、今までの合計に足し、新しい合計を記憶しておきます。
  5. 繰り返しが終わったら、その時の合計の値を標準出力に出します。

11.6 宿題

Grep.java を変更し、複数のファイルを一度に指定できるようにしましょう。表示するときは、どのファイルの何行目かも分かるようにしましょう。例えば、Label という文字列が SfcTemplate1.java,SfcTemplate2.java, SfcTemplate3.java の中の何行目に現れるか知りたければ、次のようにします。
% java Grep Label SfcTemplate1.java SfcTemplate2.java SfcTemplate3.java
SfcTemplate1.java:12:    Label l1 = new Label("Input:"), l2 = new Label("Output:");
SfcTemplate2.java:13:    Label l1 = new Label("Input:");
SfcTemplate3.java:14:    Label l1 = new Label("No Title");
% 

11.7 おまけ

ファイルを他人に見られてもいいように、暗号化するプログラムを書きましょう。Encrypt.java は、ファイルの各文字の文字コードに1を足してから別のファイルに書き込みむようにします。Decrypt.java は、逆に文字コードから1を引いて別のファイルに書き込みむようにします。

普通のファイルを Encrypt.java で変換すると、意味不明の内容になります。これを Decrypt.java で変換すると、元の内容に戻ります。


[目次] [前回] [次回] [重要語索引]

慶應義塾大学の授業以外での無断利用、複製はご遠慮下さい。
Copyright (c) 2000 慶應義塾大学