課題2201
(バイナリ) ファイルを別のファイルにコピーするプログラム BinaryCopier クラスをパッケージ j2.lesson09 に作成しなさい。
このプログラムは、二つのファイル名を入力し、一つ目に指定したバイナリファイルの内容を二つ目に指定したファイルにコピーする。課題2102と似ているが、このプログラムはテキストファイルのみでなくバイナリファイルも扱うことができる。
例えば、U:\ex2201sample.dat (ex2201sample.dat) という名前の次の内容を持つファイルがあったとする。
このプログラムを実行し、"U:/ex2201sample.dat", "U:/ex2201copy.dat" と入力すると、次のように表示される。
コピー元のファイル名を入力:U:/ex2201sample.dat コピー先のファイル名を入力:U:/ex2201copy.dat U:/ex2201sample.datからU:/ex2201copy.datにコピーしました。
さらに、上記のように表示された後、U: ドライブには ex2201copy.dat というファイルが作成され、次のような内容になっている。
次の擬似コードに従った出力をすること。
print "コピー元のファイル名を入力:" src = コンソール入力 (String) print "コピー先のファイル名を入力:" dst = コンソール入力 (String) copy(src, dst) if コピー中に例外が発生しなかった print src + "から" + dst + "にコピーしました。", 改行 else print src + "から" + dst + "にコピーできませんでした。", 改行
上記のプログラムは、j2.lesson09.BinaryCopier クラスの main メソッドに記述すること。
また、擬似コード中に現れる copy(src, dst) というメソッドは、次のようなメソッドである。
public static void copy(java.lang.String src, java.lang.String dst) throws java.io.IOException srcからdstにバイナリファイルの内容をコピーする。 このメソッド内で例外 FileNotFoundException, IOException が発生した場合は、 このメソッド内で捕捉せずに呼び出し元で処理する必要がある。 パラメータ: src - コピー元のファイル名 dst - コピー先のファイル名 例外: java.io.IOException - コピーしようとした際に例外が発生した場合
上記の仕様を持つメソッドも j2.lesson09.BinaryCopier クラス内に作成し、main 内の擬似コードの該当する部分から呼び出すこと。
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson09 にクラス BinaryCopier を作成
- 必要なメソッドを作成する
- テスト項目「BinaryCopierに対する骨格テスト」をパス
- それぞれのメソッドにプログラムを書く
- テスト項目「BinaryCopierに対する機能テスト」をパス
ヒント
copy メソッドの「このメソッド内で捕捉せずに呼び出し元で処理する必要がある」とはつまり、「このメソッドでは例外処理を行わずに呼び出し元に任せる」という意味である。そのような場合は throws で発生する例外 (RuntimeException を除く) を指定し、そのメソッド内では例外を catch しなければよい。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
ファイルが開けません | コピーしたファイルが開けなかった場合 |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample1 | ".temp/ex2201sample1.dat" の内容を ".temp/ex2201copy.dat" にコピー |
sample2 | 存在しないファイル ".temp/ex2201sample2.dat" の内容を ".temp/ex2201copy.dat" にコピー |
sample3 | ".temp/ex2201sample3.dat" の内容を書き込めないファイル ".temp/ex2201copy.dir" にコピー |
課題2202
ファイル内に書かれている数値を読み出し、その総和を表示するプログラム TotalInBinaryFile クラスをパッケージ j2.lesson09 に作成しなさい。
読み取ることができるファイルの形式は、次のようなファイルである。
まず、データを 1 バイトだけ読み、その値を「形式を表す値」とする。形式を表す値が 1 ならば次の 4 バイトは int 型の値が格納されていて、形式を表す値が 2 ならば次の 8 バイトは double 型の値が格納されている。この 1 バイト + (4 または 8 バイト) で一つの数値を表し、そのようなデータがいくつも並んでいる。
形式を表す値を読もうとした際にファイルの終端に達したら、プログラムを終了させる。また、形式を表す値が 1 または 2 ではない場合はエラーとなる。
例えば、U:\ex2202sample.dat に次のようなファイルが存在したとする。
形式を表す値 | 数値 |
---|---|
1 | 50000 |
2 | 3.1415926535 |
このファイルを作るためのプログラムは、以下のようになる。
String filename = "U:/ex2201sample.dat"; DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); try { // 5000 out.write(1); out.writeInt(5000); // 3.1415926535 out.write(2); out.writeDouble(3.1415926535); } finally { out.close(); }
課題のプログラムでは、上記のプログラムを実行して得られるようなファイルを読み込み、格納されている int 型の値や double 型の値を取得し、その合計値を表示する。
このプログラムを実行し、コンソールに "U:/ex2202sample.dat" と入力すると、次のように表示される。
ファイル名を入力:U:/ex2202sample.dat 合計は5003.1415926535
また、このプログラムは独自に定義した例外 j2.lesson09.IllegalFileFormatException をスローする可能性がある。この例外クラスは次のようなクラスである (パッケージ内にコピーして使用せよ)。
package j2.lesson09; public class IllegalFileFormatException extends Exception { // メッセージを指定して、例外インスタンスを作成する。 // message - メッセージ public IllegalFileFormatException(String message) { super(message); } }
形式を表す値は必ず 1 または 2 で、それ以外の値を読み込んだ場合は次のように例外をスローしてプログラムが終了させること (この際のメッセージは何でもよい)。
ファイル名を入力:U:/ex2202unknown.dat Exception in thread "main" j2.lesson09.IllegalFileFormatException: 不明なコード at j2.lesson09.TotalInBinaryFile.main(TotalInBinaryFile.java:62)
上記の "U:\ex2202unknown.dat" (ex2202unknown.dat) は、形式を表す値が 3 になっているデータを含むファイルである。
形式を表す値は必ず 1 バイトで、その値が 1 ならばその次には 4 バイトのデータが、その値が 2 ならばその次には 8 バイトのデータが必ず存在しなければならない。例えば、4 バイト (01 00 00 00) からなるファイル "U:\ex2202illegaleof.dat" (ex2202illegaleof.dat) を読み込んだ場合、int 型の値を読んでいる最中にファイルの終端に達してしまうため、次のように例外をスローしてプログラムを終了させること (この際のメッセージは何でもよい)。
ファイル名を入力:U:/ex2202illegaleof.dat Exception in thread "main" j2.lesson09.IllegalFileFormatException: 不正なファイルの終端 at j2.lesson09.TotalInBinaryFile.main(TotalInBinaryFile.java:69)
また、存在しないファイル "U:\ex2202notfound.dat" を指定した場合、次のように表示される。
ファイル名を入力:U:/ex2202notfound.dat U:/ex2202notfound.datが開けませんでした。
ファイルが見つからない場合や、ファイルの形式が不正である場合以外に IOException が発生した場合は、catch 節で捕捉しないでよい (つまり、このメソッドには throws IOException の指定をすればよい)。
プログラム全体の擬似コードは次の通りである。擬似コードに従った表示を行うこと。
print "ファイル名を入力:" filename = コンソール入力 (String) file = filename のファイルを読み込み用に開く if filename が開けない print filename + "が開けませんでした。", 改行 プログラムを終了 total = filename が指すファイル内に格納されている各数値の合計 if 1 でも 2 でもない「形式を表す値」を含んでいる throw IllegalFileFormatException if データを読み込んでいる途中でファイルの終端に達した throw IllegalFileFormatException if ファイル読み込み中に例外が発生しなかった print "合計は" + total
上記のプログラムは、j2.lesson09.TotalInBinaryFile クラスの main メソッドに記述すること。
手順
指定した箇所で必ずテストを行うこと。
- 詳細な擬似コードを作成する
- パッケージ j2.lesson09 にクラス TotalInBinaryFile を作成
- main メソッドを作成する
- テスト項目「TotalInBinaryに対する骨格テスト」をパス
- main メソッドにプログラムを書く
- テスト項目「TotalInBinaryに対する機能テスト」をパス
ヒント
java.io.DataInputStream を使う。このクラスが持つメソッドのいくつかは、java.io.EOFException という例外をスローする。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
(メンバ名), throws <T> | メンバを作る際に throws <T> の指定がない |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
<T> がスローされませんでした | 例外 <T> がスローされるべき場面でスローされなかった |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
sample1 | "1" というファイルを .temp/ex2202sample1.dat に作成 |
sample2 | "1.0" というファイルを .temp/ex2202sample2.dat に作成 |
sample3 | "1", "2.0", "3", "4.0" というファイルを .temp/ex2202sample3.dat に作成 |
unkwnon | ex2202unknown.dat と同じファイルを .temp/ex2202unknown.dat に作成 |
illegaleof | ex2202illegaleof.dat と同じファイルを .temp/ex2202illegaleof.dat に作成 |
notfound | 存在しないファイルを指定 |
課題2203 (optional)
バイナリデータとして書かれた学生の得点一覧ファイルを読み出すクラス ScoreDatabase をパッケージ j2.lesson09 に作成しなさい。
このプログラムは、課題2103にある ScoreDatabase クラスと非常に似ている。ただし、扱うファイルの形式がバイナリデータとなっている。
このバイナリデータは、データの先頭から順に次のような形式である。
- レコード数 - int 型のデータ, 4 bytes
- 下記をレコード数だけ繰り返す
- 学籍番号 - char 型のデータ 4 個分, 8 bytes
- 名前 - char 型のデータ 10 個分, 20 bytes
- 得点 - int 型のデータ, 4 bytes
ただし、学籍番号や名前が指定された文字数に満たない場合、末尾は (char) 0 で埋められている。
このプログラムの一部を掲載する。このプログラム (クラス) を j2.lesson09 パッケージ内にコピーし、これにコンストラクタやメソッドを書き加えること。
2005/11/24 23:49 名前の長さが char*8 になっていたのを char*10 に修正。ScoreDatabase.save(String) も修正してください。修正に伴い、ダウンロードできるデータも訂正しました。
package j2.lesson09; import java.io.*; import java.util.*; public class ScoreDatabase { private final List students; public void save(String filename) throws IOException { DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); try { // 最初に個数を int 型で書き込む out.writeInt(this.students.size()); for (int i = 0; i < this.students.size(); i++) { Student std = (Student) this.students.get(i); // id を書き込み (char*4, 8bytes) char[] id = std.getId().toCharArray(); for (int j = 0; j < 4; j++) { if (j < id.length) { out.writeChar(id[i]); } else { out.writeChar((char) 0); } } // name を書き込み (char*10, 20bytes) char[] name = std.getName().toCharArray(); for (int j = 0; j < 10; j++) { if (j < name.length) { out.writeChar(name[i]); } else { out.writeChar((char) 0); } } // score を書き込み (int, 4bytes) out.writeInt(std.getScore()); } } finally { out.close(); } } }
上記にある Student クラスは次のようなクラスである。このクラスを j2.lesson09 パッケージ内に作成すること。上記 j2.lesson09.ScoreDatabase を先に作成すると j2.lesson08.Student クラスが import されてしまう可能性があるため、import j2.lesson08.Student の指定があれば削除すること。
package j2.lesson09; public class Student { private final String id; private final String name; private final int score; // 学生インスタンスを作成する // - id この学生の学籍番号 // - name この学生の名前 // - score この学生の得点 public Student(String id, String name, int score) { super(); this.id = id; this.name = name; this.score = score; } // この学生の学籍番号を取得する public String getId() { return this.id; } // この学生の名前を取得する public String getName() { return this.name; } // この学生の得点を取得する public int getScore() { return this.score; } // この学生の成績を取得する public char getGrade() { if (this.score >= 80) { return 'A'; } else if (this.score >= 70) { return 'B'; } else if (this.score >= 60) { return 'C'; } else { return 'D'; } } // この学生の文字列表現を取得する public String toString() { return "id=" + getId() + ", name=" + getName() + ", score=" + getScore() + ", grade=" + getGrade(); } }
ScoreDatabase クラスには、次のようなコンストラクタやメソッドを記述すること。
- public ScoreDatabase(java.lang.String filename) throws java.io.IOException
- 学生の得点一覧ファイルの名前を指定してインスタンスを生成する。
- パラメータ:
- filename - 読み出すファイルの名前
- 例外:
- java.io.IOException - 得点一覧ファイルを読み込んでいる最中に例外が発生した場合
ファイルを読み込む場合は、このコンストラクタ内で読み込むこと。それ以外のメソッドでは throws IOException を発生させてはならない。また、このコンストラクタ内で例外が発生した場合は、捕捉せずに throws で呼び出し元に例外処理を任せること。
このコンストラクタで読み込めるデータの形式は、save メソッドで作成できるファイルと同じ形式であるものとする。正しい形式を持った "hoge.dat" というファイルが存在したとして、
ScoreDatabase sdb = new ScoreDatabase("hoge.dat"); sdb.save("foo.dat");
上記のようなプログラムを書いた際の動作として、hoge.dat と foo.dat の中身が同じになるようようにすること。
- public java.util.List getAllStudent()
- 一覧に含まれる全ての学生を Student 型を格納している List で取得する。List 内の順序は、コンストラクタに指定したファイルに記述されている順番に等しい。
- 戻り値:
- 全ての学生を含む List
「Student 型を格納している List」というのは、このメソッドを呼び出した結果、返ってくる List の各要素が Student クラスのインスタンスであるということを指す。
- public java.util.List getStudents(char grade)
- 一覧に含まれる学生のうち、gradeで指定した成績を持つ学生を取得する。このクラスが返す List は該当する学生を表す Student クラスのインスタンスを全て含む。 List 内の順序は、コンストラクタに指定したファイルに記述されている順番に等しい。
- パラメータ:
- grade - 取得する学生の成績, 'A', 'B', 'C', 'D' のいずれか
- 戻り値:
- 指定した成績を持つ学生を含む List
- 例外:
- java.lang.IllegalArgumentException - 引数に 'A', 'B', 'C', 'D' 以外のいずれかが指定された場合
取得する学生の成績は、Student クラスのインスタンスメソッド getGrade() の結果と等しくなるようにすること。また、指定した成績を持つ学生がいない場合は、長さ 0 の List を返すこと。
プログラムの例
まず、ex2203test.dat をダウンロードし、U:\ex2203test.dat に置く。これは、課題2103 の形式で表すと次のような内容を持つデータである。
0000,ほげ1,100 0002,ふー2,80 0005,ばー3,60 0009,ほげ4,40 0010,ふー5,20
このファイルを読む、簡単なプログラムを書いてみる。
public static void main(String[] args) { ScoreDatabase sdb; try { sdb = new ScoreDatabase("U:/ex2203test.dat"); } catch (IOException e) { System.out.println("U:/ex2203test.datが開けません"); return; } List all = sdb.getAllStudent(); System.out.println("全体の人数=" + all.size()); List as = sdb.getStudents('A'); printList('A', as); List bs = sdb.getStudents('B'); printList('B', bs); List cs = sdb.getStudents('C'); printList('C', cs); List ds = sdb.getStudents('D'); printList('D', ds); } private static void printList(char grade, List list) { System.out.println(grade + "の学生:"); for (int i = 0; i < list.size(); i++) { System.out.println(" " + list.get(i)); } }
上記のプログラムを実行すると、次のように表示される。
全体の人数=5 Aの学生: id=0000, name=ほげ1, score=100, grade=A id=0002, name=ふー2, score=80, grade=A Bの学生: Cの学生: id=0005, name=ばー3, score=60, grade=C Dの学生: id=0009, name=ほげ4, score=40, grade=D id=0010, name=ふー5, score=20, grade=D
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson09 にクラス Student を作成
- 詳細な擬似コードを作成する
- パッケージ j2.lesson09 にクラス ScoreDatabase を作成
- 指定したコンストラクタやインスタンスメソッドを作成する
- テスト項目「ScoreDatabaseに対する骨格テスト」をパス
- 各コンストラクタやメソッドにプログラムを書く
- テスト項目「ScoreDatabaseに対する単体テスト」をパス
ヒント
char 型の配列から、一部分を取り出して String 型に変換する場合、java.lang.String クラスのクラスメソッド valueOf(char[], int, int) が便利である。
また、ある文字 c が (char) 0 と同じ値を持つか判定する場合、「if (c == (char) 0) ..」のように書けばよい (0 を char にキャストしなくても同じ意味である)。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | メソッドを起動した結果が期待された結果と異なる。テスト項目を参照 |
例外 <E> がスローされませんでした | 例外 <E> が発生すべき場面で例外が発生しなかった |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
ScoreDatabase_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat") |
ScoreDatabase_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat") |
ScoreDatabase_sample4 | new ScoreDatabase(".temp/ex2203sample3.dat") |
getAllStudent_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getAllStudent() |
getAllStudent_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat").getAllStudent() |
getStudents_A_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('A') |
getStudents_A_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat").getStudents('A') |
getStudents_B_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('B') |
getStudents_B_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat").getStudents('B') |
getStudents_C_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('C') |
getStudents_C_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat").getStudents('C') |
getStudents_D_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('D') |
getStudents_D_sample2 | new ScoreDatabase(".temp/ex2203sample2.dat").getStudents('D') |
getStudents_a_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('a') |
getStudents_9_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('9') |
getStudents_at_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('@') |
getStudents_E_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('E') |
getStudents_Z_sample1 | new ScoreDatabase(".temp/ex2203sample1.dat").getStudents('Z') |
それぞれのファイルの内容は以下の通りである (読みやすいように 課題2103 と同じ形式で記述している)。
- .temp/ex2203sample1.dat (ex2203sample1.dat)
0000,ほげ1,100 0002,ふー2,80 0005,ばー3,60 0009,ほげ4,40 0010,ふー5,20
- .temp/ex2203sample2.dat (ex2203sample2.dat)
0000,ほげA,100 0006,ほげC,69 0010,ふーD,30 0004,ふーB,75 0003,ほげB,79 0007,ふーC,65 0002,ばーA,80 0008,ばーC,60 0005,ばーB,70 0009,ほげD,59 0001,ふーA,90 0011,ばーD,0
- .temp/ex2203sample3.dat (存在しないファイル)
課題2204 (optional)
ZIPファイルからデータを取り出すプログラム ZipUncompressor クラスをパッケージ j2.lesson09 に作成しなさい。
ZIPとは、世界で最もよく使われているファイル圧縮形式の一つで、いくつかのファイルをまとめて圧縮し、一つのファイルにすることができる。このようなファイルからデータを取り出すには専用のソフトウェアが必要で (WindowsXP には標準で ZIP ファイルの圧縮および展開ができる)、今回はこのような ZIP ファイルから圧縮されたデータを取り出すようなプログラムを製作する。
例えば、U:\ex2204hello.zip (ex2204hello.zip) というファイルに ex2204hello.txt という名前のファイルが格納されているとする。この ex2204hello.txt というファイルを取り出すには、課題のプログラムを実行して次のように入力する。
ZIP書庫ファイル名を入力:U:/ex2204hello.zip 書庫内のファイル名を入力:ex2204hello.txt 解凍先のファイル名を入力:U:/ex2204hello-uncompressed.txt U:/ex2204hello-uncompressed.txtにコピーしました
上記のように実行すると、U:\ex2204hello-uncompressed.txt に次のような内容のテキストファイルが作成される。
Hello, world!
例ではテキストファイルを用いたが、課題では全てのバイナリファイルを扱えるように設計すること。
プログラム全体の擬似コードは次の通りである。擬似コードに従った表示を行うこと。
プログラム全体 print "ZIP書庫ファイル名を入力:" zip = コンソール入力 (String) if zip が指すファイルを読み込めない print zip + "が読み込めません", 改行 return print "書庫内のファイル名を入力:" contents = コンソール入力 (String) if zip が指すファイル内に contents が存在しない print zip + "内の" + contents + "が存在しません", 改行 return print "解凍先のファイル名を入力:" target = コンソール入力 zip が指すファイル内の contents の内容を target に書き出す if 読み書き中に例外が発生しなかった print target + "にコピーしました", 改行 else print "コピー中に例外が発生しました", 改行
実行例
先ほどの U:\ex2204hello.zip (ex2204hello.zip) を使って、いくつか例を示す。
ZIP書庫ファイル名を入力:U:/ex2204hello.zip 書庫内のファイル名を入力:ex2204hello.txt 解凍先のファイル名を入力:U:/ex2204hello-uncompressed.txt U:/ex2204hello-uncompressed.txtにコピーしました
ZIP書庫ファイル名を入力:U:/ex2204hallo.zip U:/ex2204hallo.zipが読み込めません
ZIP書庫ファイル名を入力:U:/ex2204hello.zip 書庫内のファイル名を入力:ex2204hallo.txt U:/ex2204hello.zip内のex2204hallo.txtが存在しません
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson09 にクラス ZipUncompressor を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- テスト項目「ZipUncompressorに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「ZipUncompressorに対する単体テスト」をパス
ヒント
ZIP ファイルの形式を調べて自分で解凍処理を実装してもよいが、非常に大変である。そのため、ZIP ファイルを扱うような ZIP ファイルを扱うような API を探すとよい。検索エンジンなどに Java ZIP といったキーワードを入力してみよ。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), static | メンバを作る際に static の指定がない |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
機能テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
機能テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
notfound | 存在しないファイル .temp/ex2204.zip の内容を参照 |
hello_hello | .temp/ex2204hello.zip!ex2204hello.txt の内容を .temp/ex2204hello.txt に展開 |
hello_notfound | 存在しないファイル .temp/ex2204hello.zip!notfound の内容を参照 |
sample_ex2201 | .temp/ex2204sample.zip!ex2201sample.dat の内容を .temp/ex2204sample1.dat に展開 |
sample_ex2202 | .temp/ex2204sample.zip!ex2202sample1.dat の内容を .temp/ex2204sample2.dat に展開 |
sample_ex2203 | .temp/ex2204sample.zip!ex2203sample1.dat の内容を .temp/ex2204sample3.dat に展開 |
sample_ex2204 | .temp/ex2204sample.zip!ex2204hello.zip の内容を .temp/ex2204sample4.dat に展開 |
sample_notfound | 存在しないファイル .temp/ex2204sample.zip!ex2205sample.dat の内容を参照 |
上記テストに出てくるZIPファイルは、次のようなファイルである。