首页 > 解决方案 > 如何在 Java 中使用 PrintStream 时找出发生的异常

问题描述

我刚刚读到,Java 中的类PrintStreamPrintWriter不会抛出检查异常。相反,他们使用的是一种错误标志,我可以读取它调用方法boolean checkError()API链接)。

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

标签: javaprintwriterprintstream

解决方案


根据源代码,看起来他们丢弃了异常。所有的 catch 块看起来像这样:

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);
            }
        }
    }
}

推荐阅读