This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 8acfd4c594eb9838d7de38eeb097da050c149a80
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Sat May 20 12:08:29 2023 -0400

    Add ChunkedOutputStream.Builder and refactor
    
    - Javadoc
    - In builders, a negative or zero size buffer should reset the buffer
    size to it default buffer size value
    - In builders, AbstractOriginSupplier.checkOrigin() now throws
    IllegalStateException instead of NullPointerException
---
 src/changes/changes.xml                            |  6 ++
 .../commons/io/build/AbstractOriginSupplier.java   |  7 +-
 .../commons/io/build/AbstractStreamBuilder.java    | 34 +++++++--
 .../io/input/BufferedFileChannelInputStream.java   |  2 +-
 .../io/input/MemoryMappedFileInputStream.java      |  2 +-
 .../apache/commons/io/input/ReaderInputStream.java |  3 +-
 .../commons/io/input/ReversedLinesFileReader.java  |  2 +-
 .../commons/io/input/UncheckedBufferedReader.java  |  3 +-
 .../commons/io/input/UncheckedFilterReader.java    |  3 +-
 .../input/UnsynchronizedByteArrayInputStream.java  |  3 +-
 .../commons/io/output/ChunkedOutputStream.java     | 87 +++++++++++++++++++---
 .../commons/io/output/FileWriterWithEncoding.java  |  3 +-
 .../commons/io/output/LockableFileWriter.java      |  3 +-
 .../commons/io/output/ChunkedOutputStreamTest.java | 52 +++++++++----
 .../commons/io/output/LockableFileWriterTest.java  |  2 +-
 15 files changed, 167 insertions(+), 45 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index c2a34531..b364456c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -55,10 +55,16 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="fix" due-to="Gary Gregory">
         ByteArrayOrigin should be able convert a byte[] to a 
ByteArrayInputStream.
       </action>
+      <action dev="ggregory" type="fix" due-to="Gary Gregory">
+        AbstractOriginSupplier.checkOrigin() now throws IllegalStateException 
instead of NullPointerException.
+      </action>
       <!-- ADD -->
       <action dev="ggregory" type="add" due-to="Gary Gregory">
         Add CharSequenceInputStream.Builder.
       </action>
+      <action dev="ggregory" type="add" due-to="Gary Gregory">
+        Add ChunkedOutputStream.Builder.
+      </action>
       <action dev="ggregory" type="add" due-to="Gary Gregory">
         Add AbstractStreamBuilder.setOpenOptions(OpenOption...).
       </action>
diff --git 
a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java 
b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
index ef691f44..ae8472c2 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java
@@ -166,10 +166,13 @@ public abstract class AbstractOriginSupplier<T, B extends 
AbstractOriginSupplier
      * Checks whether the origin is null.
      *
      * @return the origin.
-     * @throws NullPointerException if the {@code origin} is {@code null}
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
      */
     protected AbstractOrigin<?, ?> checkOrigin() {
-        return Objects.requireNonNull(origin, "origin");
+        if (origin == null) {
+            throw new IllegalStateException("origin == null");
+        }
+        return origin;
     }
 
     /**
diff --git 
a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java 
b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
index 3cbe1698..f38bed07 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
@@ -23,6 +23,7 @@ import java.io.OutputStream;
 import java.io.Writer;
 import java.nio.charset.Charset;
 import java.nio.file.OpenOption;
+import java.nio.file.Path;
 
 import org.apache.commons.io.Charsets;
 import org.apache.commons.io.IOUtils;
@@ -85,11 +86,12 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
      * @return An input stream
      * @throws IOException                   if an I/O error occurs.
      * @throws UnsupportedOperationException if the origin cannot be converted 
to a CharSequence.
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
      * @see AbstractOrigin#getCharSequence(Charset)
      * @since 2.13.0
      */
     protected CharSequence getCharSequence() throws IOException {
-        return getOrigin().getCharSequence(getCharset());
+        return checkOrigin().getCharSequence(getCharset());
     }
 
     /**
@@ -117,10 +119,11 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
      * @throws IOException                   if an I/O error occurs.
      * @throws UnsupportedOperationException if the origin cannot be converted 
to an InputStream.
      * @see AbstractOrigin#getInputStream(OpenOption...)
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
      * @since 2.13.0
      */
     protected InputStream getInputStream() throws IOException {
-        return getOrigin().getInputStream(getOpenOptions());
+        return checkOrigin().getInputStream(getOpenOptions());
     }
 
     protected OpenOption[] getOpenOptions() {
@@ -128,16 +131,30 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
     }
 
     /**
-     * Gets an output stream from the origin with open options.
+     * Gets an OutputStream from the origin with open options.
      *
-     * @return An input stream
+     * @return An OutputStream
      * @throws IOException                   if an I/O error occurs.
      * @throws UnsupportedOperationException if the origin cannot be converted 
to an OututStream.
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
      * @see AbstractOrigin#getOutputStream(OpenOption...)
      * @since 2.13.0
      */
     protected OutputStream getOutputStream() throws IOException {
-        return getOrigin().getOutputStream(getOpenOptions());
+        return checkOrigin().getOutputStream(getOpenOptions());
+    }
+
+    /**
+     * Gets a Path from the origin.
+     *
+     * @return A Path
+     * @throws UnsupportedOperationException if the origin cannot be converted 
to a Path.
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
+     * @see AbstractOrigin#getPath()
+     * @since 2.13.0
+     */
+    protected Path getPath() {
+        return checkOrigin().getPath();
     }
 
     /**
@@ -146,15 +163,16 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
      * @return An writer.
      * @throws IOException                   if an I/O error occurs.
      * @throws UnsupportedOperationException if the origin cannot be converted 
to a Writer.
+     * @throws IllegalStateException if the {@code origin} is {@code null}.
      * @see AbstractOrigin#getOutputStream(OpenOption...)
      * @since 2.13.0
      */
     protected Writer getWriter() throws IOException {
-        return getOrigin().getWriter(getCharset(), getOpenOptions());
+        return checkOrigin().getWriter(getCharset(), getOpenOptions());
     }
 
     /**
-     * Sets the buffer size.
+     * Sets the buffer size. Invalid input (bufferSize &lt;= 0) resets the 
value to its default.
      * <p>
      * Subclasses may ignore this setting.
      * </p>
@@ -163,7 +181,7 @@ public abstract class AbstractStreamBuilder<T, B extends 
AbstractStreamBuilder<T
      * @return this.
      */
     public B setBufferSize(final int bufferSize) {
-        this.bufferSize = bufferSize >= 0 ? bufferSize : bufferSizeDefault;
+        this.bufferSize = bufferSize > 0 ? bufferSize : bufferSizeDefault;
         return asThis();
     }
 
diff --git 
a/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java 
b/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java
index ea75cc7d..e0d6734f 100644
--- 
a/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java
+++ 
b/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java
@@ -86,7 +86,7 @@ public final class BufferedFileChannelInputStream extends 
InputStream {
          */
         @Override
         public BufferedFileChannelInputStream get() throws IOException {
-            return new BufferedFileChannelInputStream(getOrigin().getPath(), 
getBufferSize());
+            return new BufferedFileChannelInputStream(getPath(), 
getBufferSize());
         }
 
     }
diff --git 
a/src/main/java/org/apache/commons/io/input/MemoryMappedFileInputStream.java 
b/src/main/java/org/apache/commons/io/input/MemoryMappedFileInputStream.java
index 1935fa99..89114be9 100644
--- a/src/main/java/org/apache/commons/io/input/MemoryMappedFileInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/MemoryMappedFileInputStream.java
@@ -108,7 +108,7 @@ public final class MemoryMappedFileInputStream extends 
InputStream {
          */
         @Override
         public MemoryMappedFileInputStream get() throws IOException {
-            return new MemoryMappedFileInputStream(getOrigin().getPath(), 
getBufferSize());
+            return new MemoryMappedFileInputStream(getPath(), getBufferSize());
         }
     }
 
diff --git a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java 
b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
index 27ea5ab8..7e5bee6f 100644
--- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
@@ -114,12 +114,13 @@ public class ReaderInputStream extends InputStream {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a Reader.
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getReader(Charset)
          */
         @SuppressWarnings("resource")
         @Override
         public ReaderInputStream get() throws IOException {
-            return new ReaderInputStream(getOrigin().getReader(getCharset()), 
charsetEncoder, getBufferSize());
+            return new 
ReaderInputStream(checkOrigin().getReader(getCharset()), charsetEncoder, 
getBufferSize());
         }
 
         @Override
diff --git 
a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java 
b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
index 75052f55..ef5fdf13 100644
--- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
+++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
@@ -87,7 +87,7 @@ public class ReversedLinesFileReader implements Closeable {
          */
         @Override
         public ReversedLinesFileReader get() throws IOException {
-            return new ReversedLinesFileReader(getOrigin().getPath(), 
getBufferSize(), getCharset());
+            return new ReversedLinesFileReader(getPath(), getBufferSize(), 
getCharset());
         }
 
     }
diff --git 
a/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java 
b/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java
index 7c7e9482..1a49c9bb 100644
--- a/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java
+++ b/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java
@@ -78,12 +78,13 @@ public final class UncheckedBufferedReader extends 
BufferedReader {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a Reader.
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getReader(Charset)
          */
         @Override
         public UncheckedBufferedReader get() {
             // This an unchecked class, so this method is as well.
-            return Uncheck.get(() -> new 
UncheckedBufferedReader(getOrigin().getReader(getCharset()), getBufferSize()));
+            return Uncheck.get(() -> new 
UncheckedBufferedReader(checkOrigin().getReader(getCharset()), 
getBufferSize()));
         }
 
     }
diff --git 
a/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java 
b/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java
index 4137a562..768a16b7 100644
--- a/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java
+++ b/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java
@@ -74,12 +74,13 @@ public final class UncheckedFilterReader extends 
FilterReader {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a Reader.
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getReader(Charset)
          */
         @Override
         public UncheckedFilterReader get() {
             // This an unchecked class, so this method is as well.
-            return Uncheck.get(() -> new 
UncheckedFilterReader(getOrigin().getReader(getCharset())));
+            return Uncheck.get(() -> new 
UncheckedFilterReader(checkOrigin().getReader(getCharset())));
         }
 
     }
diff --git 
a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
 
b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
index 38e9a2d9..aecf72e3 100644
--- 
a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
+++ 
b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
@@ -92,11 +92,12 @@ public class UnsynchronizedByteArrayInputStream extends 
InputStream {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a byte[].
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getByteArray()
          */
         @Override
         public UnsynchronizedByteArrayInputStream get() throws IOException {
-            return new 
UnsynchronizedByteArrayInputStream(getOrigin().getByteArray(), offset, length);
+            return new 
UnsynchronizedByteArrayInputStream(checkOrigin().getByteArray(), offset, 
length);
         }
 
         @Override
diff --git 
a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java 
b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
index 7d193cb0..581ae126 100644
--- a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
@@ -21,16 +21,73 @@ import java.io.IOException;
 import java.io.OutputStream;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.build.AbstractStreamBuilder;
 
 /**
- * OutputStream which breaks larger output blocks into chunks.
- * Native code may need to copy the input array; if the write buffer
- * is very large this can cause OOME.
+ * OutputStream which breaks larger output blocks into chunks. Native code may 
need to copy the input array; if the write buffer is very large this can cause
+ * OOME.
  *
  * @since 2.5
  */
 public class ChunkedOutputStream extends FilterOutputStream {
 
+    // @formatter:off
+    /**
+     * Builds a new {@link UnsynchronizedByteArrayOutputStream} instance.
+     * <p>
+     * Using File IO:
+     * </p>
+     *
+     * <pre>{@code
+     * UnsynchronizedByteArrayOutputStream s = 
UnsynchronizedByteArrayOutputStream.builder()
+     *   .setBufferSize(8192)
+     *   .get();
+     * }
+     * </pre>
+     * <p>
+     * Using NIO Path:
+     * </p>
+     *
+     * <pre>{@code
+     * UnsynchronizedByteArrayOutputStream s = 
UnsynchronizedByteArrayOutputStream.builder()
+     *   .setBufferSize(8192)
+     *   .get();
+     * }
+     * </pre>
+     *
+     * @since 2.13.0
+     */
+    // @formatter:on
+    public static class Builder extends 
AbstractStreamBuilder<ChunkedOutputStream, Builder> {
+
+        /**
+         * Constructs a new instance.
+         * <p>
+         * This builder use the aspects OutputStream and buffer size (chunk 
size).
+         * </p>
+         *
+         * @return a new instance.
+         * @throws IOException                   if an I/O error occurs.
+         * @throws UnsupportedOperationException if the origin cannot be 
converted to an OututStream.
+         * @see #getOutputStream()
+         */
+        @Override
+        public ChunkedOutputStream get() throws IOException {
+            return new ChunkedOutputStream(getOutputStream(), getBufferSize());
+        }
+
+    }
+
+    /**
+     * Constructs a new {@link Builder}.
+     *
+     * @return a new {@link Builder}.
+     * @since 2.13.0
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
     /**
      * The maximum chunk size to us when writing data arrays
      */
@@ -40,7 +97,9 @@ public class ChunkedOutputStream extends FilterOutputStream {
      * Creates a new stream that uses a chunk size of {@link 
IOUtils#DEFAULT_BUFFER_SIZE}.
      *
      * @param stream the stream to wrap
+     * @deprecated Use {@link #builder()} and {@link Builder#get()}
      */
+    @Deprecated
     public ChunkedOutputStream(final OutputStream stream) {
         this(stream, IOUtils.DEFAULT_BUFFER_SIZE);
     }
@@ -48,24 +107,30 @@ public class ChunkedOutputStream extends 
FilterOutputStream {
     /**
      * Creates a new stream that uses the specified chunk size.
      *
-     * @param stream the stream to wrap
+     * @param stream    the stream to wrap
      * @param chunkSize the chunk size to use; must be a positive number.
      * @throws IllegalArgumentException if the chunk size is &lt;= 0
+     * @deprecated Use {@link #builder()} and {@link Builder#get()}
      */
+    @Deprecated
     public ChunkedOutputStream(final OutputStream stream, final int chunkSize) 
{
-       super(stream);
-       if (chunkSize <= 0) {
-           throw new IllegalArgumentException();
-       }
-       this.chunkSize = chunkSize;
+        super(stream);
+        if (chunkSize <= 0) {
+            throw new IllegalArgumentException("chunkSize <= 0");
+        }
+        this.chunkSize = chunkSize;
+    }
+
+    int getChunkSize() {
+        return chunkSize;
     }
 
     /**
      * Writes the data buffer in chunks to the underlying stream
      *
-     * @param data the data to write
+     * @param data      the data to write
      * @param srcOffset the offset
-     * @param length the length of data to write
+     * @param length    the length of data to write
      *
      * @throws IOException if an I/O error occurs.
      */
diff --git 
a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java 
b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java
index 27bdb603..45cb6dec 100644
--- a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java
+++ b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java
@@ -94,6 +94,7 @@ public class FileWriterWithEncoding extends ProxyWriter {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a File.
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getFile()
          */
         @SuppressWarnings("resource")
@@ -103,7 +104,7 @@ public class FileWriterWithEncoding extends ProxyWriter {
                 throw new IllegalStateException(String.format("Mismatched 
Charset(%s) and CharsetEncoder(%s)", getCharset(), charsetEncoder.charset()));
             }
             final Object encoder = charsetEncoder != null ? charsetEncoder : 
getCharset();
-            return new 
FileWriterWithEncoding(FileWriterWithEncoding.initWriter(getOrigin().getFile(), 
encoder, append));
+            return new 
FileWriterWithEncoding(FileWriterWithEncoding.initWriter(checkOrigin().getFile(),
 encoder, append));
         }
 
         /**
diff --git a/src/main/java/org/apache/commons/io/output/LockableFileWriter.java 
b/src/main/java/org/apache/commons/io/output/LockableFileWriter.java
index 052fc4ca..dd730e73 100644
--- a/src/main/java/org/apache/commons/io/output/LockableFileWriter.java
+++ b/src/main/java/org/apache/commons/io/output/LockableFileWriter.java
@@ -87,11 +87,12 @@ public class LockableFileWriter extends Writer {
          *
          * @return a new instance.
          * @throws UnsupportedOperationException if the origin cannot provide 
a File.
+         * @throws IllegalStateException if the {@code origin} is {@code null}.
          * @see AbstractOrigin#getFile()
          */
         @Override
         public LockableFileWriter get() throws IOException {
-            return new LockableFileWriter(getOrigin().getFile(), getCharset(), 
append, lockDirectory.getFile().toString());
+            return new LockableFileWriter(checkOrigin().getFile(), 
getCharset(), append, lockDirectory.getFile().toString());
         }
 
         /**
diff --git 
a/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java 
b/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java
index 54287add..b7460a4d 100644
--- a/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java
@@ -30,39 +30,63 @@ import org.junit.jupiter.api.Test;
  */
 public class ChunkedOutputStreamTest {
 
+    private ByteArrayOutputStream newByteArrayOutputStream(final AtomicInteger 
numWrites) {
+        return new ByteArrayOutputStream() {
+            @Override
+            public void write(final byte[] b, final int off, final int len) {
+                numWrites.incrementAndGet();
+                super.write(b, off, len);
+            }
+        };
+    }
+
     @Test
-    public void defaultConstructor() throws IOException {
+    public void testDefaultBuilder() throws IOException {
         final AtomicInteger numWrites = new AtomicInteger();
         try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
-            final ChunkedOutputStream chunked = new ChunkedOutputStream(baos)) 
{
+                final ChunkedOutputStream chunked = 
ChunkedOutputStream.builder().setOutputStream(baos).get()) {
             chunked.write(new byte[IOUtils.DEFAULT_BUFFER_SIZE + 1]);
             assertEquals(2, numWrites.get());
         }
+        assertThrows(IllegalStateException.class, () -> 
ChunkedOutputStream.builder().get());
     }
 
     @Test
-    public void negative_chunkSize_not_permitted() {
-        assertThrows(IllegalArgumentException.class, () -> new 
ChunkedOutputStream(new ByteArrayOutputStream(), 0));
+    public void testDefaultConstructor() throws IOException {
+        final AtomicInteger numWrites = new AtomicInteger();
+        try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
+                final ChunkedOutputStream chunked = new 
ChunkedOutputStream(baos)) {
+            chunked.write(new byte[IOUtils.DEFAULT_BUFFER_SIZE + 1]);
+            assertEquals(2, numWrites.get());
+        }
     }
 
-    private ByteArrayOutputStream newByteArrayOutputStream(final AtomicInteger 
numWrites) {
-        return new ByteArrayOutputStream() {
-            @Override
-            public void write(final byte[] b, final int off, final int len) {
-                numWrites.incrementAndGet();
-                super.write(b, off, len);
-            }
-        };
+    @Test
+    public void testNegativeChunkSize() throws IOException {
+        assertThrows(IllegalArgumentException.class, () -> new 
ChunkedOutputStream(new ByteArrayOutputStream(), -1));
+        // Builder resets invalid input to the default.
+        try (ChunkedOutputStream os = 
ChunkedOutputStream.builder().setOutputStream(new 
ByteArrayOutputStream()).setBufferSize(-1).get()) {
+            assertEquals(IOUtils.DEFAULT_BUFFER_SIZE, os.getChunkSize());
+        }
     }
 
     @Test
-    public void write_four_chunks() throws Exception {
+    public void testWriteFourChunks() throws Exception {
         final AtomicInteger numWrites = new AtomicInteger();
         try (ByteArrayOutputStream baos = newByteArrayOutputStream(numWrites);
-            final ChunkedOutputStream chunked = new ChunkedOutputStream(baos, 
10)) {
+                final ChunkedOutputStream chunked = new 
ChunkedOutputStream(baos, 10)) {
             chunked.write("0123456789012345678901234567891".getBytes());
             assertEquals(4, numWrites.get());
         }
     }
 
+    @Test
+    public void testZeroChunkSize() throws IOException {
+        assertThrows(IllegalArgumentException.class, () -> new 
ChunkedOutputStream(new ByteArrayOutputStream(), 0));
+        // Builder resets invalid input to the default.
+        try (ChunkedOutputStream os = 
ChunkedOutputStream.builder().setOutputStream(new 
ByteArrayOutputStream()).setBufferSize(0).get()) {
+            assertEquals(IOUtils.DEFAULT_BUFFER_SIZE, os.getChunkSize());
+        }
+    }
+
 }
diff --git 
a/src/test/java/org/apache/commons/io/output/LockableFileWriterTest.java 
b/src/test/java/org/apache/commons/io/output/LockableFileWriterTest.java
index 5afef834..88c117da 100644
--- a/src/test/java/org/apache/commons/io/output/LockableFileWriterTest.java
+++ b/src/test/java/org/apache/commons/io/output/LockableFileWriterTest.java
@@ -134,7 +134,7 @@ public class LockableFileWriterTest {
         assertFalse(file.exists());
         assertFalse(lockFile.exists());
         //
-        assertThrows(NullPointerException.class, () -> 
LockableFileWriter.builder().get());
+        assertThrows(IllegalStateException.class, () -> 
LockableFileWriter.builder().get());
         assertFalse(file.exists());
         assertFalse(lockFile.exists());
         // again

Reply via email to