解决,简而言之:问题是我写了一个已经关闭的FileOutputStream
我注意到使用FileOutputStream类的一些奇怪的语义。
如果我使用以下代码创建FileOutputStream:
try {
File astDumpFile = new File(dumpASTPath);
if(!astDumpFile.exists()) {
astDumpFile.createNewFile();
}
astDumpStream = new FileOutputStream(dumpASTPath);
} catch( IOException e ) {
dumpAST = false;
//throw new IOException("Failed to open file for dumping AST: " + dumpASTPath);
System.out.println("Failed to open file for dumping AST: " + dumpASTPath);
}
在程序的开头(astDumpStream
是成员变量)。然后,如果我稍后(约3秒钟)将字符串数据写入文件,我得到一个IOException: stream closed
:
try {
String dotGraph = gpvisitor.getDotGraph();
astDumpStream.write(dotGraph.getBytes("UTF8"));
astDumpStream.flush();
astDumpStream.close();
} catch( IOException e ) {
System.out.println("Failed to dump AST to file: " + e.getMessage());
e.printStackTrace();
}
但是,如果我在写入之前直接复制用于创建FileOutputStream
的精确代码,它将按预期工作。
现在我想知道如果我之前创建该对象,为什么会出现该异常,但如果我在使用它之前直接创建该对象则不会。
编辑:例外:
java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:305)
at MyClass.function(MyClass.java:208)
我刚注意到,即使我得到一个异常,仍有一些数据被写入文件。有趣的是第一行完全写入,然后除了最后一行之外的所有后续行都丢失了。
如果我将写入的字符串dotGraph
替换为更短的内容,则所有内容都写得正确,但是我仍然会遇到异常。
编辑:环境信息:
[~]> lsb_release -a
Distributor ID: Debian
Description: Debian GNU/Linux testing (wheezy)
Release: testing
Codename: wheezy
[~]> java -version
java version "1.7.0_09"
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)
答案 0 :(得分:4)
让IOException
抱怨流已关闭的唯一原因是因为流已关闭。您必须浏览代码以找出发生的位置。一些不太明显的地方包括调用其他方法和finally
try
语句块。要查找的另一件事是将变量astDumpStream
重新分配给不同的流(在IOException
被引发之前关闭 - 可能甚至在第一次分配到astDumpStream
之前)。
除非您有一个单独的线程可能在延迟后关闭流,否则时间似乎并不相关。
答案 1 :(得分:1)
如果close()
函数被多次调用,则会发生这种情况。我的猜测是,出于某种原因,第二块代码被不止一次调用。
为了防止缩进错误,我收到了两条好的建议:
答案 2 :(得分:0)
To Second Tedd - 如果您碰巧使用资源块的嵌套尝试并使用tryblock外部的流 - 您也可以在这种情况下运行,因为一旦控件来自嵌套尝试资源块,流将被关闭。