Как узнать возникшее исключение во время использования PrintStream в Java - PullRequest
0 голосов
/ 07 января 2019

Я только что прочитал, что в Java классы PrintStream и PrintWriter не генерируют проверенные исключения. Вместо этого они используют своего рода флаг ошибки, который я могу прочитать, вызывая метод boolean checkError() ( API link ).

Теперь я спрашиваю себя, как выяснить причину возникновения исключения. Информации о том, что произошло исключение, иногда может быть недостаточно, или?

1 Ответ

0 голосов
/ 07 января 2019

Исходя из исходного кода , похоже, что они отбрасывают исключение. Все блоки улова выглядят так:

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