Writing /volume1/Web/Public/dokuwiki/data/log/deprecated/2024-11-14.log failed
Writing /volume1/Web/Public/dokuwiki/data/log/deprecated/2024-11-14.log failed

File.delete() problem in Java

今、取り掛かっているプロジェクトでリソースpropertiesファイルの内容を変更するツールを開発している。
主なロジックの流れは次のとおり。

  1. xxx.propertiesのコピーxxx.properties_orgを作成する。
  2. xxx.properties_orgのバックアップfileであるxxx.properties_org_backを作成する。1)
  3. xxx.properties_orgを読込み、変換したい文字列で変換して、xxx.properties_tempファイルで出力する。2)
  4. xxx.properties_orgファイルを削除する。
  5. xxx.properties_tempファイル名をxxx.properties_orgで修正する。(File.renameTo)
  6. xxx.properties_orgファイルからnative2asciiを用いてxxx.propertiesファイルを出力する。3)
  7. 正常に処理が終われば、xxx.properties_orgとxxx.properties_org_backを削除する。 エラーが発生する場合、xxx.properties_orgを削除して、xxx.properteis_org_backを元にnative2asciiを利用しxxx.propertiesで変換する。

最後の処理で理解出来ないことが起こった。xxx.properties_org_backファイルは削除出来るけど、xxx.properties_orgを削除しようとした瞬間、xxx.properteisファイルも一緒に消える妙な現象だ。
普通、こんなこと起こるかよ。と思いながら、真相が突き止めたくて一つの実験をすることにした。

実験(1)

実験は削除するにどのくらい掛かるのかを数えてみた。JDK1.5環境で、ログはlog4jを利用した。

String[] orgPropKey = (String[])orgPropList.keySet().toArray(new String[0]);
for(int j=0; j<orgPropKey.length; j++){
	File orgPropFile = (File)orgPropList.get(orgPropKey[j]);		
 
	boolean flg = false;
	int i = 0;
	do {
	        i++;
 
		flg = orgPropFile.delete();
		if(flg){
		       if(logger.isDebugEnabled()){
			    logger.debug(orgPropFile.getAbsolutePath()+" is deleted!!");
			    logger.debug("count="+i);
			}
		}
	} while (!flg);
 
}//for

その結果、次のテーブルのようにばらばら~

回数12345678910
count11*43511*19813802701*

ここで、asteriskが付いてる時、xxx.proertiesも一緒に削除された。
一緒に削除される原因はまだ定かではないが、いろんな仮説とテストを通じて問題なく、xxx.proerties_orgのみ削除に成功したのが次だ。

解決

先ほどの実験で分かったのがcount=1の場合に問題が起こっていたこと。それで、count=1の場合、削除を禁じる為、xxx.properties_orgファイルを読み取り専用で変更した。

String[] orgPropKey = (String[])orgPropList.keySet().toArray(new String[0]);
for(int j=0; j<orgPropKey.length; j++){
	File orgPropFile = (File)orgPropList.get(orgPropKey[j]);		
 
	boolean flg = false;
	int i = 0;
	do {
		i++;
		if(i==1) {
			if(orgPropFile.setReadOnly()){
				if(logger.isDebugEnabled()) logger.debug("readonly!!");
 
			}
		}
 
		if(logger.isDebugEnabled()) logger.debug("writable :: "+orgPropFile.canWrite());				
		flg = orgPropFile.delete();
		if(flg){
			if(logger.isDebugEnabled()){
				logger.debug(orgPropFile.getAbsolutePath()+" is deleted!!");
				logger.debug("count="+i);
			}
		}
	} while (!flg);
 
}//for

これで実行した結果のログサンプルを紹介する。

[22 5 2008 16:41:17,093] DEBUG (ResourceUpdater.java:87)  - D:\workspace\Trans-xxx\WEB-INF\prop\xxx.properties_org_back is deleted!!
[22 5 2008 16:41:17,093] DEBUG (ResourceUpdater.java:103)  - readonly!!
[22 5 2008 16:41:17,093] DEBUG (ResourceUpdater.java:108)  - writable :: false
[22 5 2008 16:41:17,312] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,312] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,328] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,343] DEBUG (ResourceUpdater.java:108)  - writable :: true
[22 5 2008 16:41:17,343] DEBUG (ResourceUpdater.java:112)  - D:\workspace\Trans-xxx\WEB-INF\prop\xxx.properties_org is deleted!!
[22 5 2008 16:41:17,343] DEBUG (ResourceUpdater.java:113)  - count=11

ちなみにcountの結果は次のようだった。

回数1234567891011121314151617181920
count11192071434834373829111127428611
1)
作業中、エラーが発生する場合、元の状態で戻す為に用意する。
2)
読み込む際、charsetは言語に沿って決める(日本語ならShift-JIS)。
3)
Runtime.getRuntime().exec(“native2ascii -encoding ” + charset + “ ” + sourceFilePath + “ ” + makeFilePath);
ここでsourceFilePathはxxx.properties_org, makeFilePathはxxx.propertiesに該当する。

QR Code
QR Code study:java:file_delete (generated for current page)