- PR -

Streamを閉じたのにファイルが削除できないです。。。

投稿者投稿内容
sumin
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 93
投稿日時: 2005-06-07 15:35
あるファイルの内容を読み込み、Javaプログラムで処理しています。処理自体は問題ないですが、処理が終了してからも該当ファイルの削除がOSレベルで出来ません。WinXPを使っていますが、ファイルを右クリックして削除を選択すると「他の人またはプログラムにより使用されていて削除できません」の警告が出て削除は失敗します。

ファイルは下記のようなソースで読み込んでますし、使用の後は各ストリームをちゃんと閉じていると思いますがなにが問題でしょうかね?

//あるメソッドの中の処理ですが、
XMLInputStreamFactory xsf = XMLInputStreamFactory.newInstance();
istream = xsf.newInputStream(new File(fileName));
if(istream.skip(ElementFactory.createXMLName("ElementType"))){
this.getTableInfo(istream.getSubStream());
}
this.getRecords(istream);
istream.close();

ちなみに、処理自体は問題がなく例外も発生していません。

AC
会議室デビュー日: 2004/04/15
投稿数: 18
投稿日時: 2005-06-07 16:28
コード自体に問題があるかどうかわかりませんがファイルをロックしているプロセスがわかるツールがありますのでそれで確認してみてはどうでしょうか?

Unlocker
http://www.forest.impress.co.jp/article/2005/05/10/unlocker.html
お犬様
ベテラン
会議室デビュー日: 2003/01/26
投稿数: 67
投稿日時: 2005-06-07 16:42
WebLogicを使った事が無いのでわかりませんが、
引用:
this.getTableInfo(istream.getSubStream());

の istream.getSubStream() で取得した XMLInputStream を閉じないと大元の istream が完全に閉じない、とかかもしれません。
sumin
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 93
投稿日時: 2005-06-07 17:26
Unlockerを使って見ました。掴んでいるのはWebLogicのjava.exeでした。Unlockerでロックを解除する事は出来ましたがこれが解決策にはならないですね。
取得したサブストリームももう一回確認しましたが、全部閉じていますが。。。参考としてソースです。


package controls;

import com.bea.control.*;
import java.io.File;
import weblogic.xml.stream.ElementFactory;
import weblogic.xml.stream.XMLEvent;
import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLInputStreamFactory;
import weblogic.xml.stream.XMLStreamException;
import weblogic.xml.stream.StartElement;
import weblogic.xml.stream.XMLName;
import weblogic.xml.stream.Attribute;
import weblogic.xml.stream.AttributeIterator;
import java.util.Iterator;
import java.util.Vector;

public class CtrCsXMLToSQLImpl
{
static final long serialVersionUID = 1L;
private XMLInputStream istream;
private String tableName;
private String[] columnNames;
private String[] columnTypes;



private void getTableInfo(XMLInputStream subStream)throws XMLStreamException{
System.out.println("getTableInfo");
XMLEvent event = subStream.next();
AttributeIterator ite = ((StartElement)event).getAttributesAndNamespaces();
while(ite.hasNext()){
Attribute attribute = ite.next();
if(attribute.getName().getQualifiedName().equals("name")){
tableName = attribute.getValue();
break;
}
}
System.out.println("Table name : " + tableName);
Vector vec = new Vector();
while(subStream.hasNext()){
XMLEvent columnEvent = subStream.next();
if((columnEvent.getType()==XMLEvent.START_ELEMENT) &&
(columnEvent.getName().getQualifiedName().equals("element"))){
String columnName = ((StartElement)columnEvent).getAttributesAndNamespaces().next().getValue();
vec.add(columnName);
System.out.println("Column name " + columnName);
}
}
subStream.close();
columnNames = new String[vec.size()];
for(int i=0; i<vec.size();i++){
columnNames[i] = (String)vec.get(i);
}
System.out.println("COLUMN NAMES :: " + this.columnNames);
// カラムのタイプを求めるロジックが必要
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
}



private void getRecords(XMLInputStream stream)throws XMLStreamException{
System.out.println("getRecords called ");
try{
int executeNumber = 0;
while(stream.hasNext()){
if(50 < executeNumber++) break; // これはテスト目的。後で削除。50件処理後停止
if(stream.skip(ElementFactory.createXMLName(tableName))){
for(int i=0; i<columnNames.length; i++){
if(stream.skip(ElementFactory.createXMLName(columnNames[i]))){
XMLInputStream subStream = stream.getSubStream();
while(subStream.hasNext()){
XMLEvent name = subStream.next();
if(name.getType()==XMLEvent.CHARACTER_DATA){
System.out.println(columnNames[i] + " :: " + name);
}
}
subStream.close();
}
}
System.out.println("=============================================");
}
}
stream.close();
}catch(XMLStreamException e){
e.printStackTrace();
throw e;
}
}



public void convertToSQL(String fileName) throws XMLStreamException
{
XMLInputStreamFactory xsf = XMLInputStreamFactory.newInstance();
istream = xsf.newInputStream(new File(fileName));
if(istream.skip(ElementFactory.createXMLName("ElementType"))){
this.getTableInfo(istream.getSubStream());
}
this.getRecords(istream);
istream.close(); }
}
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-06-07 17:43
>> new File

このオブジェクトを閉じてはいかがでしょうか。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-06-07 18:48
Weblogicのライブラリの実装に問題があるのかも知れませんね…

XMLInputStreamFactory#newInputStream()には、Fileオブジェクトではなくて
InputStreamやReaderをパラメータに取るオーバーライドメソッドがあるよう
なので、例えば

FileInputStream fin = New FileInputStream("...");
XMLInputStream xsf = XMLInputStreamFactory.newInputStream(fin)
//...
fin.close()

なんてことをやってみるとうまくいくかもしれませんね。
#もしこれでうまくいくようなら、ライブラリのバグですのでBEAのサポート
#まで苦情をいれましょう^^;

[ メッセージ編集済み 編集者: シュン 編集日時 2005-06-07 18:48 ]
sumin
ベテラン
会議室デビュー日: 2003/07/17
投稿数: 93
投稿日時: 2005-06-09 15:01
New Fileを明示的に行いそのインスタンスをNullにしてもだめでした。
が、Fileの代わりにFileInputStreamを使ったら上手くロックが解除されました。
うーむ・・。何が違うんでしょうかね?
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-06-09 15:17
あちゃー、見つけちゃいましたね。

XMLInputStream#close()が正しい実装になっていない
(ライブラリの内部で、Fileから生成したFileInputStreamに
対してclose()呼び出しをしていない)ということだと
思いますよ。現象説明してBEAに文句いってください^^;

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