无法删除由Java Transformer创建的文件

4
我正在以下方式使用Java中的Transformer类 -
1   Transformer transformerFinal = tFactory.newTransformer(new StreamSource(finalStylesheet));
2   transformerFinal.setParameter("Date", sdf.format(myDate));
3   transformerFinal.transform(new StreamSource(tempFilename), new StreamResult(new FileOutputStream(finalFilename)));

然后我想删除用于转换的源文件。

4       File fileToDelete = new File(tempFilename);                    
5       fileToDelete.delete();

它不起作用,我的意思是文件没有被删除。
但如果在第3行传递输出流的本地变量,则会起作用。

1   FileOutputStream fos = new FileOutputStream(finalFilename);
4   transformerFinal.transform(new StreamSource(tempFilename), new StreamResult(fos));
5   fos.close();

现在删除功能已经可以正常工作并且确实可以删除文件。
那么,如果我得出这样的结论:在transform过程中,输出流没有隐式关闭?因此,我必须显式地关闭流。
请问是否有其他原因导致文件无法被删除?
请假设所有变量都具有正确的值。
谢谢。

更新

我注意到另一个问题。
我从另一个类调用此代码,例如 -

public class ClassTwo {
   public void ameth(String tempFilename) {
     // the above mentioned transformation code
   }
}

1   public class ClassOne {
2       public void method1() {
3           ClassTwo ct = new ClassTwo();
4           ct.ameth("tempFilename1");
5           ct.ameth("tempFilename2");
6       }
7   }

在这里,当我没有显式关闭流时,它会删除tempFilename2,但不会删除tempFilename1
有什么想法,为什么会这样?


1
@adarshr:行号会禁用从这里简单复制粘贴代码的功能。 - Paŭlo Ebermann
1个回答

5

你说得对:如果一个文件还在打开状态,是无法删除的。由于Java API中存在一个老的错误,delete()方法无法告诉你原因——它只能返回一个布尔类型的结果。

这种行为的原因是Java不能自动清理除堆内存以外的系统资源。所以我们最终面临的问题是:谁能安全地关闭这个文件呢?也许转换还没有完成,或者你需要在同一流中写入头部和尾部。

因此,如果创建了一个流,必须始终关闭它。


谢谢您的解释。如果我理解正确,您是在说transform()中不关闭流是有意为之的,并且出于安全原因留给用户自行确保。很好。但是,我认为这应该在Java文档中提到。 - Swift-Tuttle
@Swift-Tuttle:它可能在标准的Java I/O API中提到了。由于每个人都这样做,所以没必要一遍又一遍地提到它。 - Aaron Digulla
谢谢。我已经更新了问题,如果可能的话,您能否请评论一下。 - Swift-Tuttle
没有更多的信息很难说。是Linux、Mac还是Windows?在Windows上,也许你在编辑器中打开了文件。是否涉及线程?也许GC运行并收集了锁…… - Aaron Digulla
它在Windows XP上。没有明确的线程涉及,只是一个普通的Java程序。我会四处查找并再次运行,尝试找出是否可以复制。再次感谢。 - Swift-Tuttle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接