diff --git a/src/changes/changes.xml b/src/changes/changes.xml index afc84fa3dc0..80afd3607ce 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -47,6 +47,7 @@ The type attribute can be add,update,fix,remove. + ThresholdingOutputStream.isThresholdExceeded() now reflects the threshold-reached state, and a failed thresholdReached() no longer leaves the stream unable to fire the event again. Add IOConsumer.accept(IOConsumer, T) (#846). diff --git a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java index 742572b2ebc..12ecc53ee85 100644 --- a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java @@ -111,7 +111,12 @@ public ThresholdingOutputStream(final int threshold, final IOConsumer threshold) { thresholdExceeded = true; - thresholdReached(); + try { + thresholdReached(); + } catch (final IOException | RuntimeException e) { + thresholdExceeded = false; + throw e; + } } } @@ -192,7 +197,7 @@ public int getThreshold() { * @return {@code true} if the threshold has been reached; {@code false} otherwise. */ public boolean isThresholdExceeded() { - return written > threshold; + return thresholdExceeded; } /** diff --git a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java index 5e1e2c00d9d..2c3892a51fa 100644 --- a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java @@ -208,6 +208,26 @@ void testThresholdIOConsumerIOException() throws IOException { } } + @Test + void testThresholdReachedRetriedAfterException() throws IOException { + final int threshold = 1; + final AtomicInteger counter = new AtomicInteger(); + try (ThresholdingOutputStream out = new ThresholdingOutputStream(threshold, tos -> { + if (counter.incrementAndGet() == 1) { + throw new IOException("Threshold reached."); + } + }, os -> new ByteArrayOutputStream(4))) { + assertThresholdingInitialState(out, threshold, 0); + out.write('a'); + assertFalse(out.isThresholdExceeded()); + assertThrows(IOException.class, () -> out.write('a')); + assertFalse(out.isThresholdExceeded()); + out.write('a'); + assertEquals(2, counter.get()); + assertTrue(out.isThresholdExceeded()); + } + } + @Test void testThresholdIOConsumerUncheckedException() throws IOException { final int threshold = 1;