7.ファイルの取り扱い
Copyright(C) 13Sep2013 coskx
このページではJavaプログラムでファイルを取り扱う。
ここで修得してほしい内容は以下の通りである。
1.printfを用いたコンソール画面への出力と同じように,printfを使用してファイルへの出力が出来る。
2.文字単位,行単位でのファイルからの入力が出来る。
3.行単位でのファイル入力から,行を分解して数値データ列の処理が出来る
4.コマンドラインの取り込みと,引数を取り出すことが出来る
5.バイナリファイルの入出力が出来る
内容は以下を含んでいる。
7.1 ファイルへの書き出し
コンソール画面への出力をそのままファイルへ書き出す
7.2 テキストファイルの構造を理解する
7.3 ファイルからの文字単位読み込み
キーボード入力の替わりに,ファイルからデータを読み込む
7.4 ファイルからの行単位読み込み
7.5 ファイルからの数値データの読み込み
7.6 コマンドラインの取り込み
7.7 バイナリファイルの処理
Javaには様々なファイル操作の方法(クラスライブラリ)が用意されている。基本的には○○reader(読み込み,ファイル入力)と○○writer(書き込み,ファイル出力)という名前である。ここでは代表的なReader,Writerを紹介する。
演習における注意 ここでのプログラムの実行においては,実行形式ファイルおよび書き出すファイル,読み込み用ファイルはすべて同一ディレクトリに存在するものとし,実行はコンソール画面から行なう。
ファイルからの読み込み
(ファイル入力)
ファイルへの書き込み
(ファイル出力)
テキストファイル 文字単位の操作
FileReaderのread()
PrintWriterのprintfなど
テキストファイル 行単位の操作 FileReader BufferedReaderのreadLine()
PrintWriterのprintfなど
テキストファイル 数値データの操作 FileReader BufferedReaderのreadLine()
Stringのsplit()
PrintWriterのprintfなど
バイナリファイル
FileInputStreamのread()
FileOutputStreamのwrite()
7.1 ファイルへの書き出し
コンソール画面に文字を表示する時にはSystem.out.printf,System.out.print,System.out.printlnを使った。
ファイルに文字を出力するには似たようなprintf,print,printlnを使う。
次
のような内容を画面に表示する場合とファイルに書き出す場合のプログラムを並べて書いて比較してみよう。「(A)画面出力」ではコンソール画面に文字が書
き出され,「(B)ファイル出力」ではコンソール画面にはなにも出力されないがファイルmyfile.txtが出来る。テキストエディタでファイル
myfile.txtを開いてみると「(A)画面出力」でコンソール画面に表示された内容が書いてあることが確認でき,ファイルへの書き出しが成功してい
るはずである。
各自で実行してみなさい。
Hello. How are you?
Fine, thanks. And You?
So so.
List7.1.1 文字出力プログラムの比較 | |
(A)画面出力 |
(B)ファイル出力(ファイル名はmyfile.txt) |
public class XXXX { public static void main(String[] args) { XXXX mainprg = new XXXX(); } XXXX() { System.out.printf("Hello. How are you?\n"); System.out.printf("Fine, thanks. And You?\n"); System.out.printf("So so.\n"); } } |
import java.io.*; // BufferedReader public class XXXX { |
ファイルの入出力では,ファイルが存在しなくてそれ以上読み込み作業が継続できないとか,
存在しないドライブに対してファイルを書き込もうとしてそれ以上書き込み作業が継続できないといった
ことが起こる。
そのため,エラーが起きたらその後をどうするかプログラムにあらかじめ書いておかなければならない。
この記述方法が
という記述である。Aを実行して途中で何かエラーが起こったらCを実行しなさいという意味になる。
try{
A
} catch( B ) {
C
}
この記述はすでにキーボード入力のためのメソッドgetInt,getDouble,getStringなどの中で用いていた。
たとえばgetIntの中で数値以外のキーが入力され,エラーが生じても大丈夫ようになっていた。
ファイルへ書き出すためのプログラムを検討しよう。全部で3つの部分に分かれている。
項目 |
プログラムでの記述 |
1.ファイル名を指定してファイル出力の準備を行なう。 Fileは型名(実はクラス名) myfile,mywriterは変数名なので別の名前でもよい。 この後,ファイルはファイル名ではなく, mywriterで扱われる ファイル名"myfile.txt"の場合はプログラムが置かれたフォルダに myfile.txtが作られる。 ファイル名にはドライブ名,フォルダ名も記述できる。 |
PrintWriter mywriter = new PrintWriter("myfile.txt"); 初期値を持つ変数の宣言あるいは配列の宣言に似ている と考えておこう。 例えば次のx,aryは変数名であった。 int x= 100; int[] ary= new int[100] この変数名のところがmywriterになっていると考えよう。 種明かしは「クラス」のところで。 |
2.書きたいことはここでprintfで書く。 いくらでも書ける。 print,printlnも使える。 |
mywriter.printf(fp,"Hello. How are
you?\n"); mywriter.printf(fp,"Fine, thanks. And You?\n"); mywriter.printf(fp,"So so.\n"); |
3.書くことがなくなったらファイルをクローズする。 クローズしてしまったらもう書けない。 |
mywriter.close(); |
ファイル出力時の改行に関する補足
OSによってファイル内の改行コードが異なっている。
UNIXOS系 : \n (0x0a) WindowsOS : \r\n (0x0d,0x0a)
(B)のプログラムは,UNIX系のOSに対応した改行のプログラムである。
厳密にはWindowsOSに対応していないことになる。しかしエディタによってはそのまま読めたり,改行コードを変換して
再保存できたりするものもあるので,当面は気にしないことにする。
もし,windowsに対応するなら次の例のように変更すればよい。
mywriter.printf("Hello. How are you?\r\n");
ファイル名を実行時に決めることも出来る。次の例は出力ファイル名を実行時に決め,1000までの素数を書き出すものである。
List7.1.2 素数表(1000まで)のファイル出力 |
import java.util.*; // StringTokenizer /*****************コンソール出力******************** |
書き出された「primenumber.txt」 |
1000 までの素数 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 素数は168個見つかりました。 |
課題7 その1 |
---|
(1)x,x2,x3の表を1≦x≦100でファイル出力するプログラムを作りなさい。
(p07ex01.java)
出力されたファイルの内容を実行結果として扱いなさい。
x x^2 x^3
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
: : :
7.2 テキストファイルの構造 |
---|
ABCD EDG HIJKLMN |
ABCD[改行]EDG[改行]HIJKLMN[改行] |
のように一列の文字列で構成されている。
文字コードの説明は「A.変数 (A.4 文字コード) (APPENDIX 2 文字コードに関する補足)」を参照のこと
kskdump.exeで見たファイルの内容表示([改行]は0d 0aで保存されているのがわかる)
kskdump.exeのダウンロード先
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdef 0000000 :
0000010 :41 42 43 44 0d 0a 45 44 47 0d 0a 48 49 4a 4b 4c
4d 4e 0d 0aABCD..EDG..HIJKL
MN..
同様に
ABCD EDG HIJKLMN |
ABCD[改行]EDG[改行]HIJKLMN |
のように最後の改行がない場合もある。この場合には次のようなファイルになっている。
kskdump.exeで見たファイルの内容表示([改行]は0d 0aで保存されているのがわかる)
kskdump.exeのダウンロード先
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdef 0000000 :
0000010 :41 42 43 44 0d 0a 45 44 47 0d 0a 48 49 4a 4b 4c
4d 4eABCD..EDG..HIJKL
MN
また,エディタで作成した
public class Hello { public static void main(String[] args) { Hello mainprg = new Hello(); } Hello() { System.out.println("Hello. How are you?"); System.out.println("Fine, thanks. And You?"); System.out.println("So so."); } } |
public class Hello {[改行]
public static void main(String[] args) {[改行] Hello mainprg = new Hello();[改行] }[改行][改行] Hello() {[改行] System.out.println("Hello. How are you?");[改行] System.out.println("Fine, thanks. And You?");[改行] System.out.println("So so.");[改行] }[改行] }[改行] |
のように一列の文字列で構成されている。
kskdump.exeで見たファイルの内容表示([改行]は0d 0aで保存されているのがわかる)
kskdump.exeのダウンロード先
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f
0123456789abcdef 0000000 :
0000010 :
0000020 :
0000030 :
0000040 :
0000050 :
0000060 :
0000070 :
0000080 :
0000090 :
00000a0 :
00000b0 :
00000c0 :
00000d0 :
00000e0 :
00000f0 :
0000100 :
0000110 :
70 75 62 6c 69 63 20 63 6c 61 73 73 20 48 65 6c
6c 6f 20 7b 0d 0a 20 20 20 20 70 75 62 6c 69 63
20 73 74 61 74 69 63 20 76 6f 69 64 20 6d 61 69
6e 28 53 74 72 69 6e 67 5b 5d 20 61 72 67 73 29
20 7b 0d 0a 20 20 20 20 20 20 20 20 48 65 6c 6c
6f 20 6d 61 69 6e 70 72 67 20 3d 20 6e 65 77 20
48 65 6c 6c 6f 28 29 3b 0d 0a 20 20 20 20 7d 0d
0a 20 0d 0a 20 20 20 20 48 65 6c 6c 6f 28 29 20
7b 0d 0a 20 20 20 20 20 20 20 20 53 79 73 74 65
6d 2e 6f 75 74 2e 70 72 69 6e 74 6c 6e 28 22 48
65 6c 6c 6f 2e 20 48 6f 77 20 61 72 65 20 79 6f
75 3f 22 29 3b 0d 0a 20 20 20 20 20 20 20 20 53
79 73 74 65 6d 2e 6f 75 74 2e 70 72 69 6e 74 6c
6e 28 22 46 69 6e 65 2c 20 74 68 61 6e 6b 73 2e
20 41 6e 64 20 59 6f 75 3f 22 29 3b 0d 0a 20 20
20 20 20 20 20 20 53 79 73 74 65 6d 2e 6f 75 74
2e 70 72 69 6e 74 6c 6e 28 22 53 6f 20 73 6f 2e
22 29 3b 0d 0a 20 20 20 20 7d 0d 0a 7d
public class Hel
lo {.. public
static void mai
n(String[] args)
{.. Hell
o mainprg = new
Hello();.. }.
. .. Hello()
{.. Syste
m.out.println("H
ello. How are yo
u?");.. S
ystem.out.printl
n("Fine, thanks.
And You?");..
System.out
.println("So so.
");.. }..}
7.3 テキストファイルの文字単位処理 |
---|
例1 |
テキストファイルから1文字読み込みで,ファイルの先頭の10文字を読み込み,画面に書き出すプログラム
ファイルから1文字ずつ読みだす場合は,FileReaderのread()を用いる。読み出し準備に2つの作業が必要である。
読み込み対象ファイル「Peter.txt」 |
Peter ran straight away to Mr. McGregor's garden, and squeezed under the gate! First he ate some French beans; and then he ate some radishes. |
List 7.3.1 テキストファイルから1文字読み込みで,先頭10文字を読み込み,画面に書き出すプログラム |
import java.io.*; // FileReader |
実行結果(画面表示)「Peter ran 」までが読み込まれ表示されている。 |
0文字目 [P( 80 50H)] 1文字目 [e(101 65H)] 2文字目 [t(116 74H)] 3文字目 [e(101 65H)] 4文字目 [r(114 72H)] 5文字目 [ ( 32 20H)] 6文字目 [r(114 72H)] 7文字目 [a( 97 61H)] 8文字目 [n(110 6eH)] 9文字目 [ ( 32 20H)] |
例2 |
List 7.3.2
テキストファイルのコピー(1文字入力1文字出力) | ||||
import java.io.*; // FileReader
myfilereader.close(); /*閉じる*/
|
式が値を持つことを利用するとwhileの部分をスマートに記述できる。 |
例3 |
List 7.3.3
テキストファイルの小文字大文字変換(1文字入力1文字出力) |
もし,ファイル内のアルファベットをすべて小文字にしたかったら |
例4 |
List 7.3.4 ソースファイルの暗号化 | ||||
import java.io.*; // FileReader | ||||
=====================暗号化の際のコンソール画面の様子=====================
| ||||
=====================復号化の際のコンソール画面の様子===================== 読み込みファイル名 : Hello.txt 書き出しファイル名 : result.txt (1)暗号にする (2)復号する ( 1 or 2 ) :2
|
7.4 テキストファイルの行単位処理 |
---|
例1 |
List 7.4.1 テキストファイルから1行ずつ読み込んで最初の3行を表示する |
import java.io.*; // FileReader |
実行結果(画面表示) |
0行目 [Peter ran straight away to Mr. McGregor's garden,] 1行目 [and squeezed under the gate!] 2行目 [First he ate some French beans;] |
List 7.4.1-A
テキストファイルから1行ずつ読み込んで最初の3行を表示する 別表現(ファイルのオープン作業を1行で表した。myFreaderの宣言を省略した) |
import java.io.*; // FileReader |
実行結果(画面表示) |
0行目 [Peter ran straight away to Mr. McGregor's garden,] 1行目 [and squeezed under the gate!] 2行目 [First he ate some French beans;] |
例2 |
List 7.4.2
プログラムソースファイルを読み込んで,行頭に行番号をつけて,テキストファイルに書き出す。 | ||||
import java.io.*; // FileReader
|
課題7 その2 |
---|
(2)ソースプログラムファイルを読み込み,何行で構成されていたか,何文字(リターンコードなどの
制御コードも含む)で構成されていたかをカウントするプログラムを作成しなさい。なお,検査対象ソースプログラムファイル名は,実行時にキーボードから読み込むものとする。出力はコンソール画面とする。(ファイルの最終文字がリターンコードである場合,ない場合に対応しているかどうか確認すること)
(p07ex02.java)
厄介なヒント 行数を数える場合,「'\n'」を数えればよいと思いますか?
ファイルによっては最終行の終わりに,「'\n'」が付いていないものもあります。
提出実行結果は,ソースファイルの内容および画面表示とします。
(3)ソースプログラムファイルを読み込み,行ごとに,逆順ならびにして,別のファイル名で保存しなさい。なお,ソースプログラムファイル名は,実行時にキーボードから読み込むものとする。逆順ならびとは次のようなものである。(p07ex03.java)
提出実行結果は,出力されたファイルの内容とします。
public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}
が
のようになる。{ olleH ssalc cilbup
{ )sgra ][gnirtS(niam diov citats cilbup
;)(olleH wen = grpniam olleH
}
{ )(olleH
;)"?uoy era woH .olleH"(nltnirp.tuo.metsyS
;)"?uoY dnA .sknaht ,eniF"(nltnirp.tuo.metsyS
;)".os oS"(nltnirp.tuo.metsyS
}
}
プログラミングにおいてメソッドのところで作成したprivate String strcpyrvs(String str)を用いなさい。
private String strcpyrvs(String str)は与えられた文字列sを逆順にして返すメソッドであった。
なお,実行の検査には次のファイルHello.javaを用いなさい。
(4)入力ファイル中の単語を抜き出し出力ファイルへ書き出すプログラムを作成しなさい。単語とはアル ファベットで始まり,アルファベットと数字とアンダーバー(_)のみでできている文字列である。単語の書き出しにおいては,単語ごとにスペースで区切っ て,8つごとに改行するものとする.例えば何かのプログラムを入力ファイルとした時,次のようなファイルができるでしょう。なお,ファイル名は,実行時に キーボードから読み込むものとす る。 (p07ex04.java)
Hello.java public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}
参考 Cプログラム(単語を抜き出して画面に表示している。課題とは異なる) public class Hello {
Hello.javaを抜き出した結果は次のようになる。
Hello.java
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}
抜き出した結果
public class Hello public static void main String
args Hello mainprg new Hello Hello System out
println Hello How are you System out println
Fine thanks And You System out println So
so
次のファイルについて検証しなさい。(12qwe は数字で始まるため単語ではないので抽出されてはならない)
test.txt 1234 ..wer qwe123+wer456
sw_qwe,q12_12,12qwe,A123B123
wsed_123
hello.javaを使って動作を動作を検証しなさい。
Hello.java public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}次のような結果が得られれば正解 public 2
class 1
Hello 5
static 1
void 1
main 1
String 1
args 1
mainprg 1
new 1
System 3
out 3
println 3
How 1
are 1
you 1
Fine 1
thanks 1
And 1
You 1
So 1
so 1
7.5 ファイルからの数値データの読み込み |
---|
複数の値が記述された文字列から数値を切り出す方法がわかったので,数値データの記述されたファイルから数値データを読み込んでみよう。
List7.5.1 数値が記述されている文字列から数値を読み取る import java.io.*; // BufferedReader
public class XXXX {
public static void main(String[] args) {
XXXX mainprg = new XXXX();
}
XXXX() {
int i,num;
int[] data= new int[3];
String str="128, 256, 512";
System.out.printf("%s\n",str);
/*文字列strを「,」で区切って複数の文字列に分解し,文字列配列に保存する*/
String[] strary=str.split(",");
num=strary.length;
/*取り出した文字列の個数表示*/
System.out.printf("num=%d\n",num);
for (i=0; i<num; i++) {
System.out.printf("strary[%d] [%s]\n",i,strary[i]);
}
for (i=0; i<num; i++) {
/*文字列の前後にあるスペース文字を取り除く*/
strary[i]=strary[i].trim();
}
for (i=0; i<num; i++) {
System.out.printf("strary[%d] [%s]\n",i,strary[i]);
}
for (i=0; i<num; i++) {
try {
/*数字文字列を整数値に変換してint型配列に保存*/
data[i] = Integer.valueOf(strary[i]).intValue();
}
catch(Exception e) {
System.out.println("Conversion Error");
System.exit(1);
}
}
for (i=0; i<num; i++) {
System.out.printf("data[%d] %d\n",i,data[i]);
}
}
}
/*****実行結果************
128, 256, 512
num=3
strary[0] [128]
strary[1] [ 256]
strary[2] [ 512]
strary[0] [128]
strary[1] [256]
strary[2] [512]
data[0] 128
data[1] 256
data[2] 512
**************************/
mydata.txt 128, 256, 512
次の例題として,複数の学生(100人未満)の英語・数学・国語のテストの点(0~100)の処理を考えよう。学生番号を0~9とし,英語・数学・国語の科目 番号を0,1,2とする。科目ごとの平均と各学生の3科目合計点を求める事にする。例えば,学生番号4の英語・数学・国語の得点をscore[4] [0],score[4][1],score[4][2]とし,合計点はscore[4][3]にしまうことにする。下に示す得点ファイルから読み込むこととする。人数はプログラミング時点では不明で,得点ファイルにデータが存在するだけの人数がいることにする。
List7.5.2 ファイルからの数値データ読み込み
import java.io.*; // BufferedReader
public class XXXX {
public static void main(String[] args) {
XXXX mainprg = new XXXX();
}
XXXX() {
int i,num=0;
int[] data= new int[3];
String str;
try {
FileReader myFreader = new FileReader("mydata.txt"); //ファイル読み出し準備
BufferedReader myBreader = new BufferedReader(myFreader); //ファイル読み出し準備
/*ファイル先頭の1行を読み込む*/
str=myBreader.readLine();
System.out.printf("%s\n",str);
String[] strary=str.split(",");
num=strary.length;
for (i=0; i<num; i++) {
strary[i]=strary[i].trim();
data[i] = Integer.valueOf(strary[i]).intValue();
}
myBreader.close(); //閉じる(準備の逆順)
myFreader.close(); //閉じる
} catch (Exception e) {
System.out.println(e);
}
for (i=0; i<num; i++) {
System.out.printf("data[%d] %d\n",i,data[i]);
}
}
}
/*****実行結果************
128, 256, 512
data[0] 128
data[1] 256
data[2] 512
**************************/
List7.5.3 ファイル中の成績データの処理 import java.io.*; // BufferedReader
public class XXXX {
public static void main(String[] args) {
XXXX mainprg = new XXXX();
}
XXXX() {
int[][] score= new int[100][4];
int i,j;
int num=0,numStudents=0;;
String str;
try {
FileReader myFreader = new FileReader("mydata2.txt"); //ファイル読み出し準備
BufferedReader myBreader = new BufferedReader(myFreader); //ファイル読み出し準備
str=myBreader.readLine();
while (str!=null) {
System.out.printf("%s\n",str);
String[] strary=str.split(",");
num=strary.length;
for (i=0; i<num; i++) {
strary[i]=strary[i].trim();
score[numStudents][i] = Integer.valueOf(strary[i]).intValue();
}
numStudents++;
str=myBreader.readLine();
}
myBreader.close(); //閉じる(準備の逆順)
myFreader.close(); //閉じる
} catch (Exception e) {
System.out.println(e);
}
int[] sum= new int[4];
double[] average=new double[4]; /*英・数・国・(合計)の順の平均値*/
for (i=0;i<numStudents;i++) {
score[i][3]=0;
for (j=0;j<3;j++) {
score[i][3]+=score[i][j];
}
}
for (j=0;j<4;j++) {
sum[j]=0;
for (i=0;i<numStudents;i++) {
sum[j]+=score[i][j];
}
average[j]=sum[j]/(double)numStudents;
}
System.out.printf("学生番号 英語 数学 国語 合計\n");
for (i=0;i<numStudents;i++) {
System.out.printf("%6d %3d %3d %3d %3d\n",
i+1,score[i][0],score[i][1],score[i][2],score[i][3]);
}
System.out.printf(" 平均 %.1f %.1f %.1f %.1f\n",
average[0],average[1],average[2],average[3]);
}
}
テキストファイルmydata2.txt (実行前に作っておく) 86, 75, 60
75, 68, 81
84, 98,100
87, 76, 48
82, 58, 73
100, 87, 98
64, 72, 70
87, 68, 99
98, 87, 68
87, 72, 84実行時のコンソール出力 86, 75, 60
75, 68, 81
84, 98,100
87, 76, 48
82, 58, 73
100, 87, 98
64, 72, 70
87, 68, 99
98, 87, 68
87, 72, 84
学生番号 英語 数学 国語 合計
0 86 75 60 221
1 75 68 81 224
2 84 98 100 282
3 87 76 48 211
4 82 58 73 213
5 100 87 98 285
6 64 72 70 206
7 87 68 99 254
8 98 87 68 253
9 87 72 84 243
平均 85.0 76.1 78.1 239.2
課題7 その3 |
---|
(6)次の枠内は,あるクラスの英語,数学,理科,国語の試験の得点一覧である。テキストエディタにコ
ピー&ペーストして,marks.txtというファイルを作成しなさい。次に,このファイルを読み込み,各科目の平均点,学生ごとの総点,総点の平均を求め,新たに一覧表ファイルmarks1.txtを作成するプログラムを作成しなさい。(p07ex06.java)
出力されたファイルの内容を実行結果として扱いなさい。
70, 59, 56,
66 100, 100, 100, 100 68, 90, 96, 94 79, 92, 85, 75 64, 66, 72, 50 100, 100, 100, 100 81, 92, 86, 97 95, 88, 88, 79 78, 74, 75, 74 75, 80, 92, 75 87, 76, 77, 63 90, 90, 99, 100 68, 68, 67, 75 66, 66, 69, 71 71, 69, 73, 80 98, 81, 98, 97 100, 100, 100, 100 91, 100, 94, 92 89, 87, 73, 68 89, 100, 100, 94 21, 27, 26, 25 100, 100, 100, 100 36, 53, 32, 31 97, 74, 72, 85 86, 85, 81, 79 75, 71, 63, 72 88, 94, 87, 84 62, 68, 72, 60 62, 68, 62, 70 92, 88, 86, 70 57, 64, 69, 64 55, 77, 51, 73 58, 74, 80, 71 97, 91, 79, 100 69, 58, 72, 69 38, 54, 35, 19 31, 23, 34, 37 94, 85, 71, 63 64, 90, 71, 73 55, 51, 50, 48 97, 100, 100, 100 87, 83, 100, 85 |
7.6 コマンドラインの取り込み |
---|
UNIXのコンソール,Windowsのコマンドプロンプト,Windowsのファイルのドロップに対応した内容
興味があったらここを読むこと
興味があったらここを読むこと |
7.7 バイナリファイルの処理 |
---|
テキストファイルは文字コードと改行などの制御コードで出来ている。そのためエディタと呼ばれる種類のアプリケーションで内容を見たり,変更することが容易である。
これに対して,画像やサウンドを保存するファイルは,データのコンピュータ内部表現をそのまま保存しているファイルである。
例えば音を表現する時は,1/8000秒ごとの8ビットの数値の連続で音の波形データを表わすことがある。
例えば,グラフで音の波形を表すと次のようになるが,
これを数値であらわすと,
0,31,56,68,66,50,25,-2,-24,-36,-33,-16,11,41,68,86,89,77,53,23,-6,-27,-36,-31,-12,13,40,....
の
ようになる。データをこのままテキストファイルとして保存してもよいが,1ポイントあたり4文字程度(4バイト)必要となる。しかし,各データは8ビット
であることが約束されているため,コンピュータ内部表現では,1バイトである。これをそのまま保存すると1ポイントあたり1バイトとなり,テキストファイ
ルで保存するのに比べ1/4のサイズのファイルとなる。
(実際のサウンドファイルや画像ファイルではファイルサイズを小さくするための工夫がなされ,ファイルの先頭にはヘッダーブロックと呼ばれる必要な一連のデータが保存されている部分がある。)
テキストファイルとバイナリファイルの書き出しと読み込みを比較してみよう。
テキストファイルの書き出しと読み込み | バイナリファイルの書き出しと読み込み |
/*テキストファイル"sample.txt"の書き出し*/ |
/*バイナリファイル"sample.bin"の書き出し*/ |
説明 byte型変数は8bit,値の範囲は-128~127 |
説明 Fstream.write(data,0,num)はbyte配列dataの第0要素からnum個出力する |
/*テキストファイル"sample.txt"の読み込み*/ |
/*バイナリファイル"sample.bin"の読み込み*/ |
説明 num=Fstream.read(data); は,byte配列dataにファイルからbyteデータを読み込み, numには読み込んだbyte数を保存する。 | |
Windows
PCでの テキストファイル"sample.txt"の内容 |
Windows
PCでの バイナリファイル"sample.bin"の内容 |
sample.txt +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 00 : 31 32 30 0a 32 33 0a 31 30 32 0a 2d 31 32 30 0a 10 : 2d 39 34 0a 35 0a 39 38 0a 2d 31 30 30 0a 31 30 20 : 39 0a 32 33 0a 31 31 37 0a 31 32 32 0a 2d 31 31 30 : 32 0a 32 33 0a 31 31 0a 2d 32 32 0a 31 32 30 0a 40 : 31 32 33 0a 2d 31 31 0a 31 30 30 0a 0123456789abcdef 00 : 120.23.102.-120. 10 : -94.5.98.-100.10 20 : 9.23.117.122.-11 30 : 2.23.11.-22.120. 40 : 123.-11.100. |
sample.bin +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0000000 : 78 17 66 88 a2 05 62 9c 6d 17 75 7a 90 17 0b ea 0000010 : 78 7b f5 64 0123456789abcdef 0000000 : x.f...b.m.uz.... 0000010 : x{.d |
説明 (UNIXでは'\r'がない) |
説明 |
7.8 ファイル操作のまとめ |
---|
Javaには様々なファイル操作の方法(クラスライブラリ)が用意されている。基本的には
○○reader(読み込み,ファイル入力)と○○writer(書き込み,ファイル出力)という名前である。ここでは代表的な
Reader,Writerを紹介してきたのでまとめておく。
ここに取り上げた方法以外にも特徴を持ったreaderやwriterがあるので,自分で調べて用途に適したものをりようするとよい。
ファイルからの読み込み
(ファイル入力)
ファイルへの書き込み
(ファイル出力)
テキストファイル 文字単位の操作
FileReaderのread() PrintWriterのprintfなど テキストファイル 行単位の操作 FileReader BufferedReaderのreadLine() PrintWriterのprintfなど テキストファイル 数値データの操作 FileReader BufferedReaderのreadLine()
Stringのsplit()
PrintWriterのprintfなど バイナリファイル
FileInputStreamのread() FileOutputStreamのwrite()
課題7 |
---|
(1)x,x2,x3の表を1≦x≦100でファイル出力するプログラムを作りなさい。 (p07ex01.java)
(再掲)
出力されたファイルの内容を実行結果として扱いなさい。
x x^2 x^3
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
: : :
(2)ソースプログラムファイルを読み込み,何行で構成されていたか,何文字(リターンコードなどの
制御コードも含む)で構成されていたかをカウントするプログラムを作成しなさい。なお,検査対象ソースプログラムファイル名は,実行時にキーボードから読み込むものとする。出力はコンソール画面とする。(ファイルの最終文字がリターンコードである場合,ない場合に対応しているかどうか確認すること)
(p07ex02.java)
厄介なヒント 行数を数える場合,「'\n'」を数えればよいと思いますか?
ファイルによっては最終行の終わりに,「'\n'」が付いていないものもあります。
提出実行結果は,ソースファイルの内容および画面表示とします。
(3)ソースプログラムファイルを読み込み,行ごとに,逆順ならびにして,別のファイル名で保存しなさい。なお,ソースプログラムファイル名は,実行時にキーボードから読み込むものとする。逆順ならびとは次のようなものである。(p07ex03.java)
提出実行結果は,出力されたファイルの内容とします。
public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}
が
のようになる。{ olleH ssalc cilbup
{ )sgra ][gnirtS(niam diov citats cilbup
;)(olleH wen = grpniam olleH
}
{ )(olleH
;)"?uoy era woH .olleH"(nltnirp.tuo.metsyS
;)"?uoY dnA .sknaht ,eniF"(nltnirp.tuo.metsyS
;)".os oS"(nltnirp.tuo.metsyS
}
}
プログラミングにおいてメソッドのところで作成したprivate String strcpyrvs(String str)を用いなさい。
private String strcpyrvs(String str)は与えられた文字列sを逆順にして返すメソッドであった。
なお,実行の検査には次のファイルHello.javaを用いなさい。
(4)入力ファイル中の単語を抜き出し出力ファイルへ書き出すプログラムを作成しなさい。単語とはアル ファベットで始まり,アルファベットと数字とアンダーバー(_)のみでできている文字列である。単語の書き出しにおいては,単語ごとにスペースで区切っ て,8つごとに改行するものとする.例えば何かのプログラムを入力ファイルとした時,次のようなファイルができるでしょう。なお,ファイル名は,実行時に キーボードから読み込むものとす る。 (p07ex04.java)
Hello.java public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}
参考 Cプログラム(単語を抜き出して画面に表示している。課題とは異なる)
Hello.javaを抜き出した結果は次のようになる。
Hello.java |
public class Hello { |
抜き出した結果 |
public class Hello public static void main String args Hello mainprg new Hello Hello System out println Hello How are you System out println Fine thanks And You System out println So so |
次のファイルについて検証しなさい。(12qwe は数字で始まるため単語ではないので抽出されてはならない)
test.txt 1234 ..wer qwe123+wer456
sw_qwe,q12_12,12qwe,A123B123
wsed_123
hello.javaを使って動作を動作を検証しなさい。
Hello.java public class Hello {
public static void main(String[] args) {
Hello mainprg = new Hello();
}
Hello() {
System.out.println("Hello. How are you?");
System.out.println("Fine, thanks. And You?");
System.out.println("So so.");
}
}次のような結果が得られれば正解 public 2
class 1
Hello 5
static 1
void 1
main 1
String 1
args 1
mainprg 1
new 1
System 3
out 3
println 3
How 1
are 1
you 1
Fine 1
thanks 1
And 1
You 1
So 1
so 1
(6)次の枠内は,あるクラスの英語,数学,理科,国語の試験の得点一覧である。テキストエディタにコ
ピー&ペーストして,marks.txtというファイルを作成しなさい。次に,このファイルを読み込み,各科目の平均点,学生ごとの総点,総点の平均を求め,新たに一覧表ファイルmarks1.txtを作成するプログラムを作成しなさい。(p07ex06.java)
出力されたファイルの内容を実行結果として扱いなさい。
70, 59, 56,
66 100, 100, 100, 100 68, 90, 96, 94 79, 92, 85, 75 64, 66, 72, 50 100, 100, 100, 100 81, 92, 86, 97 95, 88, 88, 79 78, 74, 75, 74 75, 80, 92, 75 87, 76, 77, 63 90, 90, 99, 100 68, 68, 67, 75 66, 66, 69, 71 71, 69, 73, 80 98, 81, 98, 97 100, 100, 100, 100 91, 100, 94, 92 89, 87, 73, 68 89, 100, 100, 94 21, 27, 26, 25 100, 100, 100, 100 36, 53, 32, 31 97, 74, 72, 85 86, 85, 81, 79 75, 71, 63, 72 88, 94, 87, 84 62, 68, 72, 60 62, 68, 62, 70 92, 88, 86, 70 57, 64, 69, 64 55, 77, 51, 73 58, 74, 80, 71 97, 91, 79, 100 69, 58, 72, 69 38, 54, 35, 19 31, 23, 34, 37 94, 85, 71, 63 64, 90, 71, 73 55, 51, 50, 48 97, 100, 100, 100 87, 83, 100, 85 |