Java:为什么未关闭的流不会引发异常?

时间:2020-05-13 07:40:00

标签: java property-files

我想写一个属性文件。但是它默默地没起作用。仅从代码行为来看,我无法注意到它。我总是不得不打开属性文件,并查看值是否更改。但是它从来没有。所以实际上我期望得到一个例外。问题似乎是我在打开OutputStream之前没有关闭InputStream。但是我从来不知道这一点。我花了3天的时间,因为我希望OutputStream或store函数能够给我一些反馈。看一下代码。

req.on('data', function (chunk) {
    postData += chunk;
}

2 个答案:

答案 0 :(得分:1)

被遗忘的close()语句不会导致异常。从您的视频流的角度来看,一切正常。它只是还没有写信到目的地。为什么要这样即使整个程序终止,也无法保证流关闭并写出其内部缓冲区。[1]

您始终必须主动致电flush()close()。然后,基础实现将执行实际的写操作。

这个错误非常普遍,以至于还有一个额外的Java功能来处理它。它称为try-with-resources,可防止程序员因丢失close()语句而带来的恶果。

示例:

//use try-with-resources on out
private void saveProperties(Properties properties, String path) {
    try(PrintStream out = new PrintStream(new FileOutputStream(path))) {
        printProperties(properties,out);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
// you can pass System.out as well to print to console
private void printProperties(Properties properties, PrintStream out) {
    try {
        properties.store(out, null);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
//properties.load leaves the stream open, so you have to use try-with-resources
private Properties readProperties(String path) {
    try (FileInputStream in = new FileInputStream(path)) {
        Properties properties = new Properties();
        properties.load(in);
        return properties;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

有关Java属性的帖子:

有关Java Streams的相关文章:

[1]参见:Josh Bloch,《有效的Java》,第2版,第27页。

避免使用终结器。[...]完全有可能甚至终止程序,而对某些不再可访问的对象不执行终结器。

答案 1 :(得分:1)

对于实际的问题“为什么它不会引发异常”,这是因为在某些情况下您希望Stream保持打开状态。

    class FileWriteSample implements Closeable {
        FileOutputStream writeTo;

        public FileWriteSample(String filename) throws IOException {
            writeTo = new FileOutputStream(filename);
            // should we expect an Exception here because we don't close the Stream?
            // we're planning to use it later on
        }
        public void write(String s) {
            // write to stream
        }
        public void close() throws IOException {
            writeTo.close();
        }
    }