如何在Java中使用PrintStream期间发现发生的异常

时间:2019-01-07 16:59:44

标签: java printwriter printstream

我刚刚读过,在Java中,类PrintStreamPrintWriter不会抛出检查异常。相反,他们使用了一种错误标志,我可以通过调用方法boolean checkError()API link)来阅读。

现在,我在问自己如何找出发生异常的原因。有时有异常的信息可能还不够,或者?

1 个答案:

答案 0 :(得分:8)

Based on the source code,看起来他们丢弃了该异常。所有的捕获块都看起来像这样:

try {
    ...
}
catch (IOException x) {
    trouble = true; // (x is ignored)
}

因此,最直接的解决方案可能是尽可能不使用PrintStream

一种解决方法是扩展PrintStream并将输出包装在另一个OutputStream中,后者在PrintStream捕获(并丢弃)异常之前捕获异常。像这样:

package mcve.util;

import java.io.*;

public class PrintStreamEx extends PrintStream {
    public PrintStreamEx(OutputStream out) {
        super(new HelperOutputStream(out));
    }

    /**
     * @return the last IOException thrown by the output,
     *         or null if there isn't one
     */
    public IOException getLastException() {
        return ((HelperOutputStream) out).lastException;
    }

    @Override
    protected void clearError() {
        super.clearError();
        ((HelperOutputStream) out).setLastException(null);
    }

    private static class HelperOutputStream extends FilterOutputStream {
        private IOException lastException;

        private HelperOutputStream(OutputStream out) {
            super(out);
        }

        private IOException setLastException(IOException e) {
            return (lastException = e);
        }

        @Override
        public void write(int b) throws IOException {
            try {
                super.write(b);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void write(byte[] b) throws IOException {
            try {
                super.write(b);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            try {
                super.write(b, off, len);
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void flush() throws IOException {
            try {
                super.flush();
            } catch (IOException e) {
                throw setLastException(e);
            }
        }

        @Override
        public void close() throws IOException {
            try {
                super.close();
            } catch (IOException e) {
                throw setLastException(e);
            }
        }
    }
}