首页 > 解决方案 > 如何在不刷新的情况下关闭 BufferedWriter?

问题描述

我编写了一个准备 SQL 插入语句并将它们存储在文本文件中的方法。在这一点上它完成了工作,但我有一个完全令人眼花缭乱的捕获块。如果我能以某种方式关闭 BufferedReader 而不会隐式调用 flush 那将是完美的。那可能吗?如果是,如何?

作为为我正在制作的记忆应用程序用汉字(日文字符)数据填充主表的准备工作,我正在制作所有字符的列表。数据源是 KANJIDIC2,一个 UTF-8 编码的 xml 文件,其中包含 13k+ 个字符的数据。最初的想法是在源文件中包含所有字符,但由于某种原因,java.nio.charset.MalformedInputException当我尝试将它们写入我的输出文件时,大约 300 个字符会抛出一个。我决定放弃这些字符,因为它们不是必需的或任何东西,但是在上述异常之后我找不到关闭 BufferedReader 的平滑方法。

File outputFile = new File("C:\\Users\\tobbelobb\\Documents\\kanjilist.bsv");
try {
    BufferedWriter bw = Files.newBufferedWriter(outputFile.toPath(), StandardCharsets.UTF_8);
    for (Kanji nextKanji : kanjiList) {
        try {
            StringBuilder sb = new StringBuilder();
            // sb.append stuff from list of objects...
            bw.write(sb.toString());
            bw.newLine();
            bw.flush();
        } catch (MalformedInputException ex) {
            // Ungracefully swallow the exception.
            ex.printStackTrace();
            bw = Files.newBufferedWriter(outputFile.toPath(), StandardCharsets.UTF_8, StandardOpenOption.APPEND);
        }
    }
    bw.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

我在 catch 块中寻找一种方法来处理我的 BufferedReader 对象,但我唯一能找到的是close(),它再次抛出相同的内容MalformedInputException,并且在此过程中将不完整的文本行写入我的文件。

标签: javabufferedwriter

解决方案


没有这样的事情:https ://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/io/BufferedWriter.java#L258

public void close() throws IOException {
    synchronized (lock) {
        if (out == null) {
            return;
        }
        try {
            flushBuffer();
        } finally {
            out.close();
            out = null;
            cb = null;
        }
    }
}

所以它总是试图刷新,这可能是大多数用户所期望的。

您可以做的是使用 in-memory 单独生成行BufferedWriter。如果它死了,你跳过这行,如果它有效,你写它。另外,现在是 2019 年,所以请开始使用try-with-resources

try(BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(outputFile))) {
    for (Kanji nextKanji : kanjiList) {
        try {
            StringBuilder sb = new StringBuilder();
            // sb.append stuff from list of objects...
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(baos));
            bw.write(sb.toString());
            bw.newLine();
            bw.close();
            baos.writeTo(bos);
        } catch (MalformedInputException ex) {}
    }
}

如果它完全有效(我只是从头顶写),它可以用一个ByteArrayOutputStream实例更漂亮,并reset()在循环中使用它。


推荐阅读