FileOutputStream:Stream已关闭

问题描述 投票:0回答:3

解决,简而言之:问题是我写了一个已经关闭的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();
}

但是,如果我在写入之前直接复制用于创建qazxsw poi的确切代码,它将按预期工作。

现在我想知道如果我之前创建该对象,为什么会出现该异常,但如果我在使用它之前直接创建该对象则不会。

编辑:例外:

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
java file io
3个回答
1
投票

如果[~]> 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) 函数不止一次被调用,那么这种情况就会发生。我的猜测是,出于某种原因,第二块代码被不止一次调用。

为了防止缩进错误,我收到了两条好的建议:

  • 始终缩进。最好使用为您执行此操作的工具(如Eclipse)。
  • 即使您认为不需要花括号,也要使用花括号。这有助于防止一些需要永远查找的小错误,因此输入每个错误需要额外的半秒钟,而不是花费大量时间来查找这些错误。

4
投票

close()抱怨流被关闭的唯一原因是因为流被关闭了。您将需要跟踪代码以找出发生的位置。一些不太明显的地方包括调用其他方法和IOException块的finally语句。要寻找的另一件事是将变量try重新分配到不同的流(在astDumpStream被提升之前关闭 - 可能甚至在第一次分配到IOException之前)。

除非您有一个单独的线程可能会在延迟后关闭流,否则时间似乎不相关。


0
投票

对于Second Tedd - 如果您碰巧使用资源块的嵌套尝试并使用tryblock外部的流 - 您也可以在这种情况下运行,因为一旦控件来自嵌套尝试资源块,流将被关闭。

© www.soinside.com 2019 - 2024. All rights reserved.