【问题标题】:PrintWriter flush is not working on Windows Server 2012PrintWriter 刷新在 Windows Server 2012 上不起作用
【发布时间】:2018-04-04 15:55:15
【问题描述】:

我使用 PrintWriter 写入 autoFlush = true 的文件: PrintWriter pw = new PrintWriter(new FileOutputStream(file), autoFlush);

没有调用 pw.flush(),每次我调用 pw.println(...) 时,都会将内容写入输出文件。

它在 Win7 和 Win Server 2008 上运行良好,但在 Win Server 2012 上运行良好。我尝试使用相同的 JDK,对于 Win Server 2012 环境,文件仅在 finally 块中调用 pw.close() 后刷新(例如到达末尾程序或异常发生)。

根据javadoc:https://docs.oracle.com/javase/7/docs/api/java/io/Writer.html#flush()

如果此流的预期目标是底层操作系统提供的抽象,例如文件,则刷新流仅保证先前写入流的字节被传递给操作系统进行写入;它不能保证它们实际上被写入了物理设备,例如磁盘驱动器。

似乎是操作系统问题。有什么帮助吗?

代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;

public class TestPW {
    public static void main(String[] args) throws Exception {

        File file = null;
        PrintWriter pw = null;

        try {
            boolean autoFlush = true;

            file = new File("C:\\NotBackedUp\\test.txt");
            pw = new PrintWriter(new FileOutputStream(file), autoFlush);

            int loop = 100000000;

            while (loop > 0) {
                pw.println("Test: " + loop);
                loop--;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pw != null) {
                    pw.close();
                }
            } catch (Exception e) {

            }
        }

    }
}

解决方法是在处理了一些循环后关闭 pw 并再次重新初始化 pw 对象,如下所示....

import java.io.*;

public class TestPSMaxLine {
    public static void main(String[] args) throws Exception {

        File file = null;
        PrintStream ps = null;

        int maxLinesToWriteBeforeClose = 100000;

        try {
            boolean appendFile = true;
            boolean autoFlush = true;

            file = new File("C:\\NotBackedUp\\test.txt");
            ps = new PrintStream(new FileOutputStream(file, appendFile), autoFlush);

            int loop = 100000000;
            int lineNum = 0;

            while (loop > 0) {
                ps.println("Test: " + loop);
                loop--;
                lineNum++;
                if(lineNum % maxLinesToWriteBeforeClose ==0){
                    closeFile(ps);
                    ps = new PrintStream(new FileOutputStream(file, appendFile), autoFlush);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeFile(ps);
        }
    }

    private static void closeFile(PrintStream ps){
        try{
            if (ps != null) {
                ps.close();
            }   
        } catch (Exception e) { 
        }
    }
}

【问题讨论】:

    标签: java windows flush printwriter


    【解决方案1】:

    有一个异常,但PrintWriter 吞下了异常。您需要手动检查它们。或者使用BufferedWriter,它不会吞下异常。

    【讨论】:

    • 我尝试过使用 BufferedWriter,要么我在循环后有 bw.flush()--;和/或在 BufferedWriter 构造函数中指定缓冲区的大小,运行程序也不例外。结果与使用 PrintWriter 完全相同,其中输出文件的大小保持为 0,直到程序结束或终止。
    • 这只发生在 Win Server 2012 中,对于我测试的其他环境(例如 Win7、Win Server 2008)在程序运行时文件大小不断增加的情况下工作正常(例如内容在循环)。
    • 确定没有例外?即使在close()?您在发布的代码中忽略了它。
    • 好的,在我放置了 e.printStackTrace();在 close() 的 try-catch 块中,这仍然不例外。
    • 问题是缓冲区没有在循环中刷新,即使在循环语句之后显式调用 flush() 也是如此。在程序完成或终止之前,文件大小保持为 0 字节。这在 close() 中没有错误,否则将不会生成包含内容的文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2016-12-30
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多