プロが教えるわが家の防犯対策術!

ただいまjavaを勉強中で、RandomAccessFileでいろいろやってみているところです。

RandomAccessFileで文字列を読み書きするときは
readUTF() と writeUTF() を使うってことでいいんでしょうか?
そう思って今やっているのですが、うまくいかないことがあります。

writeUTF() で文字列をいくつか書き込んで、
後で任意の位置の文字列を書き換えようとしています。

で、まず、いくつデータを書き込んだのか調べるために、
readUTF() とカウンタを使って数えようと思ったんですが、
繰り返しの最中にファイルの末尾に達してしまい、終了してしまいます。

さっきまではそれで数えられていた気がしたんですが、
ちょっとどこかをいじった後、できなくなってしまいました。

上書きについては、元のファイルの、任意の位置の手前までデータを読み込んでファイルポインタを進めて
その後上書きしたいデータを書き込むようにしました。

全体的によろしくないやり方でしたら、そのあたりも指摘していただけるとうれしいです。
どうぞよろしくお願いします。

A 回答 (3件)

どこで例外が発生しているかは確認しましたか?



(a) while(ra.getFilePointer() < ra.length()) { ... }のループでファイルの終わりまで読む
(b) for(i = 0; i < (number * 2); i++) { ... }のループで書き換える位置の前まで読む
(c) 書き換えるデータをwriteUTF() 2回で書く
(d) for(i = cnt; i < datacnt; i++) { ... }のループで書き換えない残りのデータを書く

という手順になっていますが、(a)でファイルの終わりまで読み終わっているので、(b)でその続きを読もうとすると例外が発生するのは当然です。
(a)と(b)の間でファイルポインタをファイルの先頭に戻す必要があります。ファイルを一度クローズしてからオープンし直すか、seek(0L)を呼んでください。

ANo.1で「writeUTF()で書き出されたデータは任意の位置の文字列を書き換えるのには向きません」と書いたのは、たとえばファイルの中の「あいうえお」という文字列の一部だけを書き換えて「あい☆□○♪えお」にするようなことを想定していました。そのような使い方にreadUTF()/writeUTF()が向かないのは確かです。
補足に書いていただいたような使い方ならreadUTF()/writeUTF()でも問題ないと思います。
    • good
    • 0
この回答へのお礼

再び回答ありがとうございます。

まさに、(a)と(b)の間で例外が起こっていました。
ファイルポインタをファイルの先頭に戻したら、ちゃんと書き換えてくれました。

すごいケアレスミスに気づかず、本当に申し訳ありません……。

とても助かりました。
ありがとうございました。

お礼日時:2011/06/30 23:08

> readUTF() と writeUTF() を使うってことでいいんでしょうか


いえ、普通にwriteやreadでもOKです。
書き込もうとするデータ用にいろいろ用意されているので
適切なものをどうぞ。

> readUTF() とカウンタを使って数えようと思ったんですが、
> 繰り返しの最中にファイルの末尾に達してしまい、終了してしまいます。
ずっとファイルを読んでいけば
そのうち末尾に到達します。
当たり前です。

> で、まず、いくつデータを書き込んだのか調べるために、
いくつ、というのは今までに何バイトのデータをファイルに出力したのか
っていう意味でしょうか?
それともwriteUTFを実行した数ですか?
ファイルにはwriteUTFを実行した情報は書き込まれていないので
writeUTFをするときに自前でカウントしない限り判断できません。

いまいち状況が分からなくて
こちらとしても何を聞き返していいのか・・・。
もう少し情報をお願いします。

この回答への補足

回答ありがとうございます。

No.1の方の解答の補足にも書きましたが、
いくつデータを~というのは、writeUTFを実行した回数です。
forを使ってwriteUTFを実行して、forを抜けた後、カウンタを変数に保存しました。

ファイルを最後まで読み込むと、EOFExceptionで、catchに飛んでしまいますよね。
そうならないように、ファイルを全部読み込むことはできないんでしょうか?
もしかして、catchからtryの中に戻ってくることができるんでしょうか。

No.1の方が提案してくれた、
read(byte[] b)やwrite(byte[] b)についていろいろ調べたんですが、
世の中では常識なのか、これについて説明してくれるところはまだ見つかりません。
どう使うのか、どうしてこれを使うのか、よくわからないままです。

情報が足りなくてすみません。
まだ足りなかったらもっとすみません。

補足日時:2011/06/30 10:06
    • good
    • 0

どのような書き換えをしたいのか、どんなコードを書いたのか、補足に貼ってください。



> RandomAccessFileで文字列を読み書きするときは
> readUTF() と writeUTF() を使うってことでいいんでしょうか?

writeUTF()で書き出されたデータは任意の位置の文字列を書き換えるのには向きません。
read(byte[])とwrite(byte[])を使ってbyteの配列を読み書きするほうが汎用性は高いでしょう。

> いくつデータを書き込んだのか調べるために、
> readUTF() とカウンタを使って数えようと思ったんですが、

数えているのは文字数ですか、それともバイト数ですか? その両者を区別しないと期待した結果は得られないと思います。

この回答への補足

回答ありがとうございます。
やりたいのは、名前と電話番号を読み書きすることです。
数えたいのは、名前と電話番号が何セットあるかということです。
書いたコードです。

String name = "ドラえもん";
String pnumber = "090-1111-1111";

RandomAccessFile ra = new RandomAccessFile(fname, "rw");

while(ra.getFilePointer() < ra.length()) {
data[i] = ra.readUTF();
i++;
}
int datacnt = i;
System.out.println("データの数:" + (datacnt / 2));

int number = 2;//書き換える位置
int cnt = 0;
for(i = 0; i < (number * 2); i++) {
ra.readUTF();
cnt++;
}
ra.writeUTF(name);
cnt++;
ra.writeUTF(pnumber);
cnt++;

for(i = cnt; i < datacnt; i++) {
ra.writeUTF(data[i]);
}

勉強がぜんぜん足りてないからなんでしょうが、
こうする以外に思いつきません。
すみませんがよろしくお願いします。

補足日時:2011/06/30 03:43
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!