[英]Why does this use, in Java, of regular expressions throw an “Unclosed character class” exception at runtime?
[英]Java: Why does an unclosed stream not throw an exception?
我想写入一个属性文件。 但它默默地从来没有奏效。 仅从代码行为中我无法注意到它。 我总是不得不打开属性文件并查看值是否发生了变化。 但它从来没有。 所以实际上我希望得到一个例外。 问题似乎是我在打开 OutputStream 之前没有关闭 InputStream。 但我从来不知道这一点。 我花了 3 天时间,因为我希望 OutputStream 或 store function 能给我一些反馈。 看看代码。
File file = ResourceUtils.getFile("classpath:First.properties");
FileInputStream in = new FileInputStream(file);
Properties props = new Properties();
props.load(in);
System.out.println(props.getProperty("country"));
in.close(); // This I always forgot
FileOutputStream out = new FileOutputStream(file);
props.setProperty("country", "germany");
props.store(out, null);
System.out.println(props.getProperty("country"));
out.close();
忘记的close()
语句不会导致异常。 从您的 stream 的角度来看,一切都很好。 它只是还没有写信给它的目的地。 为什么要呢? 即使整个程序终止,也不能保证 stream 关闭并将其内部缓冲区写出。 [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 页。
避免使用终结器。[...] 完全有可能,甚至很可能,程序在没有对某些不再可访问的对象执行终结器的情况下终止。
至于“为什么它不抛出异常”的实际问题,这是因为您希望 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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.