- PR -

ファイル出力のエラー処理について

投稿者投稿内容
yuu
会議室デビュー日: 2006/05/25
投稿数: 4
投稿日時: 2006-05-25 22:39
現在、ログを出力するプログラムを作成しているのですが、その時のエラー処理について質問させていただきます。

下記のプログラムで、sleep時にファイルを削除強制的に削除した場合、二度目の
「logFile.write(logStr)」で「IOException」が起こると思ったのですが何も起こらず、
処理を続けそのまま終了したのですが、この場合write()メソッドは「IOException」を
起こさないのでしょうか?
-------
FileWriter logFile = new FileWriter(fileName,true);
/* ログ出力 */
logFile.write(logStr);

Thread thread = new Thread();
thread.sleep(10000);

logFile.write(logStr);
logFile.close();

}catch(IOException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
---------

また、ファイルアクセス時に、他のタスクによりファイルを編集されない(削除・上書きなど)ようにする方法はありますでしょうか?
APIを参考にしたのですが、それらしいコンストラクタやメソッドが見当たりませんでした。

理解が浅く言葉におかしな箇所があるかと思いますが、宜しくお願いいたします。
luckseed
常連さん
会議室デビュー日: 2006/05/23
投稿数: 24
投稿日時: 2006-05-26 09:33
10秒しかありませんが、本当にsleep中に削除してその確認をしましたか?
試しにsleepを下のようなコードに差し替えてみてください。
無限ループになりそうな気がしますよ。
# ちなみに、sleepメソッドはstaticなので、インスタンスを作成しない方がいいです。

File target = new File(fileName);
while(target.exists()) {
Thread.sleep(10000);
}
yuu
会議室デビュー日: 2006/05/25
投稿数: 4
投稿日時: 2006-05-26 10:19
ご返信ありがとうございます。

logFile.write(logStr);

logFile.write(logStr);
logFile.close();
の間に
File target = new File(fileName);
while(target.exists()) {
Thread.sleep(10000);
}
を加えプログラムを起動し、スリープ時に削除を行ったのですが、やはりExceptionは起こりませんでした。
念のため、ループ内とループ外でコンソール上に文字列を出力するようにし確認した為、無限ループは起こっていないと思います。

以上です、宜しくお願いいたします。

unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-05-26 10:38
ちょっと試していないのですが、「削除」はどのようにされましたか?もしも Windows の場合、でたんに「ごみ箱」に入れる操作をすると、API 上はファイルの移動になり、移動先のファイルに書き続けていたかもしれません。まあ、試せばすぐにわかることなのですが。
あと、FileWriter や FileReader は簡易的なクラスなので、なにか本格的に試されるのでしたら、もっと低レベルのクラスで試されたほうが確実でしょう。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
luckseed
常連さん
会議室デビュー日: 2006/05/23
投稿数: 24
投稿日時: 2006-05-26 10:49
無限ループにならないってことは、削除されてるんでしょうねぇ・・・
環境を教えてもらえますか?

WindowsXP SP2+JDK5.0で同様の処理を試そうとしたところ、Windowsに怒られてファイルの削除が出来ませんでした。。。

[ メッセージ編集済み 編集者: luckseed 編集日時 2006-05-26 10:50 ]
yuu
会議室デビュー日: 2006/05/25
投稿数: 4
投稿日時: 2006-05-26 12:07
すいません、環境書かないとは初歩的なミスを・・・(汗
環境は下記の通りです。
OS:HP-UX 11.11
JAVA:Java2 1.4 SDK

削除は「rm」コマンドで行っています。

FileWriterの箇所ですが、
FileOutputStream fos = new FileOutputStream(fileName,true);
OutputStreamWriter fsw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(fsw);
と変更して試していますが、低レベルのクラスってこういうことで合ってますでしょうか?(汗

ちなみに、Windowsで同プログラムを実行させた場合は私の方でも削除は出来ませんでした。

以上です、宜しくお願いいたします。

[ メッセージ編集済み 編集者: yuu 編集日時 2006-05-26 13:05 ]
Ignis Fatuus
会議室デビュー日: 2006/05/26
投稿数: 1
投稿日時: 2006-05-26 13:25
すくなくともUNIXのファイルシステムではファイル名とファイルの実体(データ)は独立した存在です。
あるファイル実体に対して、そのありかを参照する名前を、ディレクトリという名簿ファイルに登録
してあるという感じになっています。

rmコマンド(=unlinkシステムコール)は、対象ファイル名の登録を親ディレクトリから取り除くという
動作をします。もしその結果として、あるファイル実体を指しているファイル名が1つもない状態にな
ると、「ファイルを消した」ことになりますが、その時点でオープンされているファイルディスクリプ
タはそのまま閉じられるまで有効です。
luckseed
常連さん
会議室デビュー日: 2006/05/23
投稿数: 24
投稿日時: 2006-05-26 13:41
Unix環境がないので、実際に試せないのですが。
FileOutputStream.getChannel()で取得したチャネルを使ってみてはどうでしょう。
lockメソッドが効けば、排他できそうですね。

[ メッセージ編集済み 編集者: luckseed 編集日時 2006-05-26 13:42 ]

スキルアップ/キャリアアップ(JOB@IT)