From 533107497ee74b3cc8dce16f419da1a525c3d11a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 2 Oct 2025 10:30:56 -0400 Subject: [PATCH 001/174] Reuse AbstractStreamBuilder.getChannel(Channel) --- .../io/input/ReversedLinesFileReader.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) 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 949ff8cbd8e..f87b109abb9 100644 --- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java @@ -25,7 +25,6 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; @@ -93,6 +92,7 @@ public static class Builder extends AbstractStreamBuilder 0) { - this.totalBlockCount = this.totalByteLength / blockSize + 1; + this.totalBlockCount = totalByteLength / blockSize + 1; } else { - this.totalBlockCount = this.totalByteLength / blockSize; - if (this.totalByteLength > 0) { + this.totalBlockCount = totalByteLength / blockSize; + if (totalByteLength > 0) { lastBlockLength = blockSize; } } From 028dd621009cb0cca677116cd0acdc69192d3d66 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 2 Oct 2025 16:31:54 +0200 Subject: [PATCH 002/174] Improve `FileUtils.forceDelete()` tests on Windows (#791) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve `FileUtils.forceDelete()` tests on Windows On Windows, the `DeleteFile` Win32 API has a little quirk: it refuses to delete files with the legacy **DOS read-only attribute** set. (Because apparently 99% of Windows users don’t realize that “deleting a file” is actually an operation on the *directory*, not the file itself 😉). So the usual drill is: clear the read-only flag first, then delete. * Until JDK 25, `File.delete()` did this for you behind the scenes: it quietly stripped the flag before calling into `DeleteFile`. That meant your file might be left behind (with the flag missing) if the *real* ACLs didn’t allow deletion. * From JDK 25 onward, `File.delete()` doesn’t touch the flag anymore. If the bit is set, `DeleteFile` fails, end of story. * `FileUtils.forceDelete()` already knows how to juggle the flag itself, so its behavior didn’t change. This PR: * Updates two tests that were (unfairly) comparing `File.delete` with `FileUtils.forceDelete`. With JDK 25, their expectations diverged. * Adds a new test to confirm that `FileUtils.forceDelete` restores the read-only flag if the actual deletion fails. > [!WARNING] > I didn’t develop this on a Windows box, so I couldn’t test it locally. Leaving this as a **draft PR** until CI tells us whether Windows agrees with me. * fix: always clear read-only bit * fix: check for `IOException`, not `AccessDeniedException` * feat: add holder for file and parent attributes Introduce a helper that snapshots file and parent directory attributes before `setReadOnly` is applied. If a deletion attempt fails, the holder can restore the original attributes to keep the filesystem state consistent. * fix: Spotbugs failure * fix: prefer POSIX to DOS attributes when both are available On Linux/Unix, both POSIX and DOS attribute views may be supported, while on Windows only DOS attributes are available. Check for POSIX first to ensure the correct view is used across platforms. * fix: revert read-only related changes --- .../org/apache/commons/io/FileUtilsTest.java | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java index 4f6efa0f946..ced4b106638 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java @@ -52,6 +52,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.AclFileAttributeView; +import java.nio.file.attribute.DosFileAttributeView; import java.nio.file.attribute.FileTime; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; @@ -1735,21 +1736,31 @@ void testForceDeleteReadOnlyDirectory() throws Exception { void testForceDeleteReadOnlyFile() throws Exception { try (TempFile destination = TempFile.create("test-", ".txt")) { final File file = destination.toFile(); - assertTrue(file.setReadOnly()); - assertTrue(file.canRead()); - assertFalse(file.canWrite()); - // sanity check that File.delete() deletes read-only files. - assertTrue(file.delete()); + assertTrue(file.setReadOnly(), "Setting file read-only successful"); + assertTrue(file.canRead(), "File must be readable"); + assertFalse(file.canWrite(), "File must not be writable"); + assertTrue(file.exists(), "File doesn't exist to delete"); + // Since JDK 25 on Windows, File.delete() refuses to remove files + // with the DOS readonly bit set (JDK-8355954). + // We clear the bit here for consistency across JDK versions. + setDosReadOnly(file.toPath(), false); + assertTrue(file.delete(), "File.delete() must delete read-only file"); } try (TempFile destination = TempFile.create("test-", ".txt")) { final File file = destination.toFile(); // real test - assertTrue(file.setReadOnly()); - assertTrue(file.canRead()); - assertFalse(file.canWrite()); + assertTrue(file.setReadOnly(), "Setting file read-only successful"); + assertTrue(file.canRead(), "File must be readable"); + assertFalse(file.canWrite(), "File must not be writable"); assertTrue(file.exists(), "File doesn't exist to delete"); FileUtils.forceDelete(file); - assertFalse(file.exists(), "Check deletion"); + assertFalse(file.exists(), "FileUtils.forceDelete() must delete read-only file"); + } + } + + private static void setDosReadOnly(Path p, boolean readOnly) throws IOException { + if (Files.getFileStore(p).supportsFileAttributeView(DosFileAttributeView.class)) { + Files.setAttribute(p, "dos:readonly", readOnly, LinkOption.NOFOLLOW_LINKS); } } @@ -1823,23 +1834,27 @@ void testForceDeleteUnwritableDirectory() throws Exception { void testForceDeleteUnwritableFile() throws Exception { try (TempFile destination = TempFile.create("test-", ".txt")) { final File file = destination.toFile(); - assertTrue(file.canWrite()); - assertTrue(file.setWritable(false)); - assertFalse(file.canWrite()); - assertTrue(file.canRead()); - // sanity check that File.delete() deletes unwritable files. - assertTrue(file.delete()); + assertTrue(file.canWrite(), "File must be writable"); + assertTrue(file.setWritable(false), "Setting file unwritable successful"); + assertFalse(file.canWrite(), "File must not be writable"); + assertTrue(file.canRead(), "File must be readable"); + assertTrue(file.exists(), "File must exist to delete"); + // Since JDK 25 on Windows, File.delete() refuses to remove files + // with the DOS readonly bit set (JDK-8355954). + // We clear the bit here for consistency across JDK versions. + setDosReadOnly(file.toPath(), false); + assertTrue(file.delete(), "File.delete() must delete unwritable file"); } try (TempFile destination = TempFile.create("test-", ".txt")) { final File file = destination.toFile(); // real test - assertTrue(file.canWrite()); - assertTrue(file.setWritable(false)); - assertFalse(file.canWrite()); - assertTrue(file.canRead()); - assertTrue(file.exists(), "File doesn't exist to delete"); + assertTrue(file.canWrite(), "File must be writable"); + assertTrue(file.setWritable(false), "Setting file unwritable successful"); + assertFalse(file.canWrite(), "File must not be writable"); + assertTrue(file.canRead(), "File must be readable"); + assertTrue(file.exists(), "File must exist to delete"); FileUtils.forceDelete(file); - assertFalse(file.exists(), "Check deletion"); + assertFalse(file.exists(), "FileUtils.forceDelete() must delete unwritable file"); } } From c2ee341e0134df62c967c6f03741894383ef83a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:27:46 -0400 Subject: [PATCH 003/174] Bump ossf/scorecard-action from 2.4.2 to 2.4.3 (#792) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.2 to 2.4.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/05b42c624433fc40578a4040d5cf5e36ddca8cde...4eaacf0543bb3f2c246792bd56e8cdeffafb205a) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index cf4d6ba87b0..dc25de392ba 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -47,7 +47,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # 2.4.2 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # 2.4.3 with: results_file: results.sarif results_format: sarif From ac2d382eeaa8b1d630051cdbc8dd302372ee4f21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:28:20 -0400 Subject: [PATCH 004/174] Bump github/codeql-action from 3.30.4 to 3.30.6 (#793) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.30.4 to 3.30.6. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9...64d10c13136e1c5bce3e5fbde8d4906eeaafc885) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 3.30.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fcc16fe390a..db18ec4ae56 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/autobuild@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index dc25de392ba..3b7d3020e33 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 with: sarif_file: results.sarif From 07d2cd9c493baae1e82553b3da420d17a6093c05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 20:29:27 -0400 Subject: [PATCH 005/174] Bump actions/dependency-review-action from 4.7.3 to 4.8.0 (#794) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4.7.3 to 4.8.0. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/595b5aeba73380359d98a5e087f648dbb0edce1b...56339e523c0409420f6c2c9a2f4292bbb3c07dd3) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-version: 4.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 1e043924237..edfe8756642 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -28,4 +28,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: 'Dependency Review PR' - uses: actions/dependency-review-action@595b5aeba73380359d98a5e087f648dbb0edce1b # v4.7.3 + uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0 From 45578a74f54886a2e2b4b72f8faeda0728146f14 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Fri, 3 Oct 2025 21:32:36 +0200 Subject: [PATCH 006/174] Add missing `read` argument validation in `IOUtils` (#795) * Add missing `read` argument validation in `IOUtils` In #790 I introduced `IOUtils#checkIndexFromLength` calls to validate arguments across the codebase. Ironically, the `IOUtils` class itself was left out. This PR addresses that omission by adding argument validation to `IOUtils#read` and `IOUtils#readFully`. Key points: * Ensures consistency with the rest of Commons IO by validating `offset` and `length`. * Fixes inconsistent exception behavior: * Previously, `length < 0` resulted in an `IllegalArgumentException`. * `offset < 0` did not trigger validation and failed later with an `IndexOutOfBoundsException`. * With this change, both invalid cases are handled consistently and upfront. * fix: failing tests --- .../java/org/apache/commons/io/IOUtils.java | 60 +++++++------------ .../org/apache/commons/io/IOUtilsTest.java | 35 ++++++++++- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index a882d4d87cb..66d785885ee 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -2054,6 +2054,7 @@ public static LineIterator lineIterator(final Reader reader) { * @param input where to read input from. * @param buffer destination. * @return actual length read; may be less than requested if EOF was reached. + * @throws NullPointerException if {@code input} or {@code buffer} is null. * @throws IOException if a read error occurs. * @since 2.2 */ @@ -2074,40 +2075,19 @@ public static int read(final InputStream input, final byte[] buffer) throws IOEx * @param offset initial offset into buffer. * @param length length to read, must be >= 0. * @return actual length read; may be less than requested if EOF was reached. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if + * {@code offset + length} is greater than {@code buffer.length}. * @throws IOException if a read error occurs. * @since 2.2 */ public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { - if (length == 0) { - return 0; - } - return read(input::read, buffer, offset, length); - } - - /** - * Reads bytes from an input. This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case - * for subclasses of {@link InputStream}. - * - * @param input How to read input. - * @param buffer destination. - * @param offset initial offset into buffer. - * @param length length to read, must be >= 0. - * @return actual length read; may be less than requested if EOF was reached. - * @throws IllegalArgumentException if length is negative. - * @throws IOException if a read error occurs. - * @since 2.2 - */ - static int read(final IOTriFunction input, final byte[] buffer, final int offset, final int length) - throws IOException { - if (length < 0) { - throw new IllegalArgumentException("Length must not be negative: " + length); - } + checkFromIndexSize(buffer, offset, length); int remaining = length; while (remaining > 0) { final int location = length - remaining; - final int count = input.apply(buffer, offset + location, remaining); + final int count = input.read(buffer, offset + location, remaining); if (EOF == count) { break; } @@ -2172,15 +2152,15 @@ public static int read(final Reader reader, final char[] buffer) throws IOExcept * @param offset initial offset into buffer. * @param length length to read, must be >= 0. * @return actual length read; may be less than requested if EOF was reached. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if + * {@code offset + length} is greater than {@code buffer.length}. * @throws IOException if a read error occurs. * @since 2.2 */ public static int read(final Reader reader, final char[] buffer, final int offset, final int length) throws IOException { - if (length < 0) { - throw new IllegalArgumentException("Length must not be negative: " + length); - } + checkFromIndexSize(buffer, offset, length); int remaining = length; while (remaining > 0) { final int location = length - remaining; @@ -2202,9 +2182,9 @@ public static int read(final Reader reader, final char[] buffer, final int offse * * @param input where to read input from. * @param buffer destination. - * @throws IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code input} or {@code buffer} is null. * @throws EOFException if the number of bytes read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final InputStream input, final byte[] buffer) throws IOException { @@ -2222,9 +2202,11 @@ public static void readFully(final InputStream input, final byte[] buffer) throw * @param buffer destination. * @param offset initial offset into buffer. * @param length length to read, must be >= 0. - * @throws IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if + * {@code offset + length} is greater than {@code buffer.length}. * @throws EOFException if the number of bytes read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) @@ -2286,9 +2268,9 @@ public static void readFully(final ReadableByteChannel input, final ByteBuffer b * * @param reader where to read input from. * @param buffer destination. - * @throws IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. * @throws EOFException if the number of characters read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final Reader reader, final char[] buffer) throws IOException { @@ -2306,9 +2288,11 @@ public static void readFully(final Reader reader, final char[] buffer) throws IO * @param buffer destination. * @param offset initial offset into buffer. * @param length length to read, must be >= 0. - * @throws IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if + * {@code offset + length} is greater than {@code buffer.length}. * @throws EOFException if the number of characters read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length) diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 02574946bf8..a2164ce49d1 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -1195,6 +1195,31 @@ void testRead_ReadableByteChannel() throws Exception { } } + static Stream invalidRead_InputStream_Offset_ArgumentsProvider() { + final InputStream input = new ByteArrayInputStream(new byte[10]); + final byte[] b = new byte[10]; + return Stream.of( + // input is null + Arguments.of(null, b, 0, 1, NullPointerException.class), + // b is null + Arguments.of(input, null, 0, 1, NullPointerException.class), + // off is negative + Arguments.of(input, b, -1, 1, IndexOutOfBoundsException.class), + // len is negative + Arguments.of(input, b, 0, -1, IndexOutOfBoundsException.class), + // off + len is too big + Arguments.of(input, b, 1, 10, IndexOutOfBoundsException.class), + // off + len is too big + Arguments.of(input, b, 10, 1, IndexOutOfBoundsException.class) + ); + } + + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + void testRead_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + assertThrows(expected, () -> IOUtils.read(input, b, off, len)); + } + @Test void testReadFully_InputStream__ReturnByteArray() throws Exception { final byte[] bytes = "abcd1234".getBytes(StandardCharsets.UTF_8); @@ -1213,7 +1238,7 @@ void testReadFully_InputStream_ByteArray() throws Exception { final byte[] buffer = new byte[size]; final InputStream input = new ByteArrayInputStream(new byte[size]); - assertThrows(IllegalArgumentException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IllegalArgumentException"); + assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IndexOutOfBoundsException"); IOUtils.readFully(input, buffer, 0, 0); IOUtils.readFully(input, buffer, 0, size - 1); @@ -1260,7 +1285,7 @@ void testReadFully_Reader() throws Exception { IOUtils.readFully(input, buffer, 0, 0); IOUtils.readFully(input, buffer, 0, size - 3); - assertThrows(IllegalArgumentException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IllegalArgumentException"); + assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IndexOutOfBoundsException"); assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 5), "Should have failed with EOFException"); IOUtils.closeQuietly(input); } @@ -1274,6 +1299,12 @@ void testReadFully_Reader_Offset() throws Exception { IOUtils.closeQuietly(reader); } + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + void testReadFully_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + assertThrows(expected, () -> IOUtils.read(input, b, off, len)); + } + @Test void testReadLines_CharSequence() throws IOException { final File file = TestUtils.newFile(temporaryFolder, "lines.txt"); From 8178f48ed70b7c023f741a602b493e110880aa5b Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Sat, 4 Oct 2025 13:15:45 +0200 Subject: [PATCH 007/174] Fix inconsistent exception in `IOUtils.toByteArray` (#796) The implementation of `IOUtils.toByteArray(InputStream, int, int)` added in #776 throws different exceptions depending on the requested size: * For request sizes larger than the internal chunk size, it correctly throws an `EOFException`. * For smaller requests, it incorrectly throws a generic `IOException`. This PR makes the behavior consistent by always throwing an `EOFException` when the stream ends prematurely. Note: This also affects `RandomAccessFiles.read`. Its previous truncation behavior was undocumented and inconsistent with `RandomAccessFile.read` (which reads as much as possible). The new behavior is not explicitly documented here either, since it is unclear whether throwing on truncation is actually desirable. --- src/main/java/org/apache/commons/io/IOUtils.java | 3 ++- src/test/java/org/apache/commons/io/IOUtilsTest.java | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 66d785885ee..4d5b7d1a526 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -2941,6 +2941,7 @@ public static byte[] toByteArray(final InputStream input, final long size) throw * @param input the input to read, not null. * @param size the size of the input to read, where 0 < {@code size} <= length of input. * @return byte [] of length {@code size}. + * @throws EOFException if the end of the input is reached before reading {@code size} bytes. * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}. * @throws IllegalArgumentException if {@code size} is less than zero. */ @@ -2958,7 +2959,7 @@ static byte[] toByteArray(final IOTriFunction offset += read; } if (offset != size) { - throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size); + throw new EOFException("Unexpected read size, current: " + offset + ", expected: " + size); } return data; } diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index a2164ce49d1..9d99d10f214 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -158,7 +158,9 @@ static Stream testToByteArray_InputStream_Size_BufferSize_Throws() { Arguments.of(-1, 128, IllegalArgumentException.class), // Invalid buffer size Arguments.of(0, 0, IllegalArgumentException.class), - // Huge size: should not cause OutOfMemoryError + // Truncation with requested size < chunk size + Arguments.of(64, 128, EOFException.class), + // Truncation with requested size > chunk size Arguments.of(Integer.MAX_VALUE, 128, EOFException.class)); } @@ -1788,6 +1790,13 @@ void testToByteArray_InputStream_Size() throws Exception { } } + @Test + void testToByteArray_InputStream_Size_Truncated() throws Exception { + try (InputStream in = new NullInputStream(0)) { + assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1), "Should have failed with EOFException"); + } + } + @ParameterizedTest @MethodSource void testToByteArray_InputStream_Size_BufferSize_Succeeds(final byte[] data, final int size, final int bufferSize) throws IOException { From 6b41b2efbcf7e7dac52d2c485c9e1f5d0873c23b Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sat, 4 Oct 2025 07:17:15 -0400 Subject: [PATCH 008/174] IOUtils.toByteArray now throws EOFException when not enough data is available #796 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index fb68216e20a..3bcc4145197 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,6 +55,7 @@ The type attribute can be add,update,fix,remove. Deprecate IOUtils.readFully(InputStream, int) in favor of toByteArray(InputStream, int). IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Javadoc general improvements. + JIOUtils.toByteArray now throws EOFException when not enough data is available #796. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. From d190051aceefe8ba4eb1b79aa69d4ee8b502beff Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sat, 4 Oct 2025 07:49:05 -0400 Subject: [PATCH 009/174] Better exception messages Better unit test messages --- src/main/java/org/apache/commons/io/IOUtils.java | 13 +++++++------ .../commons/io/input/ReadAheadInputStream.java | 2 +- .../java/org/apache/commons/io/IOUtilsTest.java | 11 ++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 4d5b7d1a526..aac71be0fa5 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -2898,15 +2898,16 @@ public static byte[] toByteArray(final InputStream input, final int size) throws public static byte[] toByteArray(final InputStream input, final int size, final int chunkSize) throws IOException { Objects.requireNonNull(input, "input"); if (chunkSize <= 0) { - throw new IllegalArgumentException("Chunk size must be greater than zero: " + chunkSize); + throw new IllegalArgumentException(String.format("chunkSize <= 0, chunkSize = %,d", chunkSize)); } if (size <= chunkSize) { // throws if size < 0 return toByteArray(input::read, size); } final UnsynchronizedByteArrayOutputStream output = copyToOutputStream(input, size, chunkSize); - if (output.size() != size) { - throw new EOFException("Unexpected read size, current: " + output.size() + ", expected: " + size); + final int outSize = output.size(); + if (outSize != size) { + throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, outSize)); } return output.toByteArray(); } @@ -2930,7 +2931,7 @@ public static byte[] toByteArray(final InputStream input, final int size, final */ public static byte[] toByteArray(final InputStream input, final long size) throws IOException { if (size > Integer.MAX_VALUE) { - throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size); + throw new IllegalArgumentException(String.format("size > Integer.MAX_VALUE, size = %,d", size)); } return toByteArray(input, (int) size); } @@ -2947,7 +2948,7 @@ public static byte[] toByteArray(final InputStream input, final long size) throw */ static byte[] toByteArray(final IOTriFunction input, final int size) throws IOException { if (size < 0) { - throw new IllegalArgumentException("Size must be equal or greater than zero: " + size); + throw new IllegalArgumentException(String.format("size < 0, size = %,d", size)); } if (size == 0) { return EMPTY_BYTE_ARRAY; @@ -2959,7 +2960,7 @@ static byte[] toByteArray(final IOTriFunction offset += read; } if (offset != size) { - throw new EOFException("Unexpected read size, current: " + offset + ", expected: " + size); + throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, offset)); } return data; } diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index bcee009a431..57edd41bcb7 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -239,7 +239,7 @@ private ReadAheadInputStream(final InputStream inputStream, final int bufferSize final boolean shutdownExecutorService) { super(Objects.requireNonNull(inputStream, "inputStream")); if (bufferSizeInBytes <= 0) { - throw new IllegalArgumentException("bufferSizeInBytes should be greater than 0, but the value is " + bufferSizeInBytes); + throw new IllegalArgumentException(String.format("bufferSizeInBytes <= 0, bufferSizeInBytes = %,d", bufferSizeInBytes)); } this.executorService = Objects.requireNonNull(executorService, "executorService"); this.shutdownExecutorService = shutdownExecutorService; diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 9d99d10f214..9e9b6c8bfc8 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -1772,10 +1772,8 @@ void testToByteArray_InputStream_LongerThanIntegerMaxValue() throws Exception { @Test void testToByteArray_InputStream_NegativeSize() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { - final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, -1), - "Should have failed with IllegalArgumentException"); - assertTrue(exc.getMessage().startsWith("Size must be equal or greater than zero"), - "Exception message does not start with \"Size must be equal or greater than zero\""); + final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, -1)); + assertTrue(exc.getMessage().startsWith("size < 0"), exc.getMessage()); } } @@ -1820,7 +1818,7 @@ void testToByteArray_InputStream_SizeIllegal() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { final IOException exc = assertThrows(IOException.class, () -> IOUtils.toByteArray(fin, testFile.length() + 1), "Should have failed with IOException"); - assertTrue(exc.getMessage().startsWith("Unexpected read size"), "Exception message does not start with \"Unexpected read size\""); + assertTrue(exc.getMessage().startsWith("Expected read size"), exc.getMessage()); } } @@ -1829,8 +1827,7 @@ void testToByteArray_InputStream_SizeLong() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, (long) Integer.MAX_VALUE + 1), "Should have failed with IllegalArgumentException"); - assertTrue(exc.getMessage().startsWith("Size cannot be greater than Integer max value"), - "Exception message does not start with \"Size cannot be greater than Integer max value\""); + assertTrue(exc.getMessage().startsWith("size > Integer.MAX_VALUE"), exc.getMessage()); } } From 26e5aa9661a72bfd9697fb384ca72f58e5d672e9 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sat, 4 Oct 2025 07:57:41 -0400 Subject: [PATCH 010/174] Don't override JUnit messages to say the same thing Reduce vertical space --- .../org/apache/commons/io/IOUtilsTest.java | 96 +++++-------------- 1 file changed, 25 insertions(+), 71 deletions(-) diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 9e9b6c8bfc8..8a830ec316a 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -683,13 +683,10 @@ void testConsumeReader() throws Exception { final long size = (long) Integer.MAX_VALUE + (long) 1; final Reader in = new NullReader(size); final Writer out = NullWriter.INSTANCE; - // Test copy() method assertEquals(-1, IOUtils.copy(in, out)); - // reset the input in.close(); - // Test consume() method assertEquals(size, IOUtils.consume(in), "consume()"); } @@ -913,12 +910,9 @@ void testCopy_ByteArray_OutputStream() throws Exception { // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid. in = IOUtils.toByteArray(fin); } - try (OutputStream fout = Files.newOutputStream(destination.toPath())) { CopyUtils.copy(in, fout); - fout.flush(); - TestUtils.checkFile(destination, testFile); TestUtils.checkWrite(fout); } @@ -933,7 +927,6 @@ void testCopy_ByteArray_Writer() throws Exception { // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid. in = IOUtils.toByteArray(fin); } - try (Writer fout = Files.newBufferedWriter(destination.toPath())) { CopyUtils.copy(in, fout); fout.flush(); @@ -951,11 +944,9 @@ void testCopy_String_Writer() throws Exception { // Create our String. Rely on testReaderToString() to make sure this is valid. str = IOUtils.toString(fin); } - try (Writer fout = Files.newBufferedWriter(destination.toPath())) { CopyUtils.copy(str, fout); fout.flush(); - TestUtils.checkFile(destination, testFile); TestUtils.checkWrite(fout); } @@ -970,19 +961,16 @@ void testCopyLarge_CharExtraLength() throws IOException { // Create streams is = new CharArrayReader(carr); os = new CharArrayWriter(); - // Test our copy method // for extra length, it reads till EOF assertEquals(200, IOUtils.copyLarge(is, os, 0, 2000)); final char[] oarr = os.toCharArray(); - // check that output length is correct assertEquals(200, oarr.length); // check that output data corresponds to input data assertEquals(1, oarr[1]); assertEquals(79, oarr[79]); assertEquals((char) -1, oarr[80]); - } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); @@ -997,18 +985,15 @@ void testCopyLarge_CharFullLength() throws IOException { // Create streams is = new CharArrayReader(carr); os = new CharArrayWriter(); - // Test our copy method assertEquals(200, IOUtils.copyLarge(is, os, 0, -1)); final char[] oarr = os.toCharArray(); - // check that output length is correct assertEquals(200, oarr.length); // check that output data corresponds to input data assertEquals(1, oarr[1]); assertEquals(79, oarr[79]); assertEquals((char) -1, oarr[80]); - } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); @@ -1023,18 +1008,15 @@ void testCopyLarge_CharNoSkip() throws IOException { // Create streams is = new CharArrayReader(carr); os = new CharArrayWriter(); - // Test our copy method assertEquals(100, IOUtils.copyLarge(is, os, 0, 100)); final char[] oarr = os.toCharArray(); - // check that output length is correct assertEquals(100, oarr.length); // check that output data corresponds to input data assertEquals(1, oarr[1]); assertEquals(79, oarr[79]); assertEquals((char) -1, oarr[80]); - } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); @@ -1049,18 +1031,15 @@ void testCopyLarge_CharSkip() throws IOException { // Create streams is = new CharArrayReader(carr); os = new CharArrayWriter(); - // Test our copy method assertEquals(100, IOUtils.copyLarge(is, os, 10, 100)); final char[] oarr = os.toCharArray(); - // check that output length is correct assertEquals(100, oarr.length); // check that output data corresponds to input data assertEquals(11, oarr[1]); assertEquals(79, oarr[69]); assertEquals((char) -1, oarr[70]); - } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); @@ -1076,15 +1055,12 @@ void testCopyLarge_CharSkipInvalid() { @Test void testCopyLarge_ExtraLength() throws IOException { - try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); - ByteArrayOutputStream os = new ByteArrayOutputStream()) { + try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Create streams - // Test our copy method // for extra length, it reads till EOF assertEquals(200, IOUtils.copyLarge(is, os, 0, 2000)); final byte[] oarr = os.toByteArray(); - // check that output length is correct assertEquals(200, oarr.length); // check that output data corresponds to input data @@ -1096,12 +1072,10 @@ void testCopyLarge_ExtraLength() throws IOException { @Test void testCopyLarge_FullLength() throws IOException { - try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); - ByteArrayOutputStream os = new ByteArrayOutputStream()) { + try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Test our copy method assertEquals(200, IOUtils.copyLarge(is, os, 0, -1)); final byte[] oarr = os.toByteArray(); - // check that output length is correct assertEquals(200, oarr.length); // check that output data corresponds to input data @@ -1113,12 +1087,10 @@ void testCopyLarge_FullLength() throws IOException { @Test void testCopyLarge_NoSkip() throws IOException { - try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); - ByteArrayOutputStream os = new ByteArrayOutputStream()) { + try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Test our copy method assertEquals(100, IOUtils.copyLarge(is, os, 0, 100)); final byte[] oarr = os.toByteArray(); - // check that output length is correct assertEquals(100, oarr.length); // check that output data corresponds to input data @@ -1130,12 +1102,10 @@ void testCopyLarge_NoSkip() throws IOException { @Test void testCopyLarge_Skip() throws IOException { - try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); - ByteArrayOutputStream os = new ByteArrayOutputStream()) { + try (ByteArrayInputStream is = new ByteArrayInputStream(iarr); ByteArrayOutputStream os = new ByteArrayOutputStream()) { // Test our copy method assertEquals(100, IOUtils.copyLarge(is, os, 10, 100)); final byte[] oarr = os.toByteArray(); - // check that output length is correct assertEquals(100, oarr.length); // check that output data corresponds to input data @@ -1162,18 +1132,15 @@ void testCopyLarge_SkipWithInvalidOffset() throws IOException { // Create streams is = new ByteArrayInputStream(iarr); os = new ByteArrayOutputStream(); - // Test our copy method assertEquals(100, IOUtils.copyLarge(is, os, -10, 100)); final byte[] oarr = os.toByteArray(); - // check that output length is correct assertEquals(100, oarr.length); // check that output data corresponds to input data assertEquals(1, oarr[1]); assertEquals(79, oarr[79]); assertEquals(-1, oarr[80]); - } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); @@ -1191,7 +1158,7 @@ void testRead_ReadableByteChannel() throws Exception { assertEquals(0, buffer.remaining()); assertEquals(0, input.read(buffer)); buffer.clear(); - assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer), "Should have failed with EOFException"); + assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer)); } finally { IOUtils.closeQuietly(input, fileInputStream); } @@ -1226,11 +1193,8 @@ void testRead_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b void testReadFully_InputStream__ReturnByteArray() throws Exception { final byte[] bytes = "abcd1234".getBytes(StandardCharsets.UTF_8); final ByteArrayInputStream stream = new ByteArrayInputStream(bytes); - final byte[] result = IOUtils.readFully(stream, bytes.length); - IOUtils.closeQuietly(stream); - assertEqualContent(result, bytes); } @@ -1240,11 +1204,11 @@ void testReadFully_InputStream_ByteArray() throws Exception { final byte[] buffer = new byte[size]; final InputStream input = new ByteArrayInputStream(new byte[size]); - assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IndexOutOfBoundsException"); + assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1)); IOUtils.readFully(input, buffer, 0, 0); IOUtils.readFully(input, buffer, 0, size - 1); - assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 2), "Should have failed with EOFException"); + assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 2)); IOUtils.closeQuietly(input); } @@ -1273,7 +1237,7 @@ void testReadFully_ReadableByteChannel() throws Exception { assertEquals(0, input.read(buffer)); IOUtils.readFully(input, buffer); buffer.clear(); - assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer), "Should have failed with EOFxception"); + assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer)); } finally { IOUtils.closeQuietly(input, fileInputStream); } @@ -1287,8 +1251,8 @@ void testReadFully_Reader() throws Exception { IOUtils.readFully(input, buffer, 0, 0); IOUtils.readFully(input, buffer, 0, size - 3); - assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1), "Should have failed with IndexOutOfBoundsException"); - assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 5), "Should have failed with EOFException"); + assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.readFully(input, buffer, 0, -1)); + assertThrows(EOFException.class, () -> IOUtils.readFully(input, buffer, 0, 5)); IOUtils.closeQuietly(input); } @@ -1628,13 +1592,11 @@ void testSkip_ReadableByteChannel() throws Exception { @Test void testSkipFully_InputStream() throws Exception { final int size = 1027; - try (InputStream input = new ByteArrayInputStream(new byte[size])) { - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); - + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1)); IOUtils.skipFully(input, 0); IOUtils.skipFully(input, size - 1); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2), "Should have failed with IOException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2)); } } @@ -1643,11 +1605,10 @@ void testSkipFully_InputStream_Buffer_New_bytes() throws Exception { final int size = 1027; final Supplier bas = () -> new byte[size]; try (InputStream input = new ByteArrayInputStream(new byte[size])) { - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException"); - + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas)); IOUtils.skipFully(input, 0, bas); IOUtils.skipFully(input, size - 1, bas); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas)); } } @@ -1657,11 +1618,10 @@ void testSkipFully_InputStream_Buffer_Reuse_bytes() throws Exception { final byte[] ba = new byte[size]; final Supplier bas = () -> ba; try (InputStream input = new ByteArrayInputStream(new byte[size])) { - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException"); - + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas)); IOUtils.skipFully(input, 0, bas); IOUtils.skipFully(input, size - 1, bas); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas)); } } @@ -1670,11 +1630,10 @@ void testSkipFully_InputStream_Buffer_Reuse_ThreadLocal() throws Exception { final int size = 1027; final ThreadLocal tl = ThreadLocal.withInitial(() -> new byte[size]); try (InputStream input = new ByteArrayInputStream(new byte[size])) { - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, tl::get), "Should have failed with IllegalArgumentException"); - + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, tl::get)); IOUtils.skipFully(input, 0, tl::get); IOUtils.skipFully(input, size - 1, tl::get); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, tl::get), "Should have failed with IOException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, tl::get)); } } @@ -1683,10 +1642,10 @@ void testSkipFully_ReadableByteChannel() throws Exception { final FileInputStream fileInputStream = new FileInputStream(testFile); final FileChannel fileChannel = fileInputStream.getChannel(); try { - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(fileChannel, -1), "Should have failed with IllegalArgumentException"); + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(fileChannel, -1)); IOUtils.skipFully(fileChannel, 0); IOUtils.skipFully(fileChannel, FILE_SIZE - 1); - assertThrows(IOException.class, () -> IOUtils.skipFully(fileChannel, 2), "Should have failed with IOException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(fileChannel, 2)); } finally { IOUtils.closeQuietly(fileChannel, fileInputStream); } @@ -1698,8 +1657,8 @@ void testSkipFully_Reader() throws Exception { try (Reader input = new CharArrayReader(new char[size])) { IOUtils.skipFully(input, 0); IOUtils.skipFully(input, size - 3); - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 5), "Should have failed with IOException"); + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1)); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 5)); } } @@ -1711,7 +1670,6 @@ void testStringToOutputStream() throws Exception { // Create our String. Rely on testReaderToString() to make sure this is valid. str = IOUtils.toString(fin); } - try (OutputStream fout = Files.newOutputStream(destination.toPath())) { CopyUtils.copy(str, fout); // Note: this method *does* flush. It is equivalent to: @@ -1720,7 +1678,6 @@ void testStringToOutputStream() throws Exception { // _out.flush(); // out = fout; // note: we don't flush here; this IOUtils method does it for us - TestUtils.checkFile(destination, testFile); TestUtils.checkWrite(fout); } @@ -1791,7 +1748,7 @@ void testToByteArray_InputStream_Size() throws Exception { @Test void testToByteArray_InputStream_Size_Truncated() throws Exception { try (InputStream in = new NullInputStream(0)) { - assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1), "Should have failed with EOFException"); + assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1)); } } @@ -1816,8 +1773,7 @@ void testToByteArray_InputStream_Size_BufferSize_Throws( @Test void testToByteArray_InputStream_SizeIllegal() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { - final IOException exc = assertThrows(IOException.class, () -> IOUtils.toByteArray(fin, testFile.length() + 1), - "Should have failed with IOException"); + final IOException exc = assertThrows(IOException.class, () -> IOUtils.toByteArray(fin, testFile.length() + 1)); assertTrue(exc.getMessage().startsWith("Expected read size"), exc.getMessage()); } } @@ -1825,8 +1781,7 @@ void testToByteArray_InputStream_SizeIllegal() throws Exception { @Test void testToByteArray_InputStream_SizeLong() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { - final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, (long) Integer.MAX_VALUE + 1), - "Should have failed with IllegalArgumentException"); + final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, (long) Integer.MAX_VALUE + 1)); assertTrue(exc.getMessage().startsWith("size > Integer.MAX_VALUE"), exc.getMessage()); } } @@ -1864,7 +1819,6 @@ void testToByteArray_String() throws Exception { try (Reader fin = Files.newBufferedReader(testFilePath)) { // Create our String. Rely on testReaderToString() to make sure this is valid. final String str = IOUtils.toString(fin); - final byte[] out = IOUtils.toByteArray(str); assertEqualContent(str.getBytes(), out); } From 66706b4961259d7a5b2e4c32783ced10e12a3402 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Tue, 7 Oct 2025 08:49:59 -0400 Subject: [PATCH 011/174] Javadoc --- .../org/apache/commons/io/filefilter/FileFilterUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java index 5e37676ac9c..937895c822c 100644 --- a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java +++ b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java @@ -153,7 +153,7 @@ public static IOFileFilter and(final IOFileFilter... filters) { * @return a filter that ANDs the two specified filters * @see #and(IOFileFilter...) * @see AndFileFilter - * @deprecated use {@link #and(IOFileFilter...)} + * @deprecated Use {@link #and(IOFileFilter...)} */ @Deprecated public static IOFileFilter andFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { @@ -603,7 +603,7 @@ public static IOFileFilter or(final IOFileFilter... filters) { * @return a filter that ORs the two specified filters * @see #or(IOFileFilter...) * @see OrFileFilter - * @deprecated use {@link #or(IOFileFilter...)} + * @deprecated Use {@link #or(IOFileFilter...)} */ @Deprecated public static IOFileFilter orFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { From eed5803bf23ab83b6506cfda48fae7c351d51ef2 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 7 Oct 2025 09:43:16 -0400 Subject: [PATCH 012/174] Javadoc --- .../java/org/apache/commons/io/CopyUtils.java | 6 ++-- .../java/org/apache/commons/io/FileUtils.java | 12 +++---- .../java/org/apache/commons/io/HexDump.java | 2 +- .../java/org/apache/commons/io/IOUtils.java | 34 +++++++++---------- .../commons/io/charset/CharsetDecoders.java | 2 +- .../commons/io/charset/CharsetEncoders.java | 2 +- .../io/filefilter/MagicNumberFileFilter.java | 2 +- .../commons/io/input/ReaderInputStream.java | 4 +-- .../io/input/ReversedLinesFileReader.java | 2 +- .../org/apache/commons/io/input/Tailer.java | 2 +- .../output/AbstractByteArrayOutputStream.java | 2 +- .../commons/io/output/LockableFileWriter.java | 2 +- .../commons/io/output/WriterOutputStream.java | 6 ++-- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index ad426952e4e..e22adef83be 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -179,7 +179,7 @@ public static int copy(final InputStream input, final OutputStream output) throw * Copies and convert bytes from an {@link InputStream} to chars on a * {@link Writer}. *

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset} for byte-to-char conversion. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

* * @param input the {@link InputStream} to read from @@ -221,7 +221,7 @@ public static void copy( * Serialize chars from a {@link Reader} to bytes on an * {@link OutputStream}, and flush the {@link OutputStream}. *

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset} for byte-to-char conversion. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

* * @param input the {@link Reader} to read from @@ -293,7 +293,7 @@ public static int copy( * {@link OutputStream}, and * flush the {@link OutputStream}. *

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset} for byte-to-char conversion. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

* * @param input the {@link String} to read from diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index 203fe84bfc5..523c2c1fd26 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -2755,7 +2755,7 @@ public static byte[] readFileToByteArray(final File file) throws IOException { } /** - * Reads the contents of a file into a String using the virtual machine's {@link Charset#defaultCharset() default charset}. The + * Reads the contents of a file into a String using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. The * file is always closed. * * @param file the file to read, must not be {@code null}. @@ -2804,7 +2804,7 @@ public static String readFileToString(final File file, final String charsetName) } /** - * Reads the contents of a file line by line to a List of Strings using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Reads the contents of a file line by line to a List of Strings using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * The file is always closed. * * @param file the file to read, must not be {@code null}. @@ -3212,7 +3212,7 @@ public static boolean waitFor(final File file, final int seconds) { } /** - * Writes a CharSequence to a file creating the file if it does not exist using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Writes a CharSequence to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param file the file to write. * @param data the content to write to the file. @@ -3226,7 +3226,7 @@ public static void write(final File file, final CharSequence data) throws IOExce } /** - * Writes a CharSequence to a file creating the file if it does not exist using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Writes a CharSequence to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param file the file to write. * @param data the content to write to the file. @@ -3501,7 +3501,7 @@ public static void writeLines(final File file, final String charsetName, final C } /** - * Writes a String to a file creating the file if it does not exist using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Writes a String to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param file the file to write * @param data the content to write to the file @@ -3514,7 +3514,7 @@ public static void writeStringToFile(final File file, final String data) throws } /** - * Writes a String to a file creating the file if it does not exist using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Writes a String to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param file the file to write * @param data the content to write to the file diff --git a/src/main/java/org/apache/commons/io/HexDump.java b/src/main/java/org/apache/commons/io/HexDump.java index cb7efa7b2f2..41c026b2fb1 100644 --- a/src/main/java/org/apache/commons/io/HexDump.java +++ b/src/main/java/org/apache/commons/io/HexDump.java @@ -169,7 +169,7 @@ public static void dump(final byte[] data, final long offset, * data array are dumped. *

*

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset}. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* * @param data the byte array to be dumped diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index aac71be0fa5..52eb5c971fc 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1269,7 +1269,7 @@ public static long copy(final InputStream inputStream, final OutputStream output /** * Copies bytes from an {@link InputStream} to chars on a - * {@link Writer} using the virtual machine's {@link Charset#defaultCharset() default charset}. + * {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method buffers the input internally, so there is no need to use a * {@link BufferedInputStream}. @@ -1421,8 +1421,8 @@ public static long copy(final Reader reader, final Appendable output, final Char } /** - * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the the virtual machine's {@link Charset#defaultCharset() default charset}, - * and calling flush. + * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the the virtual machine's {@linkplain Charset#defaultCharset() default + * charset}, and calling flush. *

* This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

@@ -2319,7 +2319,7 @@ public static List readLines(final CharSequence csq) throws UncheckedIOE /** * Gets the contents of an {@link InputStream} as a list of Strings, - * one entry per line, using the virtual machine's {@link Charset#defaultCharset() default charset}. + * one entry per line, using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method buffers the input internally, so there is no need to use a * {@link BufferedInputStream}. @@ -2967,7 +2967,7 @@ static byte[] toByteArray(final IOTriFunction /** * Gets the contents of a {@link Reader} as a {@code byte[]} - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method buffers the input internally, so there is no need to use a * {@link BufferedReader}. @@ -3032,7 +3032,7 @@ public static byte[] toByteArray(final Reader reader, final String charsetName) /** * Gets the contents of a {@link String} as a {@code byte[]} - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This is the same as {@link String#getBytes()}. *

@@ -3093,7 +3093,7 @@ public static byte[] toByteArray(final URLConnection urlConnection) throws IOExc /** * Gets the contents of an {@link InputStream} as a character array - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method buffers the input internally, so there is no need to use a * {@link BufferedInputStream}. @@ -3178,7 +3178,7 @@ public static char[] toCharArray(final Reader reader) throws IOException { /** * Converts the specified CharSequence to an input stream, encoded as bytes - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param input the CharSequence to convert. * @return an input stream. @@ -3223,7 +3223,7 @@ public static InputStream toInputStream(final CharSequence input, final String c /** * Converts the specified string to an input stream, encoded as bytes - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param input the string to convert. * @return an input stream. @@ -3268,7 +3268,7 @@ public static InputStream toInputStream(final String input, final String charset /** * Gets the contents of a {@code byte[]} as a String - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param input the byte array to read. * @return the requested String. @@ -3300,7 +3300,7 @@ public static String toString(final byte[] input, final String charsetName) { /** * Gets the contents of an {@link InputStream} as a String - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method buffers the input internally, so there is no need to use a * {@link BufferedInputStream}. @@ -3429,7 +3429,7 @@ public static String toString(final Reader reader) throws IOException { } /** - * Gets the contents at the given URI using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Gets the contents at the given URI using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param uri The URI source. * @return The contents of the URL as a String. @@ -3470,7 +3470,7 @@ public static String toString(final URI uri, final String charsetName) throws IO } /** - * Gets the contents at the given URL using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Gets the contents at the given URL using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param url The URL source. * @return The contents of the URL as a String. @@ -3528,7 +3528,7 @@ public static void write(final byte[] data, final OutputStream output) /** * Writes bytes from a {@code byte[]} to chars on a {@link Writer} - * using the virtual machine's {@link Charset#defaultCharset() default charset}. + * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method uses {@link String#String(byte[])}. *

@@ -3591,7 +3591,7 @@ public static void write(final byte[] data, final Writer writer, final String ch /** * Writes chars from a {@code char[]} to bytes on an {@link OutputStream}. *

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset}. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* * @param data the char array to write, do not modify during output, null ignored. @@ -3742,7 +3742,7 @@ public static void write(final CharSequence data, final Writer writer) throws IO /** * Writes chars from a {@link String} to bytes on an - * {@link OutputStream} using the virtual machine's {@link Charset#defaultCharset() default charset}. + * {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* This method uses {@link String#getBytes()}. *

@@ -3941,7 +3941,7 @@ public static void writeChunked(final char[] data, final Writer writer) throws I /** * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the virtual machine's - * {@link Charset#defaultCharset() default charset} and the specified line ending. + * {@linkplain Charset#defaultCharset() default charset} and the specified line ending. * * @param lines the lines to write, null entries produce blank lines. * @param lineEnding the line separator to use, null is system default. diff --git a/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java b/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java index 8595be79e8a..a8aa9a3d50b 100644 --- a/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java +++ b/src/main/java/org/apache/commons/io/charset/CharsetDecoders.java @@ -30,7 +30,7 @@ public final class CharsetDecoders { /** * Returns the given non-null CharsetDecoder or a new default CharsetDecoder. *

- * Null input maps to the virtual machine's {@link Charset#defaultCharset() default charset} decoder. + * Null input maps to the virtual machine's {@linkplain Charset#defaultCharset() default charset} decoder. *

* * @param charsetDecoder The CharsetDecoder to test. diff --git a/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java b/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java index d0f9cd04be1..a1fff5cf1f3 100644 --- a/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java +++ b/src/main/java/org/apache/commons/io/charset/CharsetEncoders.java @@ -31,7 +31,7 @@ public final class CharsetEncoders { /** * Returns the given non-null CharsetEncoder or a new default CharsetEncoder. *

- * Null input maps to the virtual machine's {@link Charset#defaultCharset() default charset} decoder. + * Null input maps to the virtual machine's {@linkplain Charset#defaultCharset() default charset} decoder. *

* * @param charsetEncoder The CharsetEncoder to test. diff --git a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java index 79aa55d68c1..5868af39a32 100644 --- a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java @@ -218,7 +218,7 @@ public MagicNumberFileFilter(final String magicNumber) { * MagicNumberFileFilter tarFileFilter = MagicNumberFileFilter("ustar", 257); * *

- * This method uses the virtual machine's {@link Charset#defaultCharset() default charset}. + * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* * @param magicNumber the magic number to look for in the file. 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 4d22d28f891..09d7bbaa1a8 100644 --- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java @@ -225,8 +225,8 @@ private ReaderInputStream(final Builder builder) throws IOException { } /** - * Constructs a new {@link ReaderInputStream} that uses the virtual machine's {@link Charset#defaultCharset() default charset} with a default input buffer - * size of {@value IOUtils#DEFAULT_BUFFER_SIZE} characters. + * Constructs a new {@link ReaderInputStream} that uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} with a default input + * buffer size of {@value IOUtils#DEFAULT_BUFFER_SIZE} characters. * * @param reader the target {@link Reader} * @deprecated Use {@link ReaderInputStream#builder()} instead 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 f87b109abb9..e88606d9e76 100644 --- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java @@ -354,7 +354,7 @@ private ReversedLinesFileReader(final Builder builder) throws IOException { } /** - * Constructs a ReversedLinesFileReader with default block size of 4KB and the virtual machine's {@link Charset#defaultCharset() default charset}. + * Constructs a ReversedLinesFileReader with default block size of 4KB and the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param file the file to be read * @throws IOException if an I/O error occurs. diff --git a/src/main/java/org/apache/commons/io/input/Tailer.java b/src/main/java/org/apache/commons/io/input/Tailer.java index 4d9fe9c4751..620ba6febcd 100644 --- a/src/main/java/org/apache/commons/io/input/Tailer.java +++ b/src/main/java/org/apache/commons/io/input/Tailer.java @@ -495,7 +495,7 @@ public String toString() { private static final String RAF_READ_ONLY_MODE = "r"; /** - * The the virtual machine's {@link Charset#defaultCharset() default charset} used for reading files. + * The the virtual machine's {@linkplain Charset#defaultCharset() default charset} used for reading files. */ private static final Charset DEFAULT_CHARSET = Charset.defaultCharset(); diff --git a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java index 6b095474fb2..dc2de64a4a2 100644 --- a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java @@ -276,7 +276,7 @@ protected InputStream toInputStream(final InputStreamCon } /** - * Gets the current contents of this byte stream as a string using the virtual machine's {@link Charset#defaultCharset() default charset}. + * Gets the current contents of this byte stream as a string using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @return the contents of the byte array as a String. * @see java.io.ByteArrayOutputStream#toString() 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 f15048e5c0e..1ee9391af8f 100644 --- a/src/main/java/org/apache/commons/io/output/LockableFileWriter.java +++ b/src/main/java/org/apache/commons/io/output/LockableFileWriter.java @@ -204,7 +204,7 @@ public LockableFileWriter(final File file, final boolean append) throws IOExcept /** * Constructs a LockableFileWriter. *

- * The new instance uses the virtual machine's {@link Charset#defaultCharset() default charset}. + * The new instance uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

* * @param file the file to write to, not null. diff --git a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java index d17318f79b6..9292aaf70e8 100644 --- a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java @@ -251,9 +251,9 @@ private WriterOutputStream(final Builder builder) throws IOException { } /** - * Constructs a new {@link WriterOutputStream} that uses the virtual machine's {@link Charset#defaultCharset() default charset} and with a default output - * buffer size of {@value #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when {@link #flush()} or {@link #close()} is - * called. + * Constructs a new {@link WriterOutputStream} that uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} and with a default + * output buffer size of {@value #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when {@link #flush()} or + * {@link #close()} is called. * * @param writer the target {@link Writer}. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. From c174b656695569f6817f0d877447ce9ec555d98b Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Wed, 8 Oct 2025 14:59:04 -0400 Subject: [PATCH 013/174] Bump org.apache.commons:commons-parent from 88 to 89 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c356baf502a..10db84b657f 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 88 + 89 4.0.0 commons-io diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3bcc4145197..cec7600b7c5 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -72,7 +72,7 @@ The type attribute can be add,update,fix,remove. Add CloseShieldChannel to close-shielded NIO Channels #786. Added IOUtils.checkFromIndexSize as a Java 8 backport of Objects.checkFromIndexSize #790. - Bump org.apache.commons:commons-parent from 85 to 88 #774, #783. + Bump org.apache.commons:commons-parent from 85 to 89 #774, #783. [test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0. [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.7 #769. [test] Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. From 806ada585296d5bd1043d581e133242c29072a7e Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Wed, 8 Oct 2025 14:59:19 -0400 Subject: [PATCH 014/174] Fix typos --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index cec7600b7c5..302b397962e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,7 +55,7 @@ The type attribute can be add,update,fix,remove. Deprecate IOUtils.readFully(InputStream, int) in favor of toByteArray(InputStream, int). IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Javadoc general improvements. - JIOUtils.toByteArray now throws EOFException when not enough data is available #796. + IOUtils.toByteArray() now throws EOFException when not enough data is available #796. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. From 5ad31b0c1a3f670b2eac34747218a25d493d7bc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 07:22:58 +0200 Subject: [PATCH 015/174] Bump github/codeql-action from 3.30.6 to 4.30.7 (#797) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.30.6 to 4.30.7. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/64d10c13136e1c5bce3e5fbde8d4906eeaafc885...e296a935590eb16afc0c0108289f68c87e2a89a5) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.30.7 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index db18ec4ae56..4d91dcc9f39 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 + uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 + uses: github/codeql-action/autobuild@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 + uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 3b7d3020e33..0de672c8692 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # 3.29.5 + uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 with: sarif_file: results.sarif From 12084ca7597f3e35f7d6d2cb8f6de646eab54f38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 07:23:56 +0200 Subject: [PATCH 016/174] Bump commons.bytebuddy.version from 1.17.7 to 1.17.8 (#798) Bumps `commons.bytebuddy.version` from 1.17.7 to 1.17.8. Updates `net.bytebuddy:byte-buddy` from 1.17.7 to 1.17.8 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.7...byte-buddy-1.17.8) Updates `net.bytebuddy:byte-buddy-agent` from 1.17.7 to 1.17.8 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.7...byte-buddy-1.17.8) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.17.8 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.17.8 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 10db84b657f..2f2162f800e 100644 --- a/pom.xml +++ b/pom.xml @@ -146,7 +146,7 @@ file comparators, endian transformation classes, and much more. https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ site-content - 1.17.7 + 1.17.8 false true From e19519ad1a61ec6852601d28ffe94a8967e4e3e0 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Fri, 10 Oct 2025 06:58:55 -0400 Subject: [PATCH 017/174] [test] Bump commons.bytebuddy.version from 1.17.7 to 1.17.8 --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 302b397962e..ecee3aeca01 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -74,7 +74,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 85 to 89 #774, #783. [test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0. - [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.7 #769. + [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.8 #769. [test] Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. Inline private constant field ProxyInputStream.exceptionHandler #780. From b95cbfa29df2928578a133b395a3e03dd05658fb Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sat, 11 Oct 2025 06:59:52 -0400 Subject: [PATCH 018/174] PMD: Discontinue using Rule name category/java/errorprone.xml/UselessOperationOnImmutable as it is scheduled for removal from PMD. PMD 8.0.0 will remove support for this Rule. --- src/conf/maven-pmd-plugin.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/conf/maven-pmd-plugin.xml b/src/conf/maven-pmd-plugin.xml index 215ac295ede..9d51e182ff9 100644 --- a/src/conf/maven-pmd-plugin.xml +++ b/src/conf/maven-pmd-plugin.xml @@ -78,7 +78,6 @@ under the License. - From 2542ebc485b095931bb9215a1715554a2bfd77de Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Tue, 14 Oct 2025 20:58:57 +0200 Subject: [PATCH 019/174] Fixes interface discovery in `CloseShieldChannel` (#800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR is split from #799. The `CloseShieldChannel` implementation only inspects interfaces **directly** implemented by the given channel’s class, ignoring those inherited from its superclasses. As a result, proxies for types such as `FileChannel` does not expose any of the interfaces declared on `FileChannel` itself. --- .../io/channels/CloseShieldChannel.java | 10 +++++--- .../io/channels/CloseShieldChannelTest.java | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java index a9a462da73b..bde0feb25cc 100644 --- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java +++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java @@ -40,11 +40,15 @@ public final class CloseShieldChannel { private static final Class[] EMPTY = {}; private static Set> collectChannelInterfaces(final Class type, final Set> out) { + Class currentType = type; // Visit interfaces - for (final Class iface : type.getInterfaces()) { - if (Channel.class.isAssignableFrom(iface) && out.add(iface)) { - collectChannelInterfaces(iface, out); + while (currentType != null) { + for (final Class iface : currentType.getInterfaces()) { + if (Channel.class.isAssignableFrom(iface) && out.add(iface)) { + collectChannelInterfaces(iface, out); + } } + currentType = currentType.getSuperclass(); } return out; } diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java index ac7e85b7a89..42a23f0af1c 100644 --- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -32,11 +33,13 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.io.IOException; import java.nio.channels.AsynchronousByteChannel; import java.nio.channels.AsynchronousChannel; import java.nio.channels.ByteChannel; import java.nio.channels.Channel; import java.nio.channels.ClosedChannelException; +import java.nio.channels.FileChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.InterruptibleChannel; import java.nio.channels.MulticastChannel; @@ -45,9 +48,12 @@ import java.nio.channels.ScatteringByteChannel; import java.nio.channels.SeekableByteChannel; import java.nio.channels.WritableByteChannel; +import java.nio.file.Path; import java.util.stream.Stream; +import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -280,4 +286,22 @@ void testWritableByteChannelMethods() throws Exception { assertThrows(ClosedChannelException.class, () -> shield.write(null)); verifyNoMoreInteractions(channel); } + + @Test + void testCorrectlyDetectsInterfaces(@TempDir Path tempDir) throws IOException { + final Path testFile = tempDir.resolve("test.txt"); + FileUtils.touch(testFile.toFile()); + try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { + assertInstanceOf(SeekableByteChannel.class, shield); + assertInstanceOf(GatheringByteChannel.class, shield); + assertInstanceOf(WritableByteChannel.class, shield); + assertInstanceOf(ScatteringByteChannel.class, shield); + assertInstanceOf(ReadableByteChannel.class, shield); + assertInstanceOf(InterruptibleChannel.class, shield); + assertInstanceOf(ByteChannel.class, shield); + assertInstanceOf(Channel.class, shield); + // These are not interfaces, so can not be implemented + assertFalse(shield instanceof FileChannel, "not FileChannel"); + } + } } From a0a6db8d55928b02888351fe40257bcd0d871095 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 14 Oct 2025 15:00:55 -0400 Subject: [PATCH 020/174] Fix interface discovery in `CloseShieldChannel` #800 Sort members --- src/changes/changes.xml | 1 + .../io/channels/CloseShieldChannelTest.java | 36 +++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ecee3aeca01..ead8994de83 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,6 +56,7 @@ The type attribute can be add,update,fix,remove. IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Javadoc general improvements. IOUtils.toByteArray() now throws EOFException when not enough data is available #796. + Fix interface discovery in `CloseShieldChannel` #800. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java index 42a23f0af1c..47d04df95d6 100644 --- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java @@ -119,6 +119,24 @@ void testCloseIsShielded(final Class channelClass) throws Exc verify(channel, times(2)).isOpen(); } + @Test + void testCorrectlyDetectsInterfaces(@TempDir Path tempDir) throws IOException { + final Path testFile = tempDir.resolve("test.txt"); + FileUtils.touch(testFile.toFile()); + try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { + assertInstanceOf(SeekableByteChannel.class, shield); + assertInstanceOf(GatheringByteChannel.class, shield); + assertInstanceOf(WritableByteChannel.class, shield); + assertInstanceOf(ScatteringByteChannel.class, shield); + assertInstanceOf(ReadableByteChannel.class, shield); + assertInstanceOf(InterruptibleChannel.class, shield); + assertInstanceOf(ByteChannel.class, shield); + assertInstanceOf(Channel.class, shield); + // These are not interfaces, so can not be implemented + assertFalse(shield instanceof FileChannel, "not FileChannel"); + } + } + @Test void testDoesNotDoubleWrap() { final ByteChannel channel = mock(ByteChannel.class); @@ -286,22 +304,4 @@ void testWritableByteChannelMethods() throws Exception { assertThrows(ClosedChannelException.class, () -> shield.write(null)); verifyNoMoreInteractions(channel); } - - @Test - void testCorrectlyDetectsInterfaces(@TempDir Path tempDir) throws IOException { - final Path testFile = tempDir.resolve("test.txt"); - FileUtils.touch(testFile.toFile()); - try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { - assertInstanceOf(SeekableByteChannel.class, shield); - assertInstanceOf(GatheringByteChannel.class, shield); - assertInstanceOf(WritableByteChannel.class, shield); - assertInstanceOf(ScatteringByteChannel.class, shield); - assertInstanceOf(ReadableByteChannel.class, shield); - assertInstanceOf(InterruptibleChannel.class, shield); - assertInstanceOf(ByteChannel.class, shield); - assertInstanceOf(Channel.class, shield); - // These are not interfaces, so can not be implemented - assertFalse(shield instanceof FileChannel, "not FileChannel"); - } - } } From 5c6a2e60b9a2b1aecf6765f8dfceebc9d58153f9 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 14 Oct 2025 15:01:43 -0400 Subject: [PATCH 021/174] Don't need need this entry since we have one already for the new class --- src/changes/changes.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ead8994de83..ecee3aeca01 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,7 +56,6 @@ The type attribute can be add,update,fix,remove. IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Javadoc general improvements. IOUtils.toByteArray() now throws EOFException when not enough data is available #796. - Fix interface discovery in `CloseShieldChannel` #800. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. From f51d19cabad7b8c67e2992a2ab22465658249485 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 14 Oct 2025 15:02:23 -0400 Subject: [PATCH 022/174] Sort members --- .../java/org/apache/commons/io/IOUtils.java | 12 +- .../org/apache/commons/io/FileUtilsTest.java | 12 +- .../org/apache/commons/io/IOUtilsTest.java | 184 +++++++++--------- .../UnsynchronizedBufferedReaderTest.java | 54 ++--- 4 files changed, 131 insertions(+), 131 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 52eb5c971fc..a1f9b0709a2 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -500,6 +500,12 @@ public static void checkFromIndexSize(final char[] array, final int off, final i checkFromIndexSize(off, len, Objects.requireNonNull(array, "char array").length); } + static void checkFromIndexSize(final int off, final int len, final int arrayLength) { + if ((off | len | arrayLength) < 0 || arrayLength - len < off) { + throw new IndexOutOfBoundsException(String.format("Range [%s, % list(final File startDirectory) throws IOException { */ private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker(); + private static void setDosReadOnly(Path p, boolean readOnly) throws IOException { + if (Files.getFileStore(p).supportsFileAttributeView(DosFileAttributeView.class)) { + Files.setAttribute(p, "dos:readonly", readOnly, LinkOption.NOFOLLOW_LINKS); + } + } private File testFile1; private File testFile2; private long testFile1Size; + private long testFile2Size; private void assertContentMatchesAfterCopyURLToFileFor(final String resourceName, final File destination) throws IOException { @@ -1758,12 +1764,6 @@ void testForceDeleteReadOnlyFile() throws Exception { } } - private static void setDosReadOnly(Path p, boolean readOnly) throws IOException { - if (Files.getFileStore(p).supportsFileAttributeView(DosFileAttributeView.class)) { - Files.setAttribute(p, "dos:readonly", readOnly, LinkOption.NOFOLLOW_LINKS); - } - } - @Test public void testForceDeleteSymlink() throws Exception { final ImmutablePair pair = createTempSymbolicLinkedRelativeDir(); diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 8a830ec316a..e9fed5c0c0e 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -138,6 +138,71 @@ public static void beforeAll() { IO.clear(); } + static Stream invalidRead_InputStream_Offset_ArgumentsProvider() { + final InputStream input = new ByteArrayInputStream(new byte[10]); + final byte[] b = new byte[10]; + return Stream.of( + // input is null + Arguments.of(null, b, 0, 1, NullPointerException.class), + // b is null + Arguments.of(input, null, 0, 1, NullPointerException.class), + // off is negative + Arguments.of(input, b, -1, 1, IndexOutOfBoundsException.class), + // len is negative + Arguments.of(input, b, 0, -1, IndexOutOfBoundsException.class), + // off + len is too big + Arguments.of(input, b, 1, 10, IndexOutOfBoundsException.class), + // off + len is too big + Arguments.of(input, b, 10, 1, IndexOutOfBoundsException.class) + ); + } + + static Stream testCheckFromIndexSizeInvalidCases() { + return Stream.of( + Arguments.of(-1, 0, 42), + Arguments.of(0, -1, 42), + Arguments.of(0, 0, -1), + // off + len > arrayLength + Arguments.of(1, 42, 42), + Arguments.of(Integer.MAX_VALUE, 1, Integer.MAX_VALUE) + ); + } + + static Stream testCheckFromIndexSizeValidCases() { + return Stream.of( + // Valid cases + Arguments.of(0, 0, 42), + Arguments.of(0, 1, 42), + Arguments.of(0, 42, 42), + Arguments.of(41, 1, 42), + Arguments.of(42, 0, 42) + ); + } + + static Stream testCheckFromToIndexInvalidCases() { + return Stream.of( + Arguments.of(-1, 0, 42), + Arguments.of(0, -1, 42), + Arguments.of(0, 0, -1), + // from > to + Arguments.of(1, 0, 42), + // to > arrayLength + Arguments.of(0, 43, 42), + Arguments.of(1, 43, 42) + ); + } + + static Stream testCheckFromToIndexValidCases() { + return Stream.of( + // Valid cases + Arguments.of(0, 0, 42), + Arguments.of(0, 1, 42), + Arguments.of(0, 42, 42), + Arguments.of(41, 42, 42), + Arguments.of(42, 42, 42) + ); + } + private static Stream testToByteArray_InputStream_Size_BufferSize_Succeeds() { final byte[] data = new byte[1024]; for (int i = 0; i < 1024; i++) { @@ -354,34 +419,6 @@ void testByteArrayWithNegativeSize() { assertThrows(NegativeArraySizeException.class, () -> IOUtils.byteArray(-1)); } - static Stream testCheckFromIndexSizeValidCases() { - return Stream.of( - // Valid cases - Arguments.of(0, 0, 42), - Arguments.of(0, 1, 42), - Arguments.of(0, 42, 42), - Arguments.of(41, 1, 42), - Arguments.of(42, 0, 42) - ); - } - - @ParameterizedTest - @MethodSource - void testCheckFromIndexSizeValidCases(int off, int len, int arrayLength) { - assertDoesNotThrow(() -> IOUtils.checkFromIndexSize(off, len, arrayLength)); - } - - static Stream testCheckFromIndexSizeInvalidCases() { - return Stream.of( - Arguments.of(-1, 0, 42), - Arguments.of(0, -1, 42), - Arguments.of(0, 0, -1), - // off + len > arrayLength - Arguments.of(1, 42, 42), - Arguments.of(Integer.MAX_VALUE, 1, Integer.MAX_VALUE) - ); - } - @ParameterizedTest @MethodSource void testCheckFromIndexSizeInvalidCases(int off, int len, int arrayLength) { @@ -402,34 +439,10 @@ void testCheckFromIndexSizeInvalidCases(int off, int len, int arrayLength) { } } - static Stream testCheckFromToIndexValidCases() { - return Stream.of( - // Valid cases - Arguments.of(0, 0, 42), - Arguments.of(0, 1, 42), - Arguments.of(0, 42, 42), - Arguments.of(41, 42, 42), - Arguments.of(42, 42, 42) - ); - } - @ParameterizedTest @MethodSource - void testCheckFromToIndexValidCases(int from, int to, int arrayLength) { - assertDoesNotThrow(() -> IOUtils.checkFromToIndex(from, to, arrayLength)); - } - - static Stream testCheckFromToIndexInvalidCases() { - return Stream.of( - Arguments.of(-1, 0, 42), - Arguments.of(0, -1, 42), - Arguments.of(0, 0, -1), - // from > to - Arguments.of(1, 0, 42), - // to > arrayLength - Arguments.of(0, 43, 42), - Arguments.of(1, 43, 42) - ); + void testCheckFromIndexSizeValidCases(int off, int len, int arrayLength) { + assertDoesNotThrow(() -> IOUtils.checkFromIndexSize(off, len, arrayLength)); } @ParameterizedTest @@ -452,6 +465,12 @@ void testCheckFromToIndexInvalidCases(int from, int to, int arrayLength) { } } + @ParameterizedTest + @MethodSource + void testCheckFromToIndexValidCases(int from, int to, int arrayLength) { + assertDoesNotThrow(() -> IOUtils.checkFromToIndex(from, to, arrayLength)); + } + @Test void testClose() { assertDoesNotThrow(() -> IOUtils.close((Closeable) null)); @@ -1147,6 +1166,12 @@ void testCopyLarge_SkipWithInvalidOffset() throws IOException { } } + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + void testRead_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + assertThrows(expected, () -> IOUtils.read(input, b, off, len)); + } + @Test void testRead_ReadableByteChannel() throws Exception { final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); @@ -1164,31 +1189,6 @@ void testRead_ReadableByteChannel() throws Exception { } } - static Stream invalidRead_InputStream_Offset_ArgumentsProvider() { - final InputStream input = new ByteArrayInputStream(new byte[10]); - final byte[] b = new byte[10]; - return Stream.of( - // input is null - Arguments.of(null, b, 0, 1, NullPointerException.class), - // b is null - Arguments.of(input, null, 0, 1, NullPointerException.class), - // off is negative - Arguments.of(input, b, -1, 1, IndexOutOfBoundsException.class), - // len is negative - Arguments.of(input, b, 0, -1, IndexOutOfBoundsException.class), - // off + len is too big - Arguments.of(input, b, 1, 10, IndexOutOfBoundsException.class), - // off + len is too big - Arguments.of(input, b, 10, 1, IndexOutOfBoundsException.class) - ); - } - - @ParameterizedTest - @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") - void testRead_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { - assertThrows(expected, () -> IOUtils.read(input, b, off, len)); - } - @Test void testReadFully_InputStream__ReturnByteArray() throws Exception { final byte[] bytes = "abcd1234".getBytes(StandardCharsets.UTF_8); @@ -1221,6 +1221,12 @@ void testReadFully_InputStream_Offset() throws Exception { IOUtils.closeQuietly(stream); } + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + void testReadFully_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + assertThrows(expected, () -> IOUtils.read(input, b, off, len)); + } + @Test void testReadFully_ReadableByteChannel() throws Exception { final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); @@ -1265,12 +1271,6 @@ void testReadFully_Reader_Offset() throws Exception { IOUtils.closeQuietly(reader); } - @ParameterizedTest - @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") - void testReadFully_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { - assertThrows(expected, () -> IOUtils.read(input, b, off, len)); - } - @Test void testReadLines_CharSequence() throws IOException { final File file = TestUtils.newFile(temporaryFolder, "lines.txt"); @@ -1745,13 +1745,6 @@ void testToByteArray_InputStream_Size() throws Exception { } } - @Test - void testToByteArray_InputStream_Size_Truncated() throws Exception { - try (InputStream in = new NullInputStream(0)) { - assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1)); - } - } - @ParameterizedTest @MethodSource void testToByteArray_InputStream_Size_BufferSize_Succeeds(final byte[] data, final int size, final int bufferSize) throws IOException { @@ -1770,6 +1763,13 @@ void testToByteArray_InputStream_Size_BufferSize_Throws( } } + @Test + void testToByteArray_InputStream_Size_Truncated() throws Exception { + try (InputStream in = new NullInputStream(0)) { + assertThrows(EOFException.class, () -> IOUtils.toByteArray(in, 1)); + } + } + @Test void testToByteArray_InputStream_SizeIllegal() throws Exception { try (InputStream fin = Files.newInputStream(testFilePath)) { diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedReaderTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedReaderTest.java index a144bc418d0..2a2b21a22ad 100644 --- a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedReaderTest.java @@ -347,6 +347,33 @@ void testRead() throws IOException { } } + @Test + void testReadArray_HARMONY_54() throws IOException { + // Regression for HARMONY-54 + final char[] ch = {}; + @SuppressWarnings("resource") + final UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(ch)); + // Check exception thrown when the reader is open. + assertThrows(NullPointerException.class, () -> reader.read(null, 1, 0)); + + // Now check IOException is thrown in preference to + // NullPointerexception when the reader is closed. + reader.close(); + assertThrows(IOException.class, () -> reader.read(null, 1, 0)); + + // And check that the IOException is thrown before + // ArrayIndexOutOfBoundException + assertThrows(IOException.class, () -> reader.read(ch, 0, 42)); + } + + @Test + void testReadArray_HARMONY_831() throws IOException { + // regression for HARMONY-831 + try (Reader reader = new UnsynchronizedBufferedReader(new PipedReader(), 9)) { + assertThrows(IndexOutOfBoundsException.class, () -> reader.read(new char[] {}, 7, 0)); + } + } + /** * Tests {@link UnsynchronizedBufferedReader#read(char[], int, int)}. * @@ -437,33 +464,6 @@ public boolean ready() throws IOException { } } - @Test - void testReadArray_HARMONY_831() throws IOException { - // regression for HARMONY-831 - try (Reader reader = new UnsynchronizedBufferedReader(new PipedReader(), 9)) { - assertThrows(IndexOutOfBoundsException.class, () -> reader.read(new char[] {}, 7, 0)); - } - } - - @Test - void testReadArray_HARMONY_54() throws IOException { - // Regression for HARMONY-54 - final char[] ch = {}; - @SuppressWarnings("resource") - final UnsynchronizedBufferedReader reader = new UnsynchronizedBufferedReader(new CharArrayReader(ch)); - // Check exception thrown when the reader is open. - assertThrows(NullPointerException.class, () -> reader.read(null, 1, 0)); - - // Now check IOException is thrown in preference to - // NullPointerexception when the reader is closed. - reader.close(); - assertThrows(IOException.class, () -> reader.read(null, 1, 0)); - - // And check that the IOException is thrown before - // ArrayIndexOutOfBoundException - assertThrows(IOException.class, () -> reader.read(ch, 0, 42)); - } - /** * Tests {@link UnsynchronizedBufferedReader#read(char[], int, int)}. * From 08573a672d6b24f6340e7111324a85d15c1542ea Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 16 Oct 2025 16:02:39 +0200 Subject: [PATCH 023/174] Fixes issues in `CloseShieldChannel` (#799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes issues in `CloseShieldChannel` Two bugs in the `CloseShieldChannel` helper make it unreliable in practice: 1. **Type-erasure bug in `T wrap(T)`** The method signature only works correctly when `T` is an **interface** extending `Channel`. Since Java’s type system doesn’t allow constraining `T` to “interface types only,” this could lead to unexpected runtime `ClassCastException`s even though the code compiles successfully. 2. **Incomplete interface discovery** The implementation only inspected interfaces **directly** implemented by the given channel’s class, ignoring those inherited from its superclasses. As a result, proxies for types such as `FileChannel` did not expose any of the interfaces declared on `FileChannel` itself. #### Fixes This PR addresses both issues: * **Reworks the API signature** * Replaces `T wrap(T)` with its erasure: `Channel wrap(Channel)`. * Introduces a new overload: `T wrap(T, Class)`, which allows callers to explicitly specify the interface type they expect. This version fails fast with a clear `IllegalArgumentException` if the provided type is not an interface, instead of allowing a `ClassCastException` later. * **Improves interface collection logic** * Updates the implementation to include interfaces declared on superclasses, ensuring all relevant `Channel` interfaces are correctly proxied. * Fixes interface discovery in `CloseShieldChannel` This PR is split from #799. The `CloseShieldChannel` implementation only inspects interfaces **directly** implemented by the given channel’s class, ignoring those inherited from its superclasses. As a result, proxies for types such as `FileChannel` does not expose any of the interfaces declared on `FileChannel` itself. * fix: add overloads for commons channel types * fix: add `ByteChannel` overload to resolve ambiguity * fix: Limit interfaces to those verified. * fix: rollback previous test * fix: Restore generic method --- .../io/channels/CloseShieldChannel.java | 35 ++++++++++++++++--- .../channels/CloseShieldChannelHandler.java | 31 ++++++++++++++++ .../io/channels/CloseShieldChannelTest.java | 5 --- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java index bde0feb25cc..ba890d8a6a7 100644 --- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java +++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java @@ -19,7 +19,16 @@ import java.io.Closeable; import java.lang.reflect.Proxy; +import java.nio.channels.AsynchronousChannel; +import java.nio.channels.ByteChannel; import java.nio.channels.Channel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.InterruptibleChannel; +import java.nio.channels.NetworkChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.channels.WritableByteChannel; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; @@ -27,9 +36,23 @@ /** * Creates a close-shielding proxy for a {@link Channel}. * - *

- * The returned proxy will implement all {@link Channel} sub-interfaces that the delegate implements. - *

+ *

The returned proxy implements all {@link Channel} sub-interfaces that are both supported by this implementation and actually implemented by the given + * delegate.

+ * + *

The following interfaces are supported:

+ * + *
    + *
  • {@link AsynchronousChannel}
  • + *
  • {@link ByteChannel}
  • + *
  • {@link Channel}
  • + *
  • {@link GatheringByteChannel}
  • + *
  • {@link InterruptibleChannel}
  • + *
  • {@link NetworkChannel}
  • + *
  • {@link ReadableByteChannel}
  • + *
  • {@link ScatteringByteChannel}
  • + *
  • {@link SeekableByteChannel}
  • + *
  • {@link WritableByteChannel}
  • + *
* * @see Channel * @see Closeable @@ -44,7 +67,7 @@ private static Set> collectChannelInterfaces(final Class type, final // Visit interfaces while (currentType != null) { for (final Class iface : currentType.getInterfaces()) { - if (Channel.class.isAssignableFrom(iface) && out.add(iface)) { + if (CloseShieldChannelHandler.isSupported(iface) && out.add(iface)) { collectChannelInterfaces(iface, out); } } @@ -57,8 +80,10 @@ private static Set> collectChannelInterfaces(final Class type, final * Wraps a channel to shield it from being closed. * * @param channel The underlying channel to shield, not {@code null}. - * @param Any Channel type (interface or class). + * @param A supported channel type. * @return A proxy that shields {@code close()} and enforces closed semantics on other calls. + * @throws ClassCastException if {@code T} is not a supported channel type. + * @throws NullPointerException if {@code channel} is {@code null}. */ @SuppressWarnings({ "unchecked", "resource" }) // caller closes public static T wrap(final T channel) { diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java index f13b101c197..a7f3d3694f1 100644 --- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java +++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java @@ -21,14 +21,45 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.nio.channels.AsynchronousChannel; +import java.nio.channels.ByteChannel; import java.nio.channels.Channel; import java.nio.channels.ClosedChannelException; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.InterruptibleChannel; import java.nio.channels.NetworkChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.ScatteringByteChannel; import java.nio.channels.SeekableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.Collections; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; final class CloseShieldChannelHandler implements InvocationHandler { + private static final Set> SUPPORTED_INTERFACES; + + static { + final Set> interfaces = new HashSet<>(); + interfaces.add(AsynchronousChannel.class); + interfaces.add(ByteChannel.class); + interfaces.add(Channel.class); + interfaces.add(GatheringByteChannel.class); + interfaces.add(InterruptibleChannel.class); + interfaces.add(NetworkChannel.class); + interfaces.add(ReadableByteChannel.class); + interfaces.add(ScatteringByteChannel.class); + interfaces.add(SeekableByteChannel.class); + interfaces.add(WritableByteChannel.class); + SUPPORTED_INTERFACES = Collections.unmodifiableSet(interfaces); + } + + static boolean isSupported(final Class interfaceClass) { + return SUPPORTED_INTERFACES.contains(interfaceClass); + } + /** * Tests whether the given method is allowed to be called after the shield is closed. * diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java index 47d04df95d6..1f448f42cc2 100644 --- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java @@ -34,7 +34,6 @@ import static org.mockito.Mockito.when; import java.io.IOException; -import java.nio.channels.AsynchronousByteChannel; import java.nio.channels.AsynchronousChannel; import java.nio.channels.ByteChannel; import java.nio.channels.Channel; @@ -42,7 +41,6 @@ import java.nio.channels.FileChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.InterruptibleChannel; -import java.nio.channels.MulticastChannel; import java.nio.channels.NetworkChannel; import java.nio.channels.ReadableByteChannel; import java.nio.channels.ScatteringByteChannel; @@ -65,14 +63,11 @@ class CloseShieldChannelTest { static Stream> testedInterfaces() { // @formatter:off return Stream.of( - AsynchronousByteChannel.class, AsynchronousChannel.class, ByteChannel.class, Channel.class, GatheringByteChannel.class, InterruptibleChannel.class, - MulticastChannel.class, - NetworkChannel.class, NetworkChannel.class, ReadableByteChannel.class, ScatteringByteChannel.class, From 13c52f99be0cfc604080723ac96e2ad10b9bcf36 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Thu, 16 Oct 2025 10:11:34 -0400 Subject: [PATCH 024/174] More precise generics for CloseShieldChannelHandler.SUPPORTED_INTERFACES --- .../apache/commons/io/channels/CloseShieldChannelHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java index a7f3d3694f1..919b86d7ceb 100644 --- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java +++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java @@ -39,10 +39,10 @@ final class CloseShieldChannelHandler implements InvocationHandler { - private static final Set> SUPPORTED_INTERFACES; + private static final Set> SUPPORTED_INTERFACES; static { - final Set> interfaces = new HashSet<>(); + final Set> interfaces = new HashSet<>(); interfaces.add(AsynchronousChannel.class); interfaces.add(ByteChannel.class); interfaces.add(Channel.class); From c28dc1bdc28cc3a47ca3a897ce31cac1fc9592c2 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Thu, 16 Oct 2025 10:25:58 -0400 Subject: [PATCH 025/174] Minor refactoring in CloseShieldChannelTest --- .../io/channels/CloseShieldChannelTest.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java index 1f448f42cc2..b21a5b8153b 100644 --- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java @@ -47,9 +47,11 @@ import java.nio.channels.SeekableByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.file.Path; +import java.util.List; import java.util.stream.Stream; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.ClassUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; @@ -60,7 +62,10 @@ */ class CloseShieldChannelTest { - static Stream> testedInterfaces() { + /** + * JRE {@link Channel} interfaces. + */ + static Stream> channelInterfaces() { // @formatter:off return Stream.of( AsynchronousChannel.class, @@ -76,8 +81,15 @@ static Stream> testedInterfaces() { // @formatter:on } + /** + * Gets all interfaces implemented by the class {@link FileChannel}. + */ + static List> fileChannelInterfaces() { + return ClassUtils.getAllInterfaces(FileChannel.class); + } + @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testCloseDoesNotCloseDelegate(final Class channelClass) throws Exception { final Channel channel = mock(channelClass); final Channel shield = CloseShieldChannel.wrap(channel); @@ -86,7 +98,7 @@ void testCloseDoesNotCloseDelegate(final Class channelClass) } @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testCloseIsIdempotent(final Class channelClass) throws Exception { final Channel channel = mock(channelClass); final Channel shield = CloseShieldChannel.wrap(channel); @@ -98,9 +110,9 @@ void testCloseIsIdempotent(final Class channelClass) throws E } @ParameterizedTest - @MethodSource("testedInterfaces") - void testCloseIsShielded(final Class channelClass) throws Exception { - final Channel channel = mock(channelClass); + @MethodSource("channelInterfaces") + void testCloseIsShielded(final Class channelInterface) throws Exception { + final Channel channel = mock(channelInterface); when(channel.isOpen()).thenReturn(true, false, true, false); final Channel shield = CloseShieldChannel.wrap(channel); // Reflects delegate state initially @@ -115,19 +127,12 @@ void testCloseIsShielded(final Class channelClass) throws Exc } @Test - void testCorrectlyDetectsInterfaces(@TempDir Path tempDir) throws IOException { + void testWrapFileChannel(final @TempDir Path tempDir) throws IOException { final Path testFile = tempDir.resolve("test.txt"); FileUtils.touch(testFile.toFile()); try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { - assertInstanceOf(SeekableByteChannel.class, shield); - assertInstanceOf(GatheringByteChannel.class, shield); - assertInstanceOf(WritableByteChannel.class, shield); - assertInstanceOf(ScatteringByteChannel.class, shield); - assertInstanceOf(ReadableByteChannel.class, shield); - assertInstanceOf(InterruptibleChannel.class, shield); - assertInstanceOf(ByteChannel.class, shield); - assertInstanceOf(Channel.class, shield); - // These are not interfaces, so can not be implemented + fileChannelInterfaces().forEach(iface -> assertInstanceOf(iface, shield)); + // FileChannel is not an interface, so can not be implemented. assertFalse(shield instanceof FileChannel, "not FileChannel"); } } @@ -141,7 +146,7 @@ void testDoesNotDoubleWrap() { } @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testEquals(final Class channelClass) throws Exception { final Channel channel = mock(channelClass); final Channel shield = CloseShieldChannel.wrap(channel); @@ -168,7 +173,7 @@ void testGatheringByteChannelMethods() throws Exception { } @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testHashCode(final Class channelClass) throws Exception { final Channel channel = mock(channelClass); final Channel shield = CloseShieldChannel.wrap(channel); @@ -208,7 +213,7 @@ void testNetworkChannelMethods() throws Exception { } @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testPreservesInterfaces(final Class channelClass) { final Channel channel = mock(channelClass); final Channel shield = CloseShieldChannel.wrap(channel); @@ -275,7 +280,7 @@ void testSeekableByteChannelMethods() throws Exception { } @ParameterizedTest - @MethodSource("testedInterfaces") + @MethodSource("channelInterfaces") void testToString(final Class channelClass) throws Exception { final Channel channel = mock(channelClass); when(channel.toString()).thenReturn("MyChannel"); From 5a5c6aee83347bd90cc60a5bfe4645f1d9e7f28f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 20:30:46 -0400 Subject: [PATCH 026/174] Bump actions/dependency-review-action from 4.8.0 to 4.8.1 (#802) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4.8.0 to 4.8.1. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/56339e523c0409420f6c2c9a2f4292bbb3c07dd3...40c09b7dc99638e5ddb0bfd91c1673effc064d8a) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-version: 4.8.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index edfe8756642..a657a4ae2cd 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -28,4 +28,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: 'Dependency Review PR' - uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0 + uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1 From 3c5166e34e19efe35b522badd08e5e7960d9c49e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 20:31:36 -0400 Subject: [PATCH 027/174] Bump github/codeql-action from 4.30.7 to 4.30.8 (#803) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.30.7 to 4.30.8. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e296a935590eb16afc0c0108289f68c87e2a89a5...f443b600d91635bebf5b0d9ebc620189c0d6fba5) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.30.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 4d91dcc9f39..ea037c8f839 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 + uses: github/codeql-action/init@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 + uses: github/codeql-action/autobuild@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 + uses: github/codeql-action/analyze@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 0de672c8692..77678628b08 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # 3.29.5 + uses: github/codeql-action/upload-sarif@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 with: sarif_file: results.sarif From f76ee129d348f04c540d205856853e587ae22766 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Fri, 17 Oct 2025 15:23:57 +0200 Subject: [PATCH 028/174] Fix concurrency issue in `IOUtils.skip` (#801) * Fix concurrency issue in `IOUtils.skip` This patch addresses a concurrency problem in `IOUtils.skip`, as reported in [COMPRESS-666](https://issues.apache.org/jira/browse/COMPRESS-666) and [COMPRESS-697](https://issues.apache.org/jira/browse/COMPRESS-697). Previously, `IOUtils.skip` relied on `InputStream#read` to skip bytes, using a buffer shared across **all** threads. Although `IOUtils.skip` itself does not consume the data read, certain `InputStream` implementations (e.g. `ChecksumInputStream`) may process that data internally. In concurrent scenarios, this shared buffer could be overwritten by another thread between the `read` and the subsequent internal processing (such as checksum calculation), leading to incorrect behavior. This change reverts commit c12eaff7f747353a7a9a97df735fd3301f42e313 and restores the use of a **per-thread buffer** in `IOUtils.skip`, ensuring thread safety and correct behavior in concurrent environments. * Adds a reentrancy guard to the thread-local pool * Apply suggestion from @Copilot (1) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestions from @Copilot (2) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/changes/changes.xml | 1 + .../java/org/apache/commons/io/CopyUtils.java | 18 +- .../java/org/apache/commons/io/IOUtils.java | 273 ++++++++++-------- .../org/apache/commons/io/IOCaseTest.java | 65 +++-- .../commons/io/IOUtilsConcurrentTest.java | 212 ++++++++++++++ 5 files changed, 419 insertions(+), 150 deletions(-) create mode 100644 src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java diff --git a/src/changes/changes.xml b/src/changes/changes.xml index ecee3aeca01..3aa41940132 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,6 +56,7 @@ The type attribute can be add,update,fix,remove. IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Javadoc general improvements. IOUtils.toByteArray() now throws EOFException when not enough data is available #796. + Fix IOUtils.skip() usage in concurrent scenarios. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index e22adef83be..fdb137d2039 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -278,14 +278,18 @@ public static int copy( final Reader input, final Writer output) throws IOException { - final char[] buffer = IOUtils.getScratchCharArray(); - int count = 0; - int n; - while (EOF != (n = input.read(buffer))) { - output.write(buffer, 0, n); - count += n; + final char[] buffer = IOUtils.ScratchBufferHolder.getScratchCharArray(); + try { + int count = 0; + int n; + while (EOF != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } finally { + IOUtils.ScratchBufferHolder.releaseScratchCharArray(buffer); } - return count; } /** diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index a1f9b0709a2..717be4b49bf 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -132,6 +132,94 @@ public class IOUtils { // Writer. Each method should take at least one of these as a parameter, // or return one of them. + /** + * Holder for per-thread internal scratch buffers. + * + *

Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer + * is allocated to avoid data corruption.

+ * + *

Typical usage:

+ * + *
{@code
+     * final byte[] buffer = ScratchBufferHolder.getScratchByteArray();
+     * try {
+     *     // use the buffer
+     * } finally {
+     *     ScratchBufferHolder.releaseScratchByteArray(buffer);
+     * }
+     * }
+ */ + static final class ScratchBufferHolder { + + /** + * Holder for internal byte array buffer. + */ + private static final ThreadLocal SCRATCH_BYTE_BUFFER_HOLDER = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() }); + + /** + * Holder for internal char array buffer. + */ + private static final ThreadLocal SCRATCH_CHAR_BUFFER_HOLDER = ThreadLocal.withInitial(() -> new Object[] { false, charArray() }); + + + /** + * Gets the internal byte array buffer. + * + * @return the internal byte array buffer. + */ + static byte[] getScratchByteArray() { + final Object[] holder = SCRATCH_BYTE_BUFFER_HOLDER.get(); + // If already in use, return a new array + if ((boolean) holder[0]) { + return byteArray(); + } + holder[0] = true; + return (byte[]) holder[1]; + } + + /** + * Gets the char array buffer. + * + * @return the char array buffer. + */ + static char[] getScratchCharArray() { + final Object[] holder = SCRATCH_CHAR_BUFFER_HOLDER.get(); + // If already in use, return a new array + if ((boolean) holder[0]) { + return charArray(); + } + holder[0] = true; + return (char[]) holder[1]; + } + + + /** + * If the argument is the internal byte array, release it for reuse. + * + * @param array the byte array to release. + */ + static void releaseScratchByteArray(byte[] array) { + final Object[] holder = SCRATCH_BYTE_BUFFER_HOLDER.get(); + if (array == holder[1]) { + Arrays.fill(array, (byte) 0); + holder[0] = false; + } + } + + /** + * If the argument is the internal char array, release it for reuse. + * + * @param array the char array to release. + */ + static void releaseScratchCharArray(char[] array) { + final Object[] holder = SCRATCH_CHAR_BUFFER_HOLDER.get(); + if (array == holder[1]) { + Arrays.fill(array, (char) 0); + holder[0] = false; + } + } + } + /** * CR char '{@value}'. * @@ -201,26 +289,6 @@ public class IOUtils { */ public static final String LINE_SEPARATOR_WINDOWS = StandardLineSeparator.CRLF.getString(); - /** - * Internal byte array buffer, intended for both reading and writing. - */ - private static final ThreadLocal SCRATCH_BYTE_BUFFER_RW = ThreadLocal.withInitial(IOUtils::byteArray); - - /** - * Internal byte array buffer, intended for write only operations. - */ - private static final byte[] SCRATCH_BYTE_BUFFER_WO = byteArray(); - - /** - * Internal char array buffer, intended for both reading and writing. - */ - private static final ThreadLocal SCRATCH_CHAR_BUFFER_RW = ThreadLocal.withInitial(IOUtils::charArray); - - /** - * Internal char array buffer, intended for write only operations. - */ - private static final char[] SCRATCH_CHAR_BUFFER_WO = charArray(); - /** * The maximum size of an array in many Java VMs. *

@@ -592,10 +660,8 @@ static void checkFromToIndex(final int fromIndex, final int toIndex, final int l * @see IO#clear() */ static void clear() { - SCRATCH_BYTE_BUFFER_RW.remove(); - SCRATCH_CHAR_BUFFER_RW.remove(); - Arrays.fill(SCRATCH_BYTE_BUFFER_WO, (byte) 0); - Arrays.fill(SCRATCH_CHAR_BUFFER_WO, (char) 0); + ScratchBufferHolder.SCRATCH_BYTE_BUFFER_HOLDER.remove(); + ScratchBufferHolder.SCRATCH_CHAR_BUFFER_HOLDER.remove(); } /** @@ -1139,39 +1205,43 @@ public static boolean contentEquals(final Reader input1, final Reader input2) th } // reuse one - final char[] array1 = getScratchCharArray(); + final char[] array1 = ScratchBufferHolder.getScratchCharArray(); // but allocate another final char[] array2 = charArray(); int pos1; int pos2; int count1; int count2; - while (true) { - pos1 = 0; - pos2 = 0; - for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { - if (pos1 == index) { - do { - count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); - } while (count1 == 0); - if (count1 == EOF) { - return pos2 == index && input2.read() == EOF; + try { + while (true) { + pos1 = 0; + pos2 = 0; + for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { + if (pos1 == index) { + do { + count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); + } while (count1 == 0); + if (count1 == EOF) { + return pos2 == index && input2.read() == EOF; + } + pos1 += count1; } - pos1 += count1; - } - if (pos2 == index) { - do { - count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); - } while (count2 == 0); - if (count2 == EOF) { - return pos1 == index && input1.read() == EOF; + if (pos2 == index) { + do { + count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); + } while (count2 == 0); + if (count2 == EOF) { + return pos1 == index && input1.read() == EOF; + } + pos2 += count2; + } + if (array1[index] != array2[index]) { + return false; } - pos2 += count2; - } - if (array1[index] != array2[index]) { - return false; } } + } finally { + ScratchBufferHolder.releaseScratchCharArray(array1); } } @@ -1651,9 +1721,13 @@ public static long copyLarge(final InputStream inputStream, final OutputStream o * @throws IOException if an I/O error occurs. * @since 2.2 */ - public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, - final long length) throws IOException { - return copyLarge(input, output, inputOffset, length, getScratchByteArray()); + public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length) throws IOException { + final byte[] buffer = ScratchBufferHolder.getScratchByteArray(); + try { + return copyLarge(input, output, inputOffset, length, buffer); + } finally { + ScratchBufferHolder.releaseScratchByteArray(buffer); + } } /** @@ -1723,7 +1797,12 @@ public static long copyLarge(final InputStream input, final OutputStream output, * @since 1.3 */ public static long copyLarge(final Reader reader, final Writer writer) throws IOException { - return copyLarge(reader, writer, getScratchCharArray()); + final char[] buffer = ScratchBufferHolder.getScratchCharArray(); + try { + return copyLarge(reader, writer, buffer); + } finally { + ScratchBufferHolder.releaseScratchCharArray(buffer); + } } /** @@ -1770,7 +1849,12 @@ public static long copyLarge(final Reader reader, final Writer writer, final cha * @since 2.2 */ public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length) throws IOException { - return copyLarge(reader, writer, inputOffset, length, getScratchCharArray()); + final char[] buffer = ScratchBufferHolder.getScratchCharArray(); + try { + return copyLarge(reader, writer, inputOffset, length, buffer); + } finally { + ScratchBufferHolder.releaseScratchCharArray(buffer); + } } /** @@ -1837,64 +1921,6 @@ static UnsynchronizedByteArrayOutputStream copyToOutputStream( } } - /** - * Fills the given array with 0s. - * - * @param arr The non-null array to fill. - * @return The given array. - */ - private static byte[] fill0(final byte[] arr) { - Arrays.fill(arr, (byte) 0); - return arr; - } - - /** - * Fills the given array with 0s. - * - * @param arr The non-null array to fill. - * @return The given array. - */ - private static char[] fill0(final char[] arr) { - Arrays.fill(arr, (char) 0); - return arr; - } - - /** - * Gets the internal byte array buffer, intended for both reading and writing. - * - * @return the internal byte array buffer, intended for both reading and writing. - */ - static byte[] getScratchByteArray() { - return fill0(SCRATCH_BYTE_BUFFER_RW.get()); - } - - /** - * Gets the internal byte array intended for write only operations. - * - * @return the internal byte array intended for write only operations. - */ - static byte[] getScratchByteArrayWriteOnly() { - return fill0(SCRATCH_BYTE_BUFFER_WO); - } - - /** - * Gets the char byte array buffer, intended for both reading and writing. - * - * @return the char byte array buffer, intended for both reading and writing. - */ - static char[] getScratchCharArray() { - return fill0(SCRATCH_CHAR_BUFFER_RW.get()); - } - - /** - * Gets the internal char array intended for write only operations. - * - * @return the internal char array intended for write only operations. - */ - static char[] getScratchCharArrayWriteOnly() { - return fill0(SCRATCH_CHAR_BUFFER_WO); - } - /** * Returns the length of the given array in a null-safe manner. * @@ -2527,7 +2553,12 @@ public static URL resourceToURL(final String name, final ClassLoader classLoader * @since 2.0 */ public static long skip(final InputStream input, final long skip) throws IOException { - return skip(input, skip, IOUtils::getScratchByteArrayWriteOnly); + final byte[] buffer = ScratchBufferHolder.getScratchByteArray(); + try { + return skip(input, skip, () -> buffer); + } finally { + ScratchBufferHolder.releaseScratchByteArray(buffer); + } } /** @@ -2634,14 +2665,18 @@ public static long skip(final Reader reader, final long toSkip) throws IOExcepti throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); } long remain = toSkip; - while (remain > 0) { - // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() - final char[] charArray = getScratchCharArrayWriteOnly(); - final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length)); - if (n < 0) { // EOF - break; + final char[] charArray = ScratchBufferHolder.getScratchCharArray(); + try { + while (remain > 0) { + // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() + final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length)); + if (n < 0) { // EOF + break; + } + remain -= n; } - remain -= n; + } finally { + ScratchBufferHolder.releaseScratchCharArray(charArray); } return toSkip - remain; } @@ -2667,7 +2702,7 @@ public static long skip(final Reader reader, final long toSkip) throws IOExcepti * @since 2.0 */ public static void skipFully(final InputStream input, final long toSkip) throws IOException { - final long skipped = skip(input, toSkip, IOUtils::getScratchByteArrayWriteOnly); + final long skipped = skip(input, toSkip); if (skipped != toSkip) { throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); } diff --git a/src/test/java/org/apache/commons/io/IOCaseTest.java b/src/test/java/org/apache/commons/io/IOCaseTest.java index 97a990f6369..1121b38eeeb 100644 --- a/src/test/java/org/apache/commons/io/IOCaseTest.java +++ b/src/test/java/org/apache/commons/io/IOCaseTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -296,34 +297,50 @@ void test_getName() { @Test void test_getScratchByteArray() { - final byte[] array = IOUtils.getScratchByteArray(); - assert0(array); - Arrays.fill(array, (byte) 1); - assert0(IOUtils.getScratchCharArray()); - } - - @Test - void test_getScratchByteArrayWriteOnly() { - final byte[] array = IOUtils.getScratchByteArrayWriteOnly(); - assert0(array); - Arrays.fill(array, (byte) 1); - assert0(IOUtils.getScratchCharArray()); + final byte[] array = IOUtils.ScratchBufferHolder.getScratchByteArray(); + try { + assert0(array); + Arrays.fill(array, (byte) 1); + // Get another array, while the first is still in use + final byte[] array2 = IOUtils.ScratchBufferHolder.getScratchByteArray(); + assert0(array2); + assertNotSame(array, array2); + } finally { + // Release first array + IOUtils.ScratchBufferHolder.releaseScratchByteArray(array); + } + // The first array should be reset and reusable + final byte[] array3 = IOUtils.ScratchBufferHolder.getScratchByteArray(); + try { + assert0(array3); + assertSame(array, array3); + } finally { + IOUtils.ScratchBufferHolder.releaseScratchByteArray(array3); + } } @Test void test_getScratchCharArray() { - final char[] array = IOUtils.getScratchCharArray(); - assert0(array); - Arrays.fill(array, (char) 1); - assert0(IOUtils.getScratchCharArray()); - } - - @Test - void test_getScratchCharArrayWriteOnly() { - final char[] array = IOUtils.getScratchCharArrayWriteOnly(); - assert0(array); - Arrays.fill(array, (char) 1); - assert0(IOUtils.getScratchCharArray()); + final char[] array = IOUtils.ScratchBufferHolder.getScratchCharArray(); + try { + assert0(array); + Arrays.fill(array, (char) 1); + // Get another array, while the first is still in use + final char[] array2 = IOUtils.ScratchBufferHolder.getScratchCharArray(); + assert0(array2); + assertNotSame(array, array2); + } finally { + // Release first array + IOUtils.ScratchBufferHolder.releaseScratchCharArray(array); + } + // The first array should be reset and reusable + final char[] array3 = IOUtils.ScratchBufferHolder.getScratchCharArray(); + try { + assert0(array3); + assertSame(array, array3); + } finally { + IOUtils.ScratchBufferHolder.releaseScratchCharArray(array3); + } } @Test diff --git a/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java b/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java new file mode 100644 index 00000000000..0e1fb057175 --- /dev/null +++ b/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import java.util.zip.CRC32; +import java.util.zip.Checksum; + +import org.apache.commons.io.function.IOConsumer; +import org.apache.commons.io.input.ChecksumInputStream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * Tests {@link IOUtils} methods in a concurrent environment. + */ +class IOUtilsConcurrentTest { + + private static class ChecksumReader extends Reader { + private final CRC32 checksum; + private final long expectedChecksumValue; + private final Reader reader; + + ChecksumReader(Reader reader, long expectedChecksumValue) { + this.reader = reader; + this.checksum = new CRC32(); + this.expectedChecksumValue = expectedChecksumValue; + } + + @Override + public void close() throws IOException { + reader.close(); + } + + public long getValue() { + return checksum.getValue(); + } + + @Override + public int read() throws IOException { + return super.read(); + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + final int n = reader.read(cbuf, off, len); + if (n > 0) { + final byte[] bytes = new String(cbuf, off, n).getBytes(Charset.defaultCharset()); + checksum.update(bytes, 0, bytes.length); + } + if (n == -1) { + final long actual = checksum.getValue(); + if (actual != expectedChecksumValue) { + throw new IOException("Checksum mismatch: expected " + expectedChecksumValue + " but got " + actual); + } + } + return n; + } + } + + /** + * Test data for InputStream tests. + */ + private static final byte[][] BYTE_DATA; + /** + * Checksum values for {@link #BYTE_DATA}. + */ + private static final long[] BYTE_DATA_CHECKSUM; + /** + * Number of runs per thread (to increase the chance of collisions). + */ + private static final int RUNS_PER_THREAD = 16; + /** + * Size of test data. + */ + private static final int SIZE = IOUtils.DEFAULT_BUFFER_SIZE; + /** + * Test data for Reader tests. + */ + private static final String[] STRING_DATA; + /** + * Checksum values for {@link #STRING_DATA}. + */ + private static final long[] STRING_DATA_CHECKSUM; + /** + * Number of threads to use. + */ + private static final int THREAD_COUNT = 16; + /** + * Number of data variants (to increase the chance of collisions). + */ + private static final int VARIANTS = 16; + + static { + final Checksum checksum = new CRC32(); + // Byte data + BYTE_DATA = new byte[VARIANTS][]; + BYTE_DATA_CHECKSUM = new long[VARIANTS]; + for (int variant = 0; variant < VARIANTS; variant++) { + final byte[] data = new byte[SIZE]; + for (int i = 0; i < SIZE; i++) { + data[i] = (byte) ((i + variant) % 256); + } + BYTE_DATA[variant] = data; + checksum.reset(); + checksum.update(data, 0 , data.length); + BYTE_DATA_CHECKSUM[variant] = checksum.getValue(); + } + // Char data + final char[] cdata = new char[SIZE]; + STRING_DATA = new String[VARIANTS]; + STRING_DATA_CHECKSUM = new long[VARIANTS]; + for (int variant = 0; variant < VARIANTS; variant++) { + for (int i = 0; i < SIZE; i++) { + cdata[i] = (char) ((i + variant) % Character.MAX_VALUE); + } + STRING_DATA[variant] = new String(cdata); + checksum.reset(); + final byte[] bytes = STRING_DATA[variant].getBytes(Charset.defaultCharset()); + checksum.update(bytes, 0, bytes.length); + STRING_DATA_CHECKSUM[variant] = checksum.getValue(); + } + } + + static Stream> testConcurrentInputStreamTasks() { + return Stream.of( + IOUtils::consume, + in -> IOUtils.skip(in, Long.MAX_VALUE), + in -> IOUtils.skipFully(in, SIZE), + IOUtils::toByteArray, + in -> IOUtils.toByteArray(in, SIZE), + in -> IOUtils.toByteArray(in, SIZE, 512) + ); + } + + static Stream> testConcurrentReaderTasks() { + return Stream.of( + IOUtils::consume, + reader -> IOUtils.skip(reader, Long.MAX_VALUE), + reader -> IOUtils.skipFully(reader, SIZE), + reader -> IOUtils.toByteArray(reader, Charset.defaultCharset()) + ); + } + + @ParameterizedTest + @MethodSource + void testConcurrentInputStreamTasks(IOConsumer consumer) throws InterruptedException { + final ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); + try { + final List> futures = IntStream.range(0, THREAD_COUNT * RUNS_PER_THREAD) + .>mapToObj(i -> threadPool.submit(() -> { + try (InputStream in = ChecksumInputStream + .builder() + .setByteArray(BYTE_DATA[i % VARIANTS]) + .setChecksum(new CRC32()) + .setExpectedChecksumValue(BYTE_DATA_CHECKSUM[i % VARIANTS]) + .get()) { + consumer.accept(in); + } + return null; + })).collect(Collectors.toList()); + futures.forEach(f -> assertDoesNotThrow(() -> f.get())); + } finally { + threadPool.shutdownNow(); + } + } + + @ParameterizedTest + @MethodSource + void testConcurrentReaderTasks(IOConsumer consumer) throws InterruptedException { + final ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); + try { + final List> futures = IntStream.range(0, THREAD_COUNT * RUNS_PER_THREAD) + .>mapToObj(i -> threadPool.submit(() -> { + try (Reader reader = new ChecksumReader(new StringReader(STRING_DATA[i % VARIANTS]), STRING_DATA_CHECKSUM[i % VARIANTS])) { + consumer.accept(reader); + } + return null; + })).collect(Collectors.toList()); + futures.forEach(f -> assertDoesNotThrow(() -> f.get())); + } finally { + threadPool.shutdownNow(); + } + } +} From 9f758494636d8b4ed12ca93841e3148fbb9bd59b Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Fri, 17 Oct 2025 09:25:16 -0400 Subject: [PATCH 029/174] Sort members --- .../channels/CloseShieldChannelHandler.java | 8 +++---- .../io/channels/CloseShieldChannelTest.java | 22 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java index 919b86d7ceb..fdafd544f07 100644 --- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java +++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java @@ -56,10 +56,6 @@ final class CloseShieldChannelHandler implements InvocationHandler { SUPPORTED_INTERFACES = Collections.unmodifiableSet(interfaces); } - static boolean isSupported(final Class interfaceClass) { - return SUPPORTED_INTERFACES.contains(interfaceClass); - } - /** * Tests whether the given method is allowed to be called after the shield is closed. * @@ -73,6 +69,10 @@ private static boolean isAllowedAfterClose(final Class declaringClass, final return parameterCount == 0 && name.equals("supportedOptions") && NetworkChannel.class.equals(declaringClass); } + static boolean isSupported(final Class interfaceClass) { + return SUPPORTED_INTERFACES.contains(interfaceClass); + } + /** * Tests whether the given method returns 'this' (the channel) as per JDK spec. * diff --git a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java index b21a5b8153b..4676e64c060 100644 --- a/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/CloseShieldChannelTest.java @@ -126,17 +126,6 @@ void testCloseIsShielded(final Class channelInterface) throws verify(channel, times(2)).isOpen(); } - @Test - void testWrapFileChannel(final @TempDir Path tempDir) throws IOException { - final Path testFile = tempDir.resolve("test.txt"); - FileUtils.touch(testFile.toFile()); - try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { - fileChannelInterfaces().forEach(iface -> assertInstanceOf(iface, shield)); - // FileChannel is not an interface, so can not be implemented. - assertFalse(shield instanceof FileChannel, "not FileChannel"); - } - } - @Test void testDoesNotDoubleWrap() { final ByteChannel channel = mock(ByteChannel.class); @@ -290,6 +279,17 @@ void testToString(final Class channelClass) throws Exception assertTrue(shieldString.contains("MyChannel")); } + @Test + void testWrapFileChannel(final @TempDir Path tempDir) throws IOException { + final Path testFile = tempDir.resolve("test.txt"); + FileUtils.touch(testFile.toFile()); + try (FileChannel channel = FileChannel.open(testFile); Channel shield = CloseShieldChannel.wrap(channel)) { + fileChannelInterfaces().forEach(iface -> assertInstanceOf(iface, shield)); + // FileChannel is not an interface, so can not be implemented. + assertFalse(shield instanceof FileChannel, "not FileChannel"); + } + } + @Test void testWritableByteChannelMethods() throws Exception { final WritableByteChannel channel = mock(WritableByteChannel.class); From 3925b50456ada7a4e23ec89ccfa34c04d03b95d5 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Fri, 17 Oct 2025 09:29:11 -0400 Subject: [PATCH 030/174] Use final --- .../java/org/apache/commons/io/IOUtils.java | 4 ++-- .../org/apache/commons/io/FileUtilsTest.java | 2 +- .../commons/io/IOUtilsConcurrentTest.java | 8 ++++---- .../org/apache/commons/io/IOUtilsTest.java | 18 ++++++++++-------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 717be4b49bf..fb6bc6c1ac4 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -198,7 +198,7 @@ static char[] getScratchCharArray() { * * @param array the byte array to release. */ - static void releaseScratchByteArray(byte[] array) { + static void releaseScratchByteArray(final byte[] array) { final Object[] holder = SCRATCH_BYTE_BUFFER_HOLDER.get(); if (array == holder[1]) { Arrays.fill(array, (byte) 0); @@ -211,7 +211,7 @@ static void releaseScratchByteArray(byte[] array) { * * @param array the char array to release. */ - static void releaseScratchCharArray(char[] array) { + static void releaseScratchCharArray(final char[] array) { final Object[] holder = SCRATCH_CHAR_BUFFER_HOLDER.get(); if (array == holder[1]) { Arrays.fill(array, (char) 0); diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java index ba9065d4f31..e45baaf421c 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java @@ -170,7 +170,7 @@ List list(final File startDirectory) throws IOException { */ private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker(); - private static void setDosReadOnly(Path p, boolean readOnly) throws IOException { + private static void setDosReadOnly(final Path p, final boolean readOnly) throws IOException { if (Files.getFileStore(p).supportsFileAttributeView(DosFileAttributeView.class)) { Files.setAttribute(p, "dos:readonly", readOnly, LinkOption.NOFOLLOW_LINKS); } diff --git a/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java b/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java index 0e1fb057175..1f1fb2a13fe 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java @@ -48,7 +48,7 @@ private static class ChecksumReader extends Reader { private final long expectedChecksumValue; private final Reader reader; - ChecksumReader(Reader reader, long expectedChecksumValue) { + ChecksumReader(final Reader reader, final long expectedChecksumValue) { this.reader = reader; this.checksum = new CRC32(); this.expectedChecksumValue = expectedChecksumValue; @@ -69,7 +69,7 @@ public int read() throws IOException { } @Override - public int read(char[] cbuf, int off, int len) throws IOException { + public int read(final char[] cbuf, final int off, final int len) throws IOException { final int n = reader.read(cbuf, off, len); if (n > 0) { final byte[] bytes = new String(cbuf, off, n).getBytes(Charset.defaultCharset()); @@ -171,7 +171,7 @@ static Stream> testConcurrentReaderTasks() { @ParameterizedTest @MethodSource - void testConcurrentInputStreamTasks(IOConsumer consumer) throws InterruptedException { + void testConcurrentInputStreamTasks(final IOConsumer consumer) throws InterruptedException { final ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); try { final List> futures = IntStream.range(0, THREAD_COUNT * RUNS_PER_THREAD) @@ -194,7 +194,7 @@ void testConcurrentInputStreamTasks(IOConsumer consumer) throws Int @ParameterizedTest @MethodSource - void testConcurrentReaderTasks(IOConsumer consumer) throws InterruptedException { + void testConcurrentReaderTasks(final IOConsumer consumer) throws InterruptedException { final ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT); try { final List> futures = IntStream.range(0, THREAD_COUNT * RUNS_PER_THREAD) diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index e9fed5c0c0e..7632b316cba 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -421,7 +421,7 @@ void testByteArrayWithNegativeSize() { @ParameterizedTest @MethodSource - void testCheckFromIndexSizeInvalidCases(int off, int len, int arrayLength) { + void testCheckFromIndexSizeInvalidCases(final int off, final int len, final int arrayLength) { final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.checkFromIndexSize(off, len, arrayLength)); assertTrue(ex.getMessage().contains(String.valueOf(off))); assertTrue(ex.getMessage().contains(String.valueOf(len))); @@ -431,7 +431,7 @@ void testCheckFromIndexSizeInvalidCases(int off, int len, int arrayLength) { final IndexOutOfBoundsException jreEx = assertThrows(IndexOutOfBoundsException.class, () -> { try { Objects.class.getDeclaredMethod("checkFromIndexSize", int.class, int.class, int.class).invoke(null, off, len, arrayLength); - } catch (InvocationTargetException ite) { + } catch (final InvocationTargetException ite) { throw ite.getTargetException(); } }); @@ -441,13 +441,13 @@ void testCheckFromIndexSizeInvalidCases(int off, int len, int arrayLength) { @ParameterizedTest @MethodSource - void testCheckFromIndexSizeValidCases(int off, int len, int arrayLength) { + void testCheckFromIndexSizeValidCases(final int off, final int len, final int arrayLength) { assertDoesNotThrow(() -> IOUtils.checkFromIndexSize(off, len, arrayLength)); } @ParameterizedTest @MethodSource - void testCheckFromToIndexInvalidCases(int from, int to, int arrayLength) { + void testCheckFromToIndexInvalidCases(final int from, final int to, final int arrayLength) { final IndexOutOfBoundsException ex = assertThrows(IndexOutOfBoundsException.class, () -> IOUtils.checkFromToIndex(from, to, arrayLength)); assertTrue(ex.getMessage().contains(String.valueOf(from))); assertTrue(ex.getMessage().contains(String.valueOf(to))); @@ -457,7 +457,7 @@ void testCheckFromToIndexInvalidCases(int from, int to, int arrayLength) { final IndexOutOfBoundsException jreEx = assertThrows(IndexOutOfBoundsException.class, () -> { try { Objects.class.getDeclaredMethod("checkFromToIndex", int.class, int.class, int.class).invoke(null, from, to, arrayLength); - } catch (InvocationTargetException ite) { + } catch (final InvocationTargetException ite) { throw ite.getTargetException(); } }); @@ -467,7 +467,7 @@ void testCheckFromToIndexInvalidCases(int from, int to, int arrayLength) { @ParameterizedTest @MethodSource - void testCheckFromToIndexValidCases(int from, int to, int arrayLength) { + void testCheckFromToIndexValidCases(final int from, final int to, final int arrayLength) { assertDoesNotThrow(() -> IOUtils.checkFromToIndex(from, to, arrayLength)); } @@ -1168,7 +1168,8 @@ void testCopyLarge_SkipWithInvalidOffset() throws IOException { @ParameterizedTest @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") - void testRead_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + void testRead_InputStream_Offset_ArgumentsValidation(final InputStream input, final byte[] b, final int off, final int len, + final Class expected) { assertThrows(expected, () -> IOUtils.read(input, b, off, len)); } @@ -1223,7 +1224,8 @@ void testReadFully_InputStream_Offset() throws Exception { @ParameterizedTest @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") - void testReadFully_InputStream_Offset_ArgumentsValidation(InputStream input, byte[] b, int off, int len, Class expected) { + void testReadFully_InputStream_Offset_ArgumentsValidation(final InputStream input, final byte[] b, final int off, final int len, + final Class expected) { assertThrows(expected, () -> IOUtils.read(input, b, off, len)); } From 0698bd9eafb2d20fb85f4ea4f695db1b702dcef2 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Fri, 17 Oct 2025 10:49:02 -0400 Subject: [PATCH 031/174] Reduce internal boilerplate Make the internal scratch byte and char buffers auto-closeable --- .../java/org/apache/commons/io/CopyUtils.java | 8 +- .../java/org/apache/commons/io/IOUtils.java | 182 ++++++++++-------- .../org/apache/commons/io/IOCaseTest.java | 49 ++--- 3 files changed, 132 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index fdb137d2039..b3243a30a4f 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -29,6 +29,8 @@ import java.io.Writer; import java.nio.charset.Charset; +import org.apache.commons.io.IOUtils.ScratchChars; + /** * This class provides static utility methods for buffered * copying between sources ({@link InputStream}, {@link Reader}, @@ -278,8 +280,8 @@ public static int copy( final Reader input, final Writer output) throws IOException { - final char[] buffer = IOUtils.ScratchBufferHolder.getScratchCharArray(); - try { + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] buffer = scratch.array(); int count = 0; int n; while (EOF != (n = input.read(buffer))) { @@ -287,8 +289,6 @@ public static int copy( count += n; } return count; - } finally { - IOUtils.ScratchBufferHolder.releaseScratchCharArray(buffer); } } diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index fb6bc6c1ac4..5d3d7cc5850 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -133,7 +133,7 @@ public class IOUtils { // or return one of them. /** - * Holder for per-thread internal scratch buffers. + * Holder for per-thread internal scratch buffer. * *

Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer * is allocated to avoid data corruption.

@@ -141,80 +141,120 @@ public class IOUtils { *

Typical usage:

* *
{@code
-     * final byte[] buffer = ScratchBufferHolder.getScratchByteArray();
-     * try {
+     * try (ScratchBytes scratch = ScratchBytes.get()) {
      *     // use the buffer
-     * } finally {
-     *     ScratchBufferHolder.releaseScratchByteArray(buffer);
+     *     byte[] bytes = scratch.array();
+     *     // ...
      * }
      * }
*/ - static final class ScratchBufferHolder { + static final class ScratchBytes implements AutoCloseable { /** - * Holder for internal byte array buffer. + * Wraps an internal byte array. + * + * [0] boolean in use. + * [1] byte[] buffer. */ - private static final ThreadLocal SCRATCH_BYTE_BUFFER_HOLDER = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() }); - - /** - * Holder for internal char array buffer. - */ - private static final ThreadLocal SCRATCH_CHAR_BUFFER_HOLDER = ThreadLocal.withInitial(() -> new Object[] { false, charArray() }); - + private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, new ScratchBytes(byteArray()) }); /** * Gets the internal byte array buffer. * * @return the internal byte array buffer. */ - static byte[] getScratchByteArray() { - final Object[] holder = SCRATCH_BYTE_BUFFER_HOLDER.get(); + static ScratchBytes get() { + final Object[] holder = LOCAL.get(); // If already in use, return a new array if ((boolean) holder[0]) { - return byteArray(); + return new ScratchBytes(byteArray()); } holder[0] = true; - return (byte[]) holder[1]; + return (ScratchBytes) holder[1]; + } + + private final byte[] buffer; + + private ScratchBytes(final byte[] buffer) { + this.buffer = buffer; + } + + byte[] array() { + return buffer; } /** - * Gets the char array buffer. - * - * @return the char array buffer. + * If the buffer is the internal array, clear and release it for reuse. */ - static char[] getScratchCharArray() { - final Object[] holder = SCRATCH_CHAR_BUFFER_HOLDER.get(); - // If already in use, return a new array - if ((boolean) holder[0]) { - return charArray(); + @Override + public void close() { + final Object[] holder = LOCAL.get(); + if (buffer == ((ScratchBytes) holder[1]).buffer) { + Arrays.fill(buffer, (byte) 0); + holder[0] = false; } - holder[0] = true; - return (char[]) holder[1]; } + } + + /** + * Holder for per-thread internal scratch buffer. + * + *

Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer + * is allocated to avoid data corruption.

+ * + *

Typical usage:

+ * + *
{@code
+     * try (ScratchChars scratch = ScratchChars.get()) {
+     *     // use the buffer
+     *     char[] bytes = scratch.array();
+     *     // ...
+     * }
+     * }
+ */ + static final class ScratchChars implements AutoCloseable { + /** + * Wraps an internal char array. + * + * [0] boolean in use. + * [1] char[] buffer. + */ + private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, new ScratchChars(charArray()) }); /** - * If the argument is the internal byte array, release it for reuse. + * Gets the internal char array buffer. * - * @param array the byte array to release. + * @return the internal char array buffer. */ - static void releaseScratchByteArray(final byte[] array) { - final Object[] holder = SCRATCH_BYTE_BUFFER_HOLDER.get(); - if (array == holder[1]) { - Arrays.fill(array, (byte) 0); - holder[0] = false; + static ScratchChars get() { + final Object[] holder = LOCAL.get(); + // If already in use, return a new array + if ((boolean) holder[0]) { + return new ScratchChars(charArray()); } + holder[0] = true; + return (ScratchChars) holder[1]; + } + + private final char[] buffer; + + private ScratchChars(final char[] buffer) { + this.buffer = buffer; + } + + char[] array() { + return buffer; } /** - * If the argument is the internal char array, release it for reuse. - * - * @param array the char array to release. + * If the buffer is the internal array, clear and release it for reuse. */ - static void releaseScratchCharArray(final char[] array) { - final Object[] holder = SCRATCH_CHAR_BUFFER_HOLDER.get(); - if (array == holder[1]) { - Arrays.fill(array, (char) 0); + @Override + public void close() { + final Object[] holder = LOCAL.get(); + if (buffer == ((ScratchChars) holder[1]).buffer) { + Arrays.fill(buffer, (char) 0); holder[0] = false; } } @@ -660,8 +700,8 @@ static void checkFromToIndex(final int fromIndex, final int toIndex, final int l * @see IO#clear() */ static void clear() { - ScratchBufferHolder.SCRATCH_BYTE_BUFFER_HOLDER.remove(); - ScratchBufferHolder.SCRATCH_CHAR_BUFFER_HOLDER.remove(); + ScratchBytes.LOCAL.remove(); + ScratchChars.LOCAL.remove(); } /** @@ -1205,14 +1245,14 @@ public static boolean contentEquals(final Reader input1, final Reader input2) th } // reuse one - final char[] array1 = ScratchBufferHolder.getScratchCharArray(); - // but allocate another - final char[] array2 = charArray(); - int pos1; - int pos2; - int count1; - int count2; - try { + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] array1 = scratch.array(); + // but allocate another + final char[] array2 = charArray(); + int pos1; + int pos2; + int count1; + int count2; while (true) { pos1 = 0; pos2 = 0; @@ -1240,8 +1280,6 @@ public static boolean contentEquals(final Reader input1, final Reader input2) th } } } - } finally { - ScratchBufferHolder.releaseScratchCharArray(array1); } } @@ -1722,11 +1760,8 @@ public static long copyLarge(final InputStream inputStream, final OutputStream o * @since 2.2 */ public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length) throws IOException { - final byte[] buffer = ScratchBufferHolder.getScratchByteArray(); - try { - return copyLarge(input, output, inputOffset, length, buffer); - } finally { - ScratchBufferHolder.releaseScratchByteArray(buffer); + try (ScratchBytes scratch = ScratchBytes.get()) { + return copyLarge(input, output, inputOffset, length, scratch.array()); } } @@ -1797,11 +1832,8 @@ public static long copyLarge(final InputStream input, final OutputStream output, * @since 1.3 */ public static long copyLarge(final Reader reader, final Writer writer) throws IOException { - final char[] buffer = ScratchBufferHolder.getScratchCharArray(); - try { - return copyLarge(reader, writer, buffer); - } finally { - ScratchBufferHolder.releaseScratchCharArray(buffer); + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + return copyLarge(reader, writer, scratch.array()); } } @@ -1849,11 +1881,8 @@ public static long copyLarge(final Reader reader, final Writer writer, final cha * @since 2.2 */ public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length) throws IOException { - final char[] buffer = ScratchBufferHolder.getScratchCharArray(); - try { - return copyLarge(reader, writer, inputOffset, length, buffer); - } finally { - ScratchBufferHolder.releaseScratchCharArray(buffer); + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + return copyLarge(reader, writer, inputOffset, length, scratch.array()); } } @@ -2553,11 +2582,8 @@ public static URL resourceToURL(final String name, final ClassLoader classLoader * @since 2.0 */ public static long skip(final InputStream input, final long skip) throws IOException { - final byte[] buffer = ScratchBufferHolder.getScratchByteArray(); - try { - return skip(input, skip, () -> buffer); - } finally { - ScratchBufferHolder.releaseScratchByteArray(buffer); + try (ScratchBytes scratch = ScratchBytes.get()) { + return skip(input, skip, scratch::array); } } @@ -2665,18 +2691,16 @@ public static long skip(final Reader reader, final long toSkip) throws IOExcepti throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); } long remain = toSkip; - final char[] charArray = ScratchBufferHolder.getScratchCharArray(); - try { + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] chars = scratch.array(); while (remain > 0) { // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() - final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length)); + final long n = reader.read(chars, 0, (int) Math.min(remain, chars.length)); if (n < 0) { // EOF break; } remain -= n; } - } finally { - ScratchBufferHolder.releaseScratchCharArray(charArray); } return toSkip - remain; } diff --git a/src/test/java/org/apache/commons/io/IOCaseTest.java b/src/test/java/org/apache/commons/io/IOCaseTest.java index 1121b38eeeb..54073da8096 100644 --- a/src/test/java/org/apache/commons/io/IOCaseTest.java +++ b/src/test/java/org/apache/commons/io/IOCaseTest.java @@ -30,6 +30,8 @@ import java.io.ObjectOutputStream; import java.util.Arrays; +import org.apache.commons.io.IOUtils.ScratchBytes; +import org.apache.commons.io.IOUtils.ScratchChars; import org.junit.jupiter.api.Test; /** @@ -297,49 +299,48 @@ void test_getName() { @Test void test_getScratchByteArray() { - final byte[] array = IOUtils.ScratchBufferHolder.getScratchByteArray(); - try { + final byte[] array; + try (ScratchBytes scratch = IOUtils.ScratchBytes.get()) { + array = scratch.array(); assert0(array); Arrays.fill(array, (byte) 1); // Get another array, while the first is still in use - final byte[] array2 = IOUtils.ScratchBufferHolder.getScratchByteArray(); - assert0(array2); - assertNotSame(array, array2); - } finally { - // Release first array - IOUtils.ScratchBufferHolder.releaseScratchByteArray(array); + // The test doesn't need the try here but that's the pattern. + try (ScratchBytes scratch2 = IOUtils.ScratchBytes.get()) { + assertNotSame(scratch, scratch2); + final byte[] array2 = scratch2.array(); + assert0(array2); + assertNotSame(array, array2); + } } // The first array should be reset and reusable - final byte[] array3 = IOUtils.ScratchBufferHolder.getScratchByteArray(); - try { + try (ScratchBytes scratch = IOUtils.ScratchBytes.get()) { + final byte[] array3 = scratch.array(); assert0(array3); assertSame(array, array3); - } finally { - IOUtils.ScratchBufferHolder.releaseScratchByteArray(array3); } } @Test void test_getScratchCharArray() { - final char[] array = IOUtils.ScratchBufferHolder.getScratchCharArray(); - try { + final char[] array; + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + array = scratch.array(); assert0(array); Arrays.fill(array, (char) 1); // Get another array, while the first is still in use - final char[] array2 = IOUtils.ScratchBufferHolder.getScratchCharArray(); - assert0(array2); - assertNotSame(array, array2); - } finally { - // Release first array - IOUtils.ScratchBufferHolder.releaseScratchCharArray(array); + // The test doesn't need the try here but that's the pattern. + try (ScratchChars scratch2 = IOUtils.ScratchChars.get()) { + final char[] array2 = scratch2.array(); + assert0(array2); + assertNotSame(array, array2); + } } // The first array should be reset and reusable - final char[] array3 = IOUtils.ScratchBufferHolder.getScratchCharArray(); - try { + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] array3 = scratch.array(); assert0(array3); assertSame(array, array3); - } finally { - IOUtils.ScratchBufferHolder.releaseScratchCharArray(array3); } } From 2707d1fd70e22ae3675508d294bb93046e02b209 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Sun, 19 Oct 2025 03:07:19 +0200 Subject: [PATCH 032/174] Prevent classloader memory leak in `ScratchBytes`/`ScratchChars` (#804) Commit 0698bd9eafb2d20fb85f4ea4f695db1b702dcef2 introduced convenient `AutoCloseable` usage for `ScratchBytes` and `ScratchChars`. However, it also introduced a **classloader memory leak risk** in application server environments by storing custom wrapper instances directly in a `ThreadLocal`. This PR keeps the ergonomic `AutoCloseable` pattern while eliminating the classloader leak risk: * Store **only primitive buffers** (`byte[]` / `char[]`) in the `ThreadLocal`, not custom classes. * Introduce two types of `ScratchBytes` / `ScratchChars` instances: * **Global instance** (`buffer == null`) that fetches its buffer from the `ThreadLocal`. * **Reentrant instances** (`buffer != null`) for nested usage without interfering with shared buffers. **Note:** While this revision keeps the readability of using the `AutoCloseable` API, it also introduces a performance regression compared to the original #801 design: retrieving a buffer now requires two `ThreadLocal` lookups: once in `get()` and once in `array()`. The original design avoided this overhead intentionally. Since these classes are package-private and used in performance-sensitive paths, we should carefully weigh the trade-off between API convenience and runtime cost. --- .../java/org/apache/commons/io/IOUtils.java | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 5d3d7cc5850..5a005fa6792 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -156,7 +156,9 @@ static final class ScratchBytes implements AutoCloseable { * [0] boolean in use. * [1] byte[] buffer. */ - private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, new ScratchBytes(byteArray()) }); + private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() }); + + private static final ScratchBytes INSTANCE = new ScratchBytes(null); /** * Gets the internal byte array buffer. @@ -170,9 +172,12 @@ static ScratchBytes get() { return new ScratchBytes(byteArray()); } holder[0] = true; - return (ScratchBytes) holder[1]; + return INSTANCE; } + /** + * The buffer, or null if using the thread-local buffer. + */ private final byte[] buffer; private ScratchBytes(final byte[] buffer) { @@ -180,7 +185,7 @@ private ScratchBytes(final byte[] buffer) { } byte[] array() { - return buffer; + return buffer != null ? buffer : (byte[]) LOCAL.get()[1]; } /** @@ -188,9 +193,9 @@ byte[] array() { */ @Override public void close() { - final Object[] holder = LOCAL.get(); - if (buffer == ((ScratchBytes) holder[1]).buffer) { - Arrays.fill(buffer, (byte) 0); + if (buffer == null) { + final Object[] holder = LOCAL.get(); + Arrays.fill((byte[]) holder[1], (byte) 0); holder[0] = false; } } @@ -220,7 +225,9 @@ static final class ScratchChars implements AutoCloseable { * [0] boolean in use. * [1] char[] buffer. */ - private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, new ScratchChars(charArray()) }); + private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, charArray() }); + + private static final ScratchChars INSTANCE = new ScratchChars(null); /** * Gets the internal char array buffer. @@ -234,9 +241,12 @@ static ScratchChars get() { return new ScratchChars(charArray()); } holder[0] = true; - return (ScratchChars) holder[1]; + return INSTANCE; } + /** + * The buffer, or null if using the thread-local buffer. + */ private final char[] buffer; private ScratchChars(final char[] buffer) { @@ -244,7 +254,7 @@ private ScratchChars(final char[] buffer) { } char[] array() { - return buffer; + return buffer != null ? buffer : (char[]) LOCAL.get()[1]; } /** @@ -252,9 +262,9 @@ char[] array() { */ @Override public void close() { - final Object[] holder = LOCAL.get(); - if (buffer == ((ScratchChars) holder[1]).buffer) { - Arrays.fill(buffer, (char) 0); + if (buffer == null) { + final Object[] holder = LOCAL.get(); + Arrays.fill((char[]) holder[1], (char) 0); holder[0] = false; } } From ee8dd0679c60c67599260a3c653b4bebb3b137f1 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sun, 19 Oct 2025 08:57:51 -0400 Subject: [PATCH 033/174] Fix grammar --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7578b4da036..4cbe168c3e8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -25,6 +25,6 @@ Before you push a pull request, review this list: - [ ] Read the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) if you use Artificial Intelligence (AI). - [ ] I used AI to create any part of, or all of, this pull request. - [ ] Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself. -- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best-practice. +- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice. - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. - [ ] Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process. From d9714be2115c66ac241ae9d1cd8e03398ac76842 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 21 Oct 2025 10:03:04 -0400 Subject: [PATCH 034/174] Java 25 builds are no longer experimental --- .github/workflows/maven.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7d0f0892434..ee6b9c99a12 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -39,7 +39,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-13] - java: [ 8, 11, 17, 21 ] + java: [ 8, 11, 17, 21, 25 ] experimental: [false] # Keep the same parameter order as the matrix above include: @@ -48,16 +48,6 @@ jobs: java: 21 experimental: false deploy: true - # Experimental builds: Java 25-ea - - os: ubuntu-latest - java: 25 - experimental: true - - os: windows-latest - java: 25 - experimental: true - - os: macos-latest - java: 25 - experimental: true # Experimental builds: Java 26-ea - os: ubuntu-latest java: 26-ea From af17dc6ce77d47ab57ad484f5d936004a5bf24a2 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Thu, 23 Oct 2025 08:52:17 -0400 Subject: [PATCH 035/174] Javadoc --- .../commons/io/build/AbstractOrigin.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java index d84aefdb79a..d8edc15ea46 100644 --- a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java +++ b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java @@ -366,6 +366,7 @@ public abstract static class AbstractRandomAccessFileOrigin * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public AbstractRandomAccessFileOrigin(final T origin) { super(origin); @@ -437,6 +438,7 @@ public static class ByteArrayOrigin extends AbstractOrigin * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public ChannelOrigin(final Channel origin) { super(origin); @@ -563,6 +566,7 @@ public static class CharSequenceOrigin extends AbstractOrigin { * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public FileOrigin(final File origin) { super(origin); @@ -689,6 +694,7 @@ public static class InputStreamOrigin extends AbstractOrigin { * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public PathOrigin(final Path origin) { super(origin); @@ -892,6 +900,7 @@ public static class ReaderOrigin extends AbstractOrigin { * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public ReaderOrigin(final Reader origin) { super(origin); @@ -959,6 +968,7 @@ public static class URIOrigin extends AbstractOrigin { * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public URIOrigin(final URI origin) { super(origin); @@ -1007,6 +1017,7 @@ public static class WriterOrigin extends AbstractOrigin { * Constructs a new instance for the given origin. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ public WriterOrigin(final Writer origin) { super(origin); @@ -1057,15 +1068,16 @@ public Writer getWriter(final Charset charset, final OpenOption... options) thro * Constructs a new instance for subclasses. * * @param origin The origin, not null. + * @throws NullPointerException if {@code origin} is {@code null}. */ protected AbstractOrigin(final T origin) { this.origin = Objects.requireNonNull(origin, "origin"); } /** - * Gets the origin. + * Gets the origin, never null. * - * @return the origin. + * @return the origin, never null. */ @Override public T get() { @@ -1113,6 +1125,7 @@ public byte[] getByteArray(final long position, final int length) throws IOExcep * @param The type of channel to return. * @throws IOException If an I/O error occurs. * @throws UnsupportedOperationException If this origin cannot be converted to a channel of the given type. + * @see #getChannel(OpenOption...) * @since 2.21.0 */ public final C getChannel(final Class channelType, final OpenOption... options) throws IOException { @@ -1131,6 +1144,7 @@ public final C getChannel(final Class channelType, final * @return A new Channel on the origin. * @throws IOException If an I/O error occurs. * @throws UnsupportedOperationException If this origin cannot be converted to a channel. + * @see #getChannel(Class, OpenOption...) * @since 2.21.0 */ protected Channel getChannel(final OpenOption... options) throws IOException { @@ -1217,6 +1231,11 @@ public Reader getReader(final Charset charset) throws IOException { return Files.newBufferedReader(getPath(), Charsets.toCharset(charset)); } + /** + * Gets simple name of the underlying class. + * + * @return The simple name of the underlying class. + */ private String getSimpleClassName() { return getClass().getSimpleName(); } From 1cf65a66e793a9e4cbfc0d0cecc29b7df341e1a5 Mon Sep 17 00:00:00 2001 From: J Hawkins <127335637+hawjo01@users.noreply.github.com> Date: Thu, 23 Oct 2025 19:38:40 -0600 Subject: [PATCH 036/174] Fix javadoc to indicate the correct class that is built. (#806) --- .../java/org/apache/commons/io/input/XmlStreamReader.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java index 7f5102e8218..e438c940487 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java @@ -42,7 +42,6 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.build.AbstractStreamBuilder; import org.apache.commons.io.function.IOConsumer; -import org.apache.commons.io.output.XmlStreamWriter; /** * Character stream that handles all the necessary Voodoo to figure out the charset encoding of the XML document within the stream. @@ -76,7 +75,7 @@ public class XmlStreamReader extends Reader { // @formatter:off /** - * Builds a new {@link XmlStreamWriter}. + * Builds a new {@link XmlStreamReader}. * * Constructs a Reader using an InputStream and the associated content-type header. This constructor is lenient regarding the encoding detection. *

@@ -131,7 +130,7 @@ public Builder() { } /** - * Builds a new {@link XmlStreamWriter}. + * Builds a new {@link XmlStreamReader}. *

* You must set an aspect that supports {@link #getInputStream()}, otherwise, this method throws an exception. *

From 5677c9063d5808819de15ef7febb50df79705a22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:41:07 -0400 Subject: [PATCH 037/174] Bump github/codeql-action from 4.30.8 to 4.30.9 (#807) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.30.8 to 4.30.9. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f443b600d91635bebf5b0d9ebc620189c0d6fba5...16140ae1a102900babc80a33c44059580f687047) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.30.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ea037c8f839..797bf87270c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 + uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 + uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 + uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 77678628b08..6f3b56a60c2 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f443b600d91635bebf5b0d9ebc620189c0d6fba5 # 3.29.5 + uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 with: sarif_file: results.sarif From 5954478cab510f332eb29e4f0143b9f1070d8739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Oct 2025 21:41:25 -0400 Subject: [PATCH 038/174] Bump org.apache.commons:commons-parent from 89 to 90 (#808) Bumps [org.apache.commons:commons-parent](https://github.com/apache/commons-parent) from 89 to 90. - [Changelog](https://github.com/apache/commons-parent/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-parent/commits) --- updated-dependencies: - dependency-name: org.apache.commons:commons-parent dependency-version: '90' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2f2162f800e..d3c5e213413 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 89 + 90 4.0.0 commons-io From 347d1dfbf33c0dac42b0415f286f1eb212765874 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 23 Oct 2025 22:10:26 -0400 Subject: [PATCH 039/174] [javadoc] Fix XmlStreamReader Javadoc to indicate the correct class that is built #806 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3aa41940132..0b85f7f4c5c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -57,6 +57,7 @@ The type attribute can be add,update,fix,remove. Javadoc general improvements. IOUtils.toByteArray() now throws EOFException when not enough data is available #796. Fix IOUtils.skip() usage in concurrent scenarios. + [javadoc] Fix XmlStreamReader Javadoc to indicate the correct class that is built #806. FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Add org.apache.commons.io.FileUtils.ONE_RB #763. From d92ebcce0bcd403b286ee59882dd65a577846242 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 23 Oct 2025 22:11:03 -0400 Subject: [PATCH 040/174] Bump org.apache.commons:commons-parent from 89 to 90 #808 --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 0b85f7f4c5c..cd5a9d8f851 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -74,7 +74,7 @@ The type attribute can be add,update,fix,remove. Add CloseShieldChannel to close-shielded NIO Channels #786. Added IOUtils.checkFromIndexSize as a Java 8 backport of Objects.checkFromIndexSize #790. - Bump org.apache.commons:commons-parent from 85 to 89 #774, #783. + Bump org.apache.commons:commons-parent from 85 to 90 #774, #783, #808. [test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0. [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.8 #769. [test] Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. From f92f7a063a56e6da6bece497d665ecba8c0d6165 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Fri, 24 Oct 2025 08:38:21 -0400 Subject: [PATCH 041/174] Add some basic requirements documentation. - Using h1 and h2 as done here is needed to get Javadoc to work on Java 8, 11, 17, 21, and 25 - I checked with `mvn clean javadoc:javadoc` --- src/main/javadoc/overview.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index 7fa4bd1f700..d9ac38e071d 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -17,6 +17,8 @@ --> +

Apache Commons IO

+

Introduction

The Apache Commons IO component contains utility classes, filters, streams, readers and writers. @@ -28,5 +30,10 @@ The filters and streams provide useful implementations that perhaps should be in the JDK itself.

+

Requirements

+
    +
  • Java 8 or above.
  • +
  • If using OSGi, R7 or above.
  • +
From f11570f1b1373ba2cf25845e45ffaf5a88be5eda Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Thu, 30 Oct 2025 07:47:51 -0400 Subject: [PATCH 042/174] Use new Oak leaf logotype --- .../org/apache/commons/io/doc-files/logo.png | Bin 0 -> 9233 bytes src/main/javadoc/overview.html | 1 + src/media/commons-logo-component-100.xcf | Bin 0 -> 30258 bytes src/media/commons-logo-component.xcf | Bin 0 -> 146691 bytes src/media/logo-large.xcf | Bin 138018 -> 0 bytes src/media/logo.png | Bin 9536 -> 9233 bytes src/media/logo.xcf | Bin 21258 -> 0 bytes src/site/resources/images/logo.png | Bin 9536 -> 9233 bytes ...TestDataCR.dat => FileUtilsTestDataCR.bin} | 0 ...DataCRLF.dat => FileUtilsTestDataCRLF.bin} | 0 ...TestDataLF.dat => FileUtilsTestDataLF.bin} | 0 11 files changed, 1 insertion(+) create mode 100644 src/main/java/org/apache/commons/io/doc-files/logo.png create mode 100644 src/media/commons-logo-component-100.xcf create mode 100644 src/media/commons-logo-component.xcf delete mode 100644 src/media/logo-large.xcf delete mode 100644 src/media/logo.xcf rename src/test/resources/org/apache/commons/io/{FileUtilsTestDataCR.dat => FileUtilsTestDataCR.bin} (100%) rename src/test/resources/org/apache/commons/io/{FileUtilsTestDataCRLF.dat => FileUtilsTestDataCRLF.bin} (100%) rename src/test/resources/org/apache/commons/io/{FileUtilsTestDataLF.dat => FileUtilsTestDataLF.bin} (100%) diff --git a/src/main/java/org/apache/commons/io/doc-files/logo.png b/src/main/java/org/apache/commons/io/doc-files/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..02a758f0ed838a31f373f399db089a898c161e54 GIT binary patch literal 9233 zcmWk!1yCGI6g*smLvT4DI6;F2cXtRL+VkNgbb+lRV!5;)Ug*9-Gq%OlIdTEs)~$H#w5G)w;jB?Tw5$Y#oe@>WKq8mwq%a zjO!fbfm;k~#vF=jYLwQYdM8Ja-AH9!E;j;N2HHyI9En^1zg@w(?l~i_tqcNStDpjP zv3Bp%@ho1O$+O(QzLW0xXj0+m^(K-5`K+rvosJFQD{vTC@TWqrXxUr7E>g%S9vw^T zJ2IO%P7XWt}Ms3ryIQOH5+SnsLv4fTSP6>CeDz&Lm5^YH$a>SW! z$#{x+v&%T&mOa!M^r|4VTDSchketg1Ot+cw?8;|JvAsIbWil!kU39bj$`jqK-K>WC zbKcFe&ak{2&6QFERR)|80t+D@iW_0SS;i2gtOR&16hE_W@ejpuOkQLG{r-p(k=Bmc zBAR-wEyYrfEumzF^E{>k3J_foT|}J6$F?6UgW{#Z>tMY?>ddpY`Zq{CYYw|En!`ib(BC}7N?s31Wyx4W*CIc?kMr%JmB1@(jDkT%gyZxu}olt!&h}_{O~@-T`I9IYhC^khwjBw_>0LJJRy;|zT;vZIQh6GyHycSQ8mG(kc+eg z%_KS#L->gL-0Nof26AMI_U^E*Dx~vzOGt2lmmM((j&;V|yyU*{vmUOJq$8p=LXYR# z(jSe06B`9w%P=F_(*C3EGWT$x%sZ(TWtP`G8>!Q`cqIiMYfGX~EQqCzQF*sZylfER zeF0Ip3Ql|!g1S+8pkg8QCc*{+BqK6$94@^d)#cI0)*ri?kjs?clOtb!V5V+ z(jyXLx!cU84LcdoJC{81Fb~OR-l(VJ#)I1#i(%O@tNay^VWIXvZab*!+NWNg6Qg|| z;SK>0ToV$!sQ0nEse1m$SGw`HAml|DMP@g_>^OBr6V;St&Ld5x{i zH-|hEy$YN9SA`MfvN;O9JBxI97W@&p=5{sPYU*sNw-9)FsYtimJZ!61IjW}sJ7~WY z#+af63{;#^;XbRrn${h)}Umf|7=y36*KGqEoihCi&qsEhH zFk+JksMK`zNpEmlJ39$<*9JH{mArG^BT-rylDioEg~A~ccgU`2?sLyLye^pw3$x+A zDahtTrmATiGfhoCQmPR6xEl7Q96%qid4`~*y{~|KUkb*r+)EH58x0irDm%0AXpp>L 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 literal 0 HcmV?d00001 diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index d9ac38e071d..0ffd28dace2 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -17,6 +17,7 @@ --> +Apache Commons IO

Apache Commons IO

Introduction

diff --git a/src/media/commons-logo-component-100.xcf b/src/media/commons-logo-component-100.xcf new file mode 100644 index 0000000000000000000000000000000000000000..d767311a12dadd6685c0d976ee23707dee5bfd26 GIT binary patch literal 30258 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 EAAc$RrT_o{ literal 0 HcmV?d00001 diff --git a/src/media/commons-logo-component.xcf b/src/media/commons-logo-component.xcf new file mode 100644 index 0000000000000000000000000000000000000000..a7dcdd43c1e09cb458fa792489781947091be25f GIT binary patch literal 146691 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 Hi{k$u@2EOn literal 0 HcmV?d00001 diff --git a/src/media/logo-large.xcf b/src/media/logo-large.xcf deleted file mode 100644 index caa37f4d0958b5750b4e422a616dad49017919bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138018 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

    |r? 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 B*2w?> diff --git a/src/media/logo.png b/src/media/logo.png index 396ba49f82fc6d07a9b6773ddf15f5ef0162c2c0..02a758f0ed838a31f373f399db089a898c161e54 100644 GIT binary patch delta 9191 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 delta 9496 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 VuLpk0$iq%3A7qpv)l#2={s&bRfAjzV diff --git a/src/media/logo.xcf b/src/media/logo.xcf deleted file mode 100644 index 72619d28ccfa2e67349fd90e94587afbed771fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21258 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 CU0K}# diff --git a/src/site/resources/images/logo.png b/src/site/resources/images/logo.png index 396ba49f82fc6d07a9b6773ddf15f5ef0162c2c0..02a758f0ed838a31f373f399db089a898c161e54 100644 GIT binary patch delta 9191 zcmVqdj*^SG&(ATxDWVx zno|tml86w^z;D7=8shT~W4o`QA%2sAkbYd=GOKK4_)0^BGiASutz}05f4|Q0^dccR z9k@Ast@(px+Qq)XTRLv6HEfj~gp|#*%8G%BBwKH4eS7Nv1o0^PfgXh2U18 zpa-|vKYXQm$5X&z`t!=Ljdu`Iw#+X3u7K-+y#a&}UXh5@w$3iQG2wZ455BN59=s-E zh-tpgkSqGdaAleHw}9XKe-2&ZxUsndq>mH(w z5yN=7WmcIPm{s=xVrh!ZWMN&^4}>&;%YiTW{w}vnTZG*w#OIEbOQ%%s*ZM)^mbP_~ z_6(;TAp{FrW|e&dVDs%|hM~mPVX2A)Hm55{!hibVF-`!+2aX*Ie;glnpAerrQVPK| zV9;lE1rg~H&v5EaLNK>=cG>?%B0LD3mExS`zXY07AoQZDF+$G9woSS)}`!|oH} z^QcoE1(0YKg_}PpXc;o1Gn%C?7p3{FS;9;Kw`REh#X-}TeU@j@b-bP_lW6nlRVQ1f zJ=Sq!i!zA4Q?*V8f3VbXW3O7Ky$5g{PzFSRkAc^L8pn;vEcMw5I2@<|cGaT%D&RH8 zjV;dcnId}TKNJ|Q%V+{#cHG#C9Lv}Rn1nL=lmMRsZvt;SZp_Q!`lx=6LxA0YR-hi3 z@3^rI1D%xpsuwj(t*iwO1P}(^?nkzF6qI^BH5Nz-(*;Zef4-REyz@&gXt*QKq`VV2 zSAUHI-v{pYNf>uJZtMqXt}W1n+f^TW5Lk`!N-Eh>^5#Fl<&GPBK1Esk0~T;5Fet_C zJm5v(r;Zz|%`ixu1K7Zr6z@I(JO=#2abpd>>s|*Y>aVMTyY%2WIK?w80)FDSv6s`- zLFhXCRu4)+e{2F~0l#(J*yd1t?Po|2V}n~Dq{QptrE`QLL?%MEODX@IXF~255Tl=T z+}J(93%+A#Tc*8ljzxYG_@5MnOb(8R0Z&_|eMz7m-vQnMzL$oO$@h31@UouWgU?c= z2a~(??3QXUjsRZ+Ub9SlT$=j~2Y#7?kjZBlr=Q`(e>Ah>EMQI=LIMoY>cY#GY3~`5 zvVXAJ|D|)CQM7qwL0b>5Z}gEPOM_CcVGJ%D+ZX%ETr z44uG-f55uH@nYbwmT8v;j{gSuQQ+8zz^i~8XoqpY{hG)jDf5iF;DODHqs5(@ja-Q7 zNy!C<5YvEtvYh)?o@dFSzz=ol{`X|u=Q~~=qZfp!NQtOz0BiUMD zmo(212d>iZWItdpt#|vEqxJ*7;j2Rh@GIZ%p8;p<=Qs+r>t|fxJx)q7kc5VwB$iA$ zC@KUc5&@F7G4pCVb1eVOpz%g}80!`lM)sK4-f2W-CU2cTgLFasGl%=^v+4HHV#r0y ze`KE8Wm=$9{xNC5aNJnJGVNRFGCJ)7oDbZPL%A~@H)bWjXv5A@%e1Eg4*_4*KkW%j z0siK=F=?6hWx&pk8+*fFn6A_7mT6xN%=U?qhw6a@;OBwC_s5PK`%9pVMV4uw0z3gc z0NmoZv2@n*YR8RT6VOGUvrPLU;E@2Sf9}zrrvrt)-@fm-v4;cgP-~g?X}aD?(e*;D z!-k|xV(FBF_7OtZy0h#hKpG9T>2WwI;=u6}a0+G;SS=U=^76t3w z!nWNi+arjSv-O8ka-|TWTI(6v@U3V>jBA};R;OpN|47M8rPCW$_hObT0)FN@fAleM zU*NR6w6S70{r#twY2WI&u}tf+8-Qz5{h*0n1$@P)?;Q{PP5)l6>$aPoQT7gW@{xfe zch~0^1CxEnYk@n`)ZsJBw2yY&SR#wadV8ARp4TFAiEp+{;>3VBj%C`Xrzz)M;1vD& z5X-cO4m68wGy@?I5JEh!#S=eve*=yNjuucQ3>G&`t-QlS-Z5rwZ8yEHd~R){CUE5z zO4Y|k@y5XgEjx|sEJE4bT>(u%lflj?Q@CwQj+|%|b2n={Fee5ss zEbEXmO&^Q)@jZs(t0BZOax;_KKS;C|kBCGNIjv_70WKDTA2m#^{9h^Mb>;JF*Jwk< zuhLz#v9_Q@K+B-L<0U{sN-i-BaiE@g@-^`MT14ctK(-n4cwj={e^?|aey70%Ev7w{ z=Jztov_(1x0n4;^rE5(yIV%BN3HX;?>Vf%sR+2s)^qe#zb0=LpZOXSnA4_NnAnE(O z5qP)<*MAU_QsFBAi8ZpMqtt6D9A=dEpv+R>G9koy4O1&`MzSIcrNw8p1*M4&(K2Me z&U;HQY8(V9cb_2@73vj$;+9Mn{wmi+ia0c*#Mh`OU;ns1 zohMXMI&j?BhYV1p6SofjuV%l(D~WHEz1i5h8}M6%GFD{6f954ox%$=Ot3SHDVr;xs zoJ!A~47$rv9`SgK(cbb&v~9zZ!nQT<6s^i4x{d=*@*R3Xx5L;Be+ScjDIt~fy1%Xe zW|{WL6!$&~sP-N5fO-0}-`Dq}6ofR$?1wuiFks$mnfC4}>hK+{C%UuX z-_jTzBno6_!Ok*KFvK$=#WE2omIWe0yAhEQ3?hKQBQ6sn;Uy^WI)qGg2oY}fabq<(=%IhmojFOoe@lVyra65K@UCUrcL8r}v2wB& z)&08DT*r;Qt3TJFeTacC>E(}mP%dfZz)$h538rdS)S`XTcy%Od`Qa{6K3Ez^EL4{9x_HP=cC^YXlu@jG*Bn)Aw|^rF?G92N{U9FKRJ6 z2^Y0ymkS;O8g-`vn4*_A(urR?Ya*qC3;ft$cP;h`O`5Cd3J{icHq%QTX9G|AX5C>Z zceZqxkYEJ>j1!ji_ zfEik(#YaXzA=|Rl@pU~TFU)fPILf8*ntZ=t$BivREu}q|!|ASWhlLD4q$6cYLxA_0 ze=Kfandk^~kiKG#hrDI!l*&=s*pW}vNy#_L=hbA>iI4J$Yj2Qwy)hN;(1w|08Aq_C z<9Q9royzOtS5jLl$G^S zlsDBOKJk6PA*J}UXjH|O0mDOgnQ>pErEqwUEV7w!RoUE{YZ|6j-iUGu%NJ@SoKilw zX4ST6*c4m0o^;&UDf%~|^;ZETa@m6zFzh6C-*~n?nEhQ&AKOUyRHz=c!+;~@f5K4} zUlj0KrctqQw9#6yYoCd^UP@UmK^Q_T19r;ObItdp{N@<7PRjO1$`B!XEWYYkH<@;! zi;hOGIKD~tH3sOc@_DuE3?VMaBO&jU$S-e8LWT&DcT$dTtm`D3cfQ1EUy>+HG|RSL z-n&IgdGnH~2bIv>+SpqpfU3A;e_Hw6+P3i3hS<>zJxKTy*?c8EB5g|&1&KD<-iv$B zDW6ySk%2gi?E59Np&9sg+1#2L2h6M4p7fGd-(N@A-9q$mZq3)1POY3IRKTZR&yW&MET3DmAbgb}cKDf6&z5VX+NF>c zvXg?gx`dI-j49!ddPMk1AL~CeBxHyIMM?lq$~#EE9cc?#giI$AUpM_HL!qO>~ z`_i>@ptooYUtx#=N6HCJfAyYJ4$ZmwAjXNd)g=ltESKCqW?qda1n1MYP0RqdHcYLo zS~{h&eDRb@BYd49c6goAk42*@rlQ=zM2;nUg(Hl%g53>&xR3Rolp{g38G;6s!*M%&(a;&VyLcScnh0y$JlKAX@~zr`+zg`*DGNgx)oW%RVn zHz}s0aAc$-GKeF}=heR7Ftze=x+0eKH#PxtB=UFVb8DM=Q-EdKg{brkCTjDxhl38;1=2bj6|z4SmH~eUZg$+*XJMBL(O3M}I8q<| z;!Pkb^s!;U4+Oko2=T_EQ58R4II5y-;mC?zMOO&Ko+^ERe*tKBz4Kb!xYxPXYn5@i zHN9L00e=*Tt8*ZuVVU;NQCpCHmVuC0;$m2iS_DVbP4ujZX}ghcHv zyfEGM`hTjZe+{j`RL6}y8g{J^eVQo+VmJ_eGg@A>#wcscK;Yhroc|c#w75kW;yAj( zW`M--*2|KP2CukfVLaNpIMLeisn?chm2F7+OHYdmkuoW55?7`mAyo! z>FHJn+Ost5Rw4S-K@~UT#{%Jbh{(%@k|iblRkM0p2Kmg*y2J6{PB}WEzAN_pGKXa8(mb z^Z1UJD3R;(VT^ghLw-@fE&{QF^f?x@At6ddXJjx!ln7}Q3t<%Ei2@N7Mvuulvutk7 zl__4zgLHQszZ002ZAZM$KQh*FV{ZnImuXTTo1uQ6ppwPj8Mw9p6^T8m!`EqDf7dkS ze=N~;-$~ayU5LgGtpm>pb}q}bpF`!jOxEi&R0O_MSPT3BWr4n1lPR6rGY7c9abs;M z+O80|8Wl~jID^XYci__C0A`u?ZK%ATXac>Jr7jNvKS)u|;d;;;li4)FtHAVp1{O;x zzRq+Vi7$0|vnVWhsqiSTLk#K6!#(aCf8SUy1>(#;5E39FTV!$k6Is-`+$(OcPZYJj zmndm@Cr-v*Am|(6NzTonrM-my*An6waa#|L&jx- zXHs;IVZISJITQXOmk8*5KN$g%nb9+zdn7>0@mn=J=tMFv8mJJS=WsCAiQf2J0q zf@5Xd!#XTW2i*;o_~@k!BuEbY-y=n0AU&A<6SyJ+A(Il_4^i2@cFAyFaSnAk1DNAa zF`;AeK9S{llh+?keq&UnCZ&=wy*a3WP5^8W#YHa_PVzd%pm-n3ZO?Rp0F<6O(MedciqUih6yBDQ z60VxCqAt}yb3owx%YC@df6oH5)qB7hjvH$Th^MwT79~SQUT2y1BaRzOw^Z~x@O6L0 zJIl0B)}-;jpH8jc&I=3_k81rE)E>{%=pMa1h!25N95?o!ubeTuZH5KTy&7Bj(e|+1Y|5EGcGf}DG zllTtsfBN$gzT+PQ6N4GjbX56Y(LIxQ|IU;E)o$#qK*d>O3@VymcxDu)ueqNxHoarZ|7I`~SftCG+q0!n%kxs9gmLde@Q(9#8 z;|@O|^?950{ros2f6L=s<|m{sXNjJDy4ekYnBTKWC!MwQOq=R{-=%xd@2ea)c3)7> zb==tefHhobV@^8U=qIEuBcTV4b%9yeKSL)m1Qm%s5-4Mh z`dU$1^g`jWUYpppC&c_jdOY*as4+s1klPxMdXgVbSiU5kf8{J_gc#fh%kC)O_s1MJ zwls|{DpPduFQzl(IBx9yG`|I7q&|}7yqbWxyL%R~^@$ws_kXE$Z*86Rcj7$)>Vp4X zvoqA?A#L>fZyRM0VING>)-77RPW9|>1Vr*DfDbIwe$+DU-&v-8wq@FTZLN;F1u18| zUoAZn7ZXTVf3`ss7d=~e44cGWxrY6iH*R@dn}KmKDhTnmLMw1pLV9P6Z>q}_eXl9- zeS9zPw`ZVT-_LUX;(*~`uMDDOrf2lyqYReUM5g!e*MT$W)Vba-c&?G=Iag{+Z#qL- z9JPexZ{u{NT$N*8{4?S20@n#$ztgnjcptFbGVOnDe~rXLDPPJAcSeVl@*D!GWt#pD&zH*c6@60wSF#xXcsYf_Fw&800VcYjULDtSw<1P-|r$YHQhZ z+RAu|gd;uVh_Q`zzZln8pKEl2C8#y7Buu)}r)Sk8Ez?fwq#w}biU%+;%jJgzNV%MW z0l#Fj4;l8>>eTiJ`VOtgcQkd!jV*WF*g3i`f2RY#1?K7*+6&Cmmu(YLYGQ7ZQl74@ ze!k&G7;i+&OW!G&)S93u)u=Uh!m`B)LvjfD$sW8)BF9T9hf67kd(s;omvVTA^oEaZ ztlMX7W8Hyc8|zLO+gNx0*v7gW$2Hb17~fdm(ZiP_folV!>F;&Ms!W75v_a!tZBbm0 zfAaoFVzRa%rnR;MO@^$^ae+an8GVQMce*oT1j?mgVcPPrDnOyUF4wby- zHk1cSvct`_O#58msibw$GVS50^-8}v{hBj?roA4hPA10H%SPwZ zJ+DnCddE>7aXKoQ?q7l1{Ogc96Lm1!e&;qNr6%TDP0Uw;Zu0axQBw3|(b0*+e>#`8 z?3-9rB9L{Sl#AXOvA=;@Q_2U18baLs?x_8zjc;7sZySpB3ph`cYrIdI_zo(4`D)9w zSLoSv1Zqo{f6(~?YBBsqx_neYt?4}u)LW*#M34H1(cO8y4fxqWNpj=3u{D-y{|aS& zPOj5l30z>A_S;$o7{``@x^Kwmf8xEi8(f20oBuIzk!9M;P;QMaD5rvnboWMku0Pu* zt@v71VHI6rUK#Nba}~(%q*Aiu7?A}9`i1$KM@!z=ZKlfAyRDvBP-4U6yJ8 z1LcH#EL~3FQg@X1fTz=KE7Go7msqC#J3aDGV9TvrZ>8A^l+d$Caz<^)P~G`jKT8t* z<22{Bp_0}n-+Ry}^zU>T);Ae;+v67Rmd+0-U5B(~s5tf4Hv0I@DV8Q$eq+{(=a|*VEb3!=y)j z*>Pibm1&m?wJ0vSreqo4-D{2ymmAo{ThC73r=mn|C=eui8?W`Ov5j>DZgvT=<0EM3 zIj#?7NwkZTP}VHbUB(m9PmICQPZ$glwIo#};~hg~TViL~e=K&A&0>&jrbKRv7s<^< zQQ7JlbVLQxNFxP{@b!fl2&CM#4`nS)$V5^c$|)T|yNDL97K2&c-OaQJkOrPtBt03y zYmJgfL`eukN<#n%AwJtX@$oa+)x8iQKL4cb%R1o0GwWt}RTWjc14s5%toASpTZI8o zl45SW_UB9Pe_a>8z7RVig8E!dAIf?NKnUX`=+~%p4@egbs+|X_$oaX2!jTC?yve-wd=&IOsfF3*qTowz79Mr zrM$no&e;&YvJeA`lr!p`gk{=)1a9eJIgconPaMXUe_i^4;vfhIa zX4E+y;cE&pU`Yw!N%>bph>LqLTW<33lD>ea_Tb)2B=Vb{^lE3;&G5ok5h6qiof2S1 zozsd+d!8#%o}b}XC%q_ol1ZyB4mBYmLxkv#l)0bv8o$8|6ix3hyChGRW`A zd6>0NKy7H9wk;Y%M*@iX+NH^HW4C0vMxgdye|{O2yJAoMEE`Y;tQUc2Q-$mg5u!(= z1aRt{O;r`vSA`IFqk;wn@kDi9wX8BNgTDFA`cbis+v8_+h0uS643=oiv`<0Baygvz zzPP^xKDJEzMpRN;mLo}8*XUvSa>as7WZ-D92h1vT4yqgke1WSRD# ze^6-yCX(GbeoxdktXFl?pAaE>Pf7r%-ibSI>}n*(`AD-)O8JJ?CyygPyEfKI6})PD zCS(CB4(Rm2GfQ9vDj?JosJ)iKL2Lr>LP*RIeI{j>I2(J#!<&c-?f7DKos$&BPRK)D zRsg3~yRl{4d7E7o5alKCZ#`pSu|&TB%+t9LLxkv=PMHb< zF$T58>q&qs%qoNK5!rf*^}sACr>>wkSGtOD$BGV zMI~dQ8omGk14&6lK~$4TX1N-VN^bM}?e$r&D7(TiqDGMf;UyAn*Dk#_TugKTi#%#ZAB1x`{1Qv1h`=s35}0 zu#@`$Ut-_{Uk=e9q_irm-L&p>W2W<}U8e(;O77DgsI7vt|C5dzTa&Xsu42mG<0B<>v9q8oY^v`UB*P~kcr8-Q&!BJh1tFUnXL_`Yx01w-_Wl*(&morm|ve*kQ&qQLj& zUX;<2rOXf^awp}L6<0=38y5WdyGY9q>c+o|J|#Dzv!u_yBFI zdb)3Co7{^sCZ{MfM2Oysui|7tN-3Wipl!91?lCP7vrPL-xn69U_F%d@+9%T;gb2}V zo$_SB6)Gv}fP;1h_-ml;e`Z;xJv0YG3gCLWCq{kQabt_aE*PR$q^vTnQdIisr=2=S z4&e5hP4`4JmB5phX^+l8$Wl}u%ISew@;71k3y}&rty2obL|_Q;)Ie@5$Bk{)`758K z%d=-9u*fp)yHE}S^(aU5FQC>WFF^Ug`f-!v#$F7&Ux>bluO|R4e-io1KyNU|jlF|HS4??8?e*$RK`sV_aGkTDaccT1dLxkuvDPOO4osD6Wf#b&RLoE;WL?>)UC6zs2 zCzTBmqIaaMGOb;JLs7XDLv#`IWz_bp>A;($PB}JG>ULb$I?J@j;7_@?_0W+nHG7DVl&ST}3Tv1a$?n*} z+u;FJG=Qy*MpV$T5Fv6Sr4Zt1AR>`F`kLA|*fu*h!jyg?J$fv@9tV6Rp>_w?C6|X? xA;k8AY)c~RL4I|H>xAoSAwq-*5n^EC{{hxm*^zeuQj!1w002ovPDHLkV1gH3+UWoQ delta 9496 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 VuLpk0$iq%3A7qpv)l#2={s&bRfAjzV diff --git a/src/test/resources/org/apache/commons/io/FileUtilsTestDataCR.dat b/src/test/resources/org/apache/commons/io/FileUtilsTestDataCR.bin similarity index 100% rename from src/test/resources/org/apache/commons/io/FileUtilsTestDataCR.dat rename to src/test/resources/org/apache/commons/io/FileUtilsTestDataCR.bin diff --git a/src/test/resources/org/apache/commons/io/FileUtilsTestDataCRLF.dat b/src/test/resources/org/apache/commons/io/FileUtilsTestDataCRLF.bin similarity index 100% rename from src/test/resources/org/apache/commons/io/FileUtilsTestDataCRLF.dat rename to src/test/resources/org/apache/commons/io/FileUtilsTestDataCRLF.bin diff --git a/src/test/resources/org/apache/commons/io/FileUtilsTestDataLF.dat b/src/test/resources/org/apache/commons/io/FileUtilsTestDataLF.bin similarity index 100% rename from src/test/resources/org/apache/commons/io/FileUtilsTestDataLF.dat rename to src/test/resources/org/apache/commons/io/FileUtilsTestDataLF.bin From e81bb0a29a1fec17e5a628c8f0ac3ca767b0f0f3 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Thu, 30 Oct 2025 07:47:58 -0400 Subject: [PATCH 043/174] Bump org.apache.commons:commons-parent from 90 to 91 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- .../org/apache/commons/io/FileUtilsTest.java | 6 ++--- .../org/apache/commons/io/IOUtilsTest.java | 24 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index d3c5e213413..f60efbc76db 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 90 + 91 4.0.0 commons-io diff --git a/src/changes/changes.xml b/src/changes/changes.xml index cd5a9d8f851..07bb304a545 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -74,7 +74,7 @@ The type attribute can be add,update,fix,remove. Add CloseShieldChannel to close-shielded NIO Channels #786. Added IOUtils.checkFromIndexSize as a Java 8 backport of Objects.checkFromIndexSize #790. - Bump org.apache.commons:commons-parent from 85 to 90 #774, #783, #808. + Bump org.apache.commons:commons-parent from 85 to 91 #774, #783, #808. [test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0. [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.8 #769. [test] Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java index e45baaf421c..91d351efeaa 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java @@ -666,17 +666,17 @@ void testContentEqualsIgnoreEOL() throws Exception { assertFalse(FileUtils.contentEqualsIgnoreEOL(tfile1, tfile3, null)); assertFalse(FileUtils.contentEqualsIgnoreEOL(tfile2, tfile3, null)); - final URL urlCR = getClass().getResource("FileUtilsTestDataCR.dat"); + final URL urlCR = getClass().getResource("FileUtilsTestDataCR.bin"); assertNotNull(urlCR); final File cr = new File(urlCR.toURI()); assertTrue(cr.exists()); - final URL urlCRLF = getClass().getResource("FileUtilsTestDataCRLF.dat"); + final URL urlCRLF = getClass().getResource("FileUtilsTestDataCRLF.bin"); assertNotNull(urlCRLF); final File crlf = new File(urlCRLF.toURI()); assertTrue(crlf.exists()); - final URL urlLF = getClass().getResource("FileUtilsTestDataLF.dat"); + final URL urlLF = getClass().getResource("FileUtilsTestDataLF.bin"); assertNotNull(urlLF); final File lf = new File(urlLF.toURI()); assertTrue(lf.exists()); diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 7632b316cba..033fdffdd76 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -1375,16 +1375,16 @@ void testResourceToByteArray_ExistingResourceAtRootPackage_WithClassLoader() thr @Test void testResourceToByteArray_ExistingResourceAtSubPackage() throws Exception { - final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length(); - final byte[] bytes = IOUtils.resourceToByteArray("/org/apache/commons/io/FileUtilsTestDataCR.dat"); + final long fileSize = TestResources.getFile("FileUtilsTestDataCR.bin").length(); + final byte[] bytes = IOUtils.resourceToByteArray("/org/apache/commons/io/FileUtilsTestDataCR.bin"); assertNotNull(bytes); assertEquals(fileSize, bytes.length); } @Test void testResourceToByteArray_ExistingResourceAtSubPackage_WithClassLoader() throws Exception { - final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length(); - final byte[] bytes = IOUtils.resourceToByteArray("org/apache/commons/io/FileUtilsTestDataCR.dat", + final long fileSize = TestResources.getFile("FileUtilsTestDataCR.bin").length(); + final byte[] bytes = IOUtils.resourceToByteArray("org/apache/commons/io/FileUtilsTestDataCR.bin", ClassLoader.getSystemClassLoader()); assertNotNull(bytes); assertEquals(fileSize, bytes.length); @@ -1436,8 +1436,8 @@ void testResourceToString_ExistingResourceAtRootPackage_WithClassLoader() throws @Test void testResourceToString_ExistingResourceAtSubPackage() throws Exception { - final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length(); - final String content = IOUtils.resourceToString("/org/apache/commons/io/FileUtilsTestDataCR.dat", + final long fileSize = TestResources.getFile("FileUtilsTestDataCR.bin").length(); + final String content = IOUtils.resourceToString("/org/apache/commons/io/FileUtilsTestDataCR.bin", StandardCharsets.UTF_8); assertNotNull(content); @@ -1446,8 +1446,8 @@ void testResourceToString_ExistingResourceAtSubPackage() throws Exception { @Test void testResourceToString_ExistingResourceAtSubPackage_WithClassLoader() throws Exception { - final long fileSize = TestResources.getFile("FileUtilsTestDataCR.dat").length(); - final String content = IOUtils.resourceToString("org/apache/commons/io/FileUtilsTestDataCR.dat", + final long fileSize = TestResources.getFile("FileUtilsTestDataCR.bin").length(); + final String content = IOUtils.resourceToString("org/apache/commons/io/FileUtilsTestDataCR.bin", StandardCharsets.UTF_8, ClassLoader.getSystemClassLoader()); assertNotNull(content); @@ -1506,18 +1506,18 @@ void testResourceToURL_ExistingResourceAtRootPackage_WithClassLoader() throws Ex @Test void testResourceToURL_ExistingResourceAtSubPackage() throws Exception { - final URL url = IOUtils.resourceToURL("/org/apache/commons/io/FileUtilsTestDataCR.dat"); + final URL url = IOUtils.resourceToURL("/org/apache/commons/io/FileUtilsTestDataCR.bin"); assertNotNull(url); - assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat")); + assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.bin")); } @Test void testResourceToURL_ExistingResourceAtSubPackage_WithClassLoader() throws Exception { - final URL url = IOUtils.resourceToURL("org/apache/commons/io/FileUtilsTestDataCR.dat", + final URL url = IOUtils.resourceToURL("org/apache/commons/io/FileUtilsTestDataCR.bin", ClassLoader.getSystemClassLoader()); assertNotNull(url); - assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.dat")); + assertTrue(url.getFile().endsWith("/org/apache/commons/io/FileUtilsTestDataCR.bin")); } @Test From bc01dee31ec0ff10aa0841ff245b770fa1ecfade Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 21:16:05 -0400 Subject: [PATCH 044/174] Bump github/codeql-action from 4.30.9 to 4.31.2 (#811) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.30.9 to 4.31.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/16140ae1a102900babc80a33c44059580f687047...0499de31b99561a6d14a36a5f662c2a54f91beee) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.31.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 797bf87270c..276e14f41de 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 + uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 + uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 + uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 6f3b56a60c2..ac12058b3f0 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@16140ae1a102900babc80a33c44059580f687047 # 3.29.5 + uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 with: sarif_file: results.sarif From ad875d566f273f54094b6b872bf9433be9fd86a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 21:16:55 -0400 Subject: [PATCH 045/174] Bump actions/upload-artifact from 4.6.2 to 5.0.0 (#810) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 5.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...330a01c490aca151604b8cf639adc76d48f6c5d4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index ac12058b3f0..3215897f03b 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -59,7 +59,7 @@ jobs: publish_results: true - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # 5.0.0 with: name: SARIF file path: results.sarif From 3d6a7e113633e1a33ca254d744c3fcbab61663f3 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sat, 1 Nov 2025 06:50:22 -0400 Subject: [PATCH 046/174] Javadoc --- src/test/java/org/apache/commons/io/input/TailerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java index 4e764bf94ad..dcada2f8f3f 100644 --- a/src/test/java/org/apache/commons/io/input/TailerTest.java +++ b/src/test/java/org/apache/commons/io/input/TailerTest.java @@ -659,7 +659,7 @@ void testTailerEndOfFileReached() throws Exception { // write a few lines writeLines(file, "line7", "line8", "line9"); TestUtils.sleep(testDelayMillis); - // May be > 3 times due to underlying OS behavior wrt streams + // May be > 3 times due to underlying OS behavior and streams. assertTrue(listener.reachedEndOfFile >= 3, "end of file reached at least 3 times"); } } From d715865ee705fdb8ed786582bd6bd4ee996b0665 Mon Sep 17 00:00:00 2001 From: Sebb Date: Sat, 1 Nov 2025 16:59:41 +0000 Subject: [PATCH 047/174] Add dependabot email [skip ci] --- .asf.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.asf.yaml b/.asf.yaml index 5ea25ac8897..33a8dd8c4ff 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -23,7 +23,8 @@ notifications: pullrequests: issues@commons.apache.org jira_options: link label jobs: notifications@commons.apache.org - issues_bot_dependabot: notifications@commons.apache.org - pullrequests_bot_dependabot: notifications@commons.apache.org + # commits_bot_dependabot: dependabot@commons.apache.org + issues_bot_dependabot: dependabot@commons.apache.org + pullrequests_bot_dependabot: dependabot@commons.apache.org issues_bot_codecov-commenter: notifications@commons.apache.org pullrequests_bot_codecov-commenter: notifications@commons.apache.org From 9e511181a03096b77c3a4b9c6077a4ac0b56b510 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 2 Nov 2025 09:51:57 -0500 Subject: [PATCH 048/174] Use HTTPS in URL --- src/site/xdoc/description.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/site/xdoc/description.xml b/src/site/xdoc/description.xml index ac5ab0a77ed..94b7d1bf0ee 100644 --- a/src/site/xdoc/description.xml +++ b/src/site/xdoc/description.xml @@ -157,7 +157,7 @@ limitations under the License.

    For more information, see - http://www.cs.umass.edu/~verts/cs32/endian.html + https://www.cs.umass.edu/~verts/cs32/endian.html

    From 34a961c3ed58ed96c73836db154ae50f0c45110f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 2 Nov 2025 10:25:35 -0500 Subject: [PATCH 049/174] Use HTTPS in URL --- .../org/apache/commons/io/ByteOrderMark.java | 2 +- .../java/org/apache/commons/io/CopyUtils.java | 10 +++---- .../java/org/apache/commons/io/IOUtils.java | 28 +++++++++---------- .../ValidatingObjectInputStream.java | 2 +- src/site/xdoc/building.xml | 4 +-- src/site/xdoc/description.xml | 2 +- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/apache/commons/io/ByteOrderMark.java b/src/main/java/org/apache/commons/io/ByteOrderMark.java index 0067f7d2d6f..9624a0ba8b4 100644 --- a/src/main/java/org/apache/commons/io/ByteOrderMark.java +++ b/src/main/java/org/apache/commons/io/ByteOrderMark.java @@ -40,7 +40,7 @@ * * @see org.apache.commons.io.input.BOMInputStream * @see Wikipedia: Byte Order Mark - * @see W3C: Autodetection of Character Encodings + * @see W3C: Autodetection of Character Encodings * (Non-Normative) * @since 2.0 */ diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index b3243a30a4f..bb9ac470c75 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -46,7 +46,7 @@ * released when the associated Stream is garbage-collected. It is not a good * idea to rely on this mechanism. For a good overview of the distinction * between "memory management" and "resource management", see - * this + * this * UnixReview article. *

    * For byte-to-char methods, a {@code copy} variant allows the encoding @@ -148,7 +148,7 @@ public static void copy(final byte[] input, final Writer output) throws IOExcept * @param input the byte array to read from * @param output the {@link Writer} to write to * @param encoding The name of a supported character encoding. See the - * IANA + * IANA * Charset Registry for a list of valid encoding types. * @throws IOException In case of an I/O problem */ @@ -206,7 +206,7 @@ public static void copy( * @param input the {@link InputStream} to read from * @param output the {@link Writer} to write to * @param encoding The name of a supported character encoding. See the - * IANA + * IANA * Charset Registry for a list of valid encoding types. * @throws IOException In case of an I/O problem */ @@ -251,7 +251,7 @@ public static void copy( * @param input the {@link Reader} to read from * @param output the {@link OutputStream} to write to * @param encoding The name of a supported character encoding. See the - * IANA + * IANA * Charset Registry for a list of valid encoding types. * @throws IOException In case of an I/O problem * @since 2.5 @@ -327,7 +327,7 @@ public static void copy( * @param input the {@link String} to read from * @param output the {@link OutputStream} to write to * @param encoding The name of a supported character encoding. See the - * IANA + * IANA * Charset Registry for a list of valid encoding types. * @throws IOException In case of an I/O problem * @since 2.5 diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 5a005fa6792..09a018b036d 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1596,7 +1596,7 @@ public static void copy(final Reader reader, final OutputStream output, final Ch * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    *

    - * Character encoding names can be found at IANA. + * Character encoding names can be found at IANA. *

    *

    * Due to the implementation of OutputStreamWriter, this method performs a flush. @@ -2426,7 +2426,7 @@ public static List readLines(final InputStream input, final Charset char * one entry per line, using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method buffers the input internally, so there is no need to use a @@ -3080,7 +3080,7 @@ public static byte[] toByteArray(final Reader reader, final Charset charset) thr * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method buffers the input internally, so there is no need to use a @@ -3207,7 +3207,7 @@ public static char[] toCharArray(final InputStream inputStream, final Charset ch * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method buffers the input internally, so there is no need to use a @@ -3277,7 +3277,7 @@ public static InputStream toInputStream(final CharSequence input, final Charset * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    * * @param input the CharSequence to convert. @@ -3322,7 +3322,7 @@ public static InputStream toInputStream(final String input, final Charset charse * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    * * @param input the string to convert. @@ -3355,7 +3355,7 @@ public static String toString(final byte[] input) { * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    * * @param input the byte array to read. @@ -3413,7 +3413,7 @@ public static String toString(final InputStream input, final Charset charset) th * using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method buffers the input internally, so there is no need to use a @@ -3639,7 +3639,7 @@ public static void write(final byte[] data, final Writer writer, final Charset c /** * Writes bytes from a {@code byte[]} to chars on a {@link Writer} using the specified character encoding. *

    - * Character encoding names can be found at IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link String#String(byte[], String)}. @@ -3698,7 +3698,7 @@ public static void write(final char[] data, final OutputStream output, final Cha /** * Writes chars from a {@code char[]} to bytes on an {@link OutputStream} using the specified character encoding. *

    - * Character encoding names can be found at IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link String#String(char[])} and {@link String#getBytes(String)}. @@ -3775,7 +3775,7 @@ public static void write(final CharSequence data, final OutputStream output, fin /** * Writes chars from a {@link CharSequence} to bytes on an {@link OutputStream} using the specified character encoding. *

    - * Character encoding names can be found at IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link String#getBytes(String)}. @@ -3858,7 +3858,7 @@ public static void write(final String data, final OutputStream output, final Cha * {@link OutputStream} using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method uses {@link String#getBytes(String)}. @@ -3918,7 +3918,7 @@ public static void write(final StringBuffer data, final OutputStream output) //N * {@link OutputStream} using the specified character encoding. *

    * Character encoding names can be found at - * IANA. + * IANA. *

    *

    * This method uses {@link String#getBytes(String)}. @@ -4064,7 +4064,7 @@ public static void writeLines(final Collection lines, String lineEnding, fina * Writes the {@link #toString()} value of each item in a collection to an {@link OutputStream} line by line, using the specified character encoding and the * specified line ending. *

    - * Character encoding names can be found at IANA. + * Character encoding names can be found at IANA. *

    * * @param lines the lines to write, null entries produce blank lines. diff --git a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java index 6141cc59b1c..d2e51425b24 100644 --- a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java +++ b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java @@ -74,7 +74,7 @@ * } * } *

    - * Design inspired by a IBM DeveloperWorks Article. + * Design inspired by a IBM DeveloperWorks Article. *

    * * @since 2.5 diff --git a/src/site/xdoc/building.xml b/src/site/xdoc/building.xml index be5de6b1a1d..bef84849f24 100644 --- a/src/site/xdoc/building.xml +++ b/src/site/xdoc/building.xml @@ -25,7 +25,7 @@ limitations under the License.

    - Commons IO uses Maven its build system. + Commons IO uses Maven its build system.

    Commons IO requires a minimum of JDK 8 to build. @@ -46,7 +46,7 @@ limitations under the License.

    - The following Maven commands can be used to build io: + The following Maven commands can be used to build io:

    • mvn - runs the default Maven goal which performs all build checks
    • diff --git a/src/site/xdoc/description.xml b/src/site/xdoc/description.xml index 94b7d1bf0ee..230a43a8410 100644 --- a/src/site/xdoc/description.xml +++ b/src/site/xdoc/description.xml @@ -157,7 +157,7 @@ limitations under the License.

    For more information, see - https://www.cs.umass.edu/~verts/cs32/endian.html + https://www.cs.umass.edu/~verts/cs32/endian.html

    From 0f499d060adbd4b36bbd9f47393a7ea6af8149ff Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 2 Nov 2025 15:43:03 -0500 Subject: [PATCH 050/174] Use new oak logo --- .../org/apache/commons/io/doc-files/leaf.svg | 29 +++++++++++++++++ src/main/javadoc/overview.html | 32 ++++++++----------- src/site/resources/images/leaf.svg | 29 +++++++++++++++++ src/site/xdoc/index.xml | 2 +- 4 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 src/main/java/org/apache/commons/io/doc-files/leaf.svg create mode 100644 src/site/resources/images/leaf.svg diff --git a/src/main/java/org/apache/commons/io/doc-files/leaf.svg b/src/main/java/org/apache/commons/io/doc-files/leaf.svg new file mode 100644 index 00000000000..261459fafa6 --- /dev/null +++ b/src/main/java/org/apache/commons/io/doc-files/leaf.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index 0ffd28dace2..a2204feeade 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -17,24 +17,18 @@ --> -Apache Commons IO -

    Apache Commons IO

    -

    Introduction

    -

    -The Apache Commons IO component contains utility classes, -filters, streams, readers and writers. -

    -

    -These classes aim to add to the standard JDK IO classes. -The utilities provide convenience wrappers around the JDK, simplifying -various operations into pre-tested units of code. -The filters and streams provide useful implementations that perhaps should -be in the JDK itself. -

    -

    Requirements

    -
      -
    • Java 8 or above.
    • -
    • If using OSGi, R7 or above.
    • -
    + Apache Commons IO + +

    + leafIntroduction +

    +

    Apache Commons IO is a library of utilities to assist with developing IO functionality as the package list below describes.

    +

    + leafRequirements +

    +
      +
    • Java 8 or above.
    • +
    • If using OSGi, R7 or above.
    • +
    diff --git a/src/site/resources/images/leaf.svg b/src/site/resources/images/leaf.svg new file mode 100644 index 00000000000..261459fafa6 --- /dev/null +++ b/src/site/resources/images/leaf.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index 54022e401ae..403c225db03 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -28,7 +28,7 @@ limitations under the License. Apache Commons IO is a library of utilities to assist with developing IO functionality.

    - Main areas include: + The Commons IO packages include:

    • From adcf1350152faf4dbd8cf53fb2f2649f25dbe227 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 2 Nov 2025 16:42:34 -0500 Subject: [PATCH 051/174] Add license header --- .../org/apache/commons/io/doc-files/leaf.svg | 16 ++++++++++++++++ src/site/resources/images/leaf.svg | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/org/apache/commons/io/doc-files/leaf.svg b/src/main/java/org/apache/commons/io/doc-files/leaf.svg index 261459fafa6..71de588c648 100644 --- a/src/main/java/org/apache/commons/io/doc-files/leaf.svg +++ b/src/main/java/org/apache/commons/io/doc-files/leaf.svg @@ -1,4 +1,20 @@ + - + When testing on Java 21 and up, enable -XX:+EnableDynamicAgentLoading. When testing on Java 24 and up, don't fail FileUtilsListFilesTest for a different behavior in the JRE. diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 567d2653265..6a0ba144cd9 100644 --- a/src/site/xdoc/download_io.xml +++ b/src/site/xdoc/download_io.xml @@ -115,32 +115,32 @@ limitations under the License.

    -
    +
    - - - + + + - - - + + +
    commons-io-2.20.0-bin.tar.gzsha512pgpcommons-io-2.21.0-bin.tar.gzsha512pgp
    commons-io-2.20.0-bin.zipsha512pgpcommons-io-2.21.0-bin.zipsha512pgp
    - - - + + + - - - + + +
    commons-io-2.20.0-src.tar.gzsha512pgpcommons-io-2.21.0-src.tar.gzsha512pgp
    commons-io-2.20.0-src.zipsha512pgpcommons-io-2.21.0-src.zipsha512pgp
    From 54073d3b5fdd2985b98a48040ede95eb59c7ee53 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 4 Nov 2025 20:23:47 +0000 Subject: [PATCH 053/174] Prepare for the release candidate 2.21.0 RC1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f60efbc76db..59e438881c2 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 4.0.0 commons-io commons-io - 2.21.0-SNAPSHOT + 2.21.0 Apache Commons IO 2002 @@ -119,7 +119,7 @@ file comparators, endian transformation classes, and much more. 2.21.0 2.21.1 - 2025-07-18T21:12:04Z + 2025-11-04T20:17:29Z (requires Java 8) IO 12310477 From 764a439dedc5d77a6693cf19667a4e86be27b2bf Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 5 Nov 2025 07:09:30 -0500 Subject: [PATCH 054/174] Upgrade from deprecated macos-13 to macos-latest in GitHub CI --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index ee6b9c99a12..77997ee2faf 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -38,7 +38,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-13] + os: [ubuntu-latest, windows-latest, macos-latest] java: [ 8, 11, 17, 21, 25 ] experimental: [false] # Keep the same parameter order as the matrix above @@ -72,7 +72,7 @@ jobs: - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - distribution: 'temurin' + distribution: ${{ runner.os == 'macOS' && matrix.java == '8' && 'zulu' || 'temurin' }} java-version: ${{ matrix.java }} # these values cause the plugin to set up the Maven settings.xml file server-id: apache.snapshots.https # Value of the distributionManagement/repository/id field of the pom.xml From 7c357c162f48dc1f906332f9c98ff9ecb0ce4119 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 5 Nov 2025 07:40:16 -0500 Subject: [PATCH 055/174] Typo --- src/main/javadoc/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index a2204feeade..e592a25591e 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -24,7 +24,7 @@

    Apache Commons IO is a library of utilities to assist with developing IO functionality as the package list below describes.

    - leafRequirements + leafRequirements

    • Java 8 or above.
    • From ae5e7be386644ff4d31917da6452c283f9c3ac74 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 6 Nov 2025 16:43:22 -0500 Subject: [PATCH 056/174] Fix typos --- src/main/javadoc/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html index e592a25591e..7de36f6ede9 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -20,7 +20,7 @@ Apache Commons IO

      - leafIntroduction + leafIntroduction

      Apache Commons IO is a library of utilities to assist with developing IO functionality as the package list below describes.

      From e6ef23e6325061f732e8261c4b08fa63bed97a48 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 6 Nov 2025 21:58:24 +0000 Subject: [PATCH 057/174] Bump to next development version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 59e438881c2..c23957da7d3 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 4.0.0 commons-io commons-io - 2.21.0 + 2.21.1-SNAPSHOT Apache Commons IO 2002 @@ -119,7 +119,7 @@ file comparators, endian transformation classes, and much more. 2.21.0 2.21.1 - 2025-11-04T20:17:29Z + 2025-11-06T21:58:17Z (requires Java 8) IO 12310477 From f107caf609366f1033ac9812628f69aeefb73d05 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 6 Nov 2025 21:59:13 +0000 Subject: [PATCH 058/174] Updates for the next release --- src/changes/changes.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 23a7d3b40d6..dc1d3370d9b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,6 +45,11 @@ The type attribute can be add,update,fix,remove. Apache Commons IO Release Notes + + + + + When testing on Java 21 and up, enable -XX:+EnableDynamicAgentLoading. From 0071af06884917f81974b53d5d9718406b70b25a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 7 Nov 2025 20:10:14 +0000 Subject: [PATCH 059/174] Updates for the next release --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c23957da7d3..a6b7621fff4 100644 --- a/pom.xml +++ b/pom.xml @@ -115,9 +115,9 @@ file comparators, endian transformation classes, and much more. io org.apache.commons.io RC1 - 2.20.0 - 2.21.0 - 2.21.1 + 2.21.0 + 2.21.1 + 2.21.2 2025-11-06T21:58:17Z (requires Java 8) From 3f6d4ff1300b8b94f63e0322dd8a966ad30c7d28 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 7 Nov 2025 15:16:54 -0500 Subject: [PATCH 060/174] Typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f708680735d..71936d344fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ Making Changes + Respect the original code style: + Only use spaces for indentation; you can check for unnecessary whitespace with `git diff` before committing. + Create minimal diffs - disable _On Save_ actions like _Reformat Source Code_ or _Organize Imports_. If you feel the source code should be reformatted create a separate PR for this change first. -+ Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible but is a best-practice. ++ Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible but is a best practice. Unit tests are typically in the `src/test/java` directory. + Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself. + Write a pull request description that is detailed enough to understand what the pull request does, how, and why. From ccc02e73813fc6d25ef83ffccfdab00dd207cf2f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 7 Nov 2025 22:05:08 -0500 Subject: [PATCH 061/174] Javadoc Use emphasis instead of italics --- src/main/java/org/apache/commons/io/input/QueueInputStream.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/input/QueueInputStream.java b/src/main/java/org/apache/commons/io/input/QueueInputStream.java index 5f701945cb3..d672d23fa2b 100644 --- a/src/main/java/org/apache/commons/io/input/QueueInputStream.java +++ b/src/main/java/org/apache/commons/io/input/QueueInputStream.java @@ -229,7 +229,7 @@ public int read() { /** * Reads up to {@code length} bytes of data from the input stream into - * an array of bytes. The first byte is read while honoring the timeout; the rest are read while not honoring + * an array of bytes. The first byte is read while honoring the timeout; the rest are read while not honoring * the timeout. The number of bytes actually read is returned as an integer. * * @param b the buffer into which the data is read. From f07af41b6473660bc489d9d299b708ed621cf04f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 8 Nov 2025 11:21:43 -0500 Subject: [PATCH 062/174] No need to override project/issueManagement/system --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index a6b7621fff4..a64102d167c 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,6 @@ file comparators, endian transformation classes, and much more. https://commons.apache.org/proper/commons-io/ - jira https://issues.apache.org/jira/browse/IO From 3c659ecd0b8be87d8e60d437da1c08d7a170da1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 06:11:21 -0500 Subject: [PATCH 063/174] Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 (#812) Bumps [commons-codec:commons-codec](https://github.com/apache/commons-codec) from 1.19.0 to 1.20.0. - [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.19.0...rel/commons-codec-1.20.0) --- updated-dependencies: - dependency-name: commons-codec:commons-codec dependency-version: 1.20.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a64102d167c..4412e13dfa0 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ file comparators, endian transformation classes, and much more. commons-codec commons-codec - 1.19.0 + 1.20.0 test From 524ab6dd60b0b5f553352b1d58dce846c9a7c971 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 10 Nov 2025 06:12:00 -0500 Subject: [PATCH 064/174] Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index dc1d3370d9b..89fafc47369 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The type attribute can be add,update,fix,remove. + Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. From baf2c57bfebaf71e356ff1c71a7e32a737bc4c3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:47:13 -0500 Subject: [PATCH 065/174] Bump github/codeql-action from 4.31.2 to 4.31.3 (#815) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.2 to 4.31.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0499de31b99561a6d14a36a5f662c2a54f91beee...014f16e7ab1402f30e7c3329d33797e7948572db) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.31.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 276e14f41de..5525f89ae53 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 + uses: github/codeql-action/init@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 + uses: github/codeql-action/autobuild@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 + uses: github/codeql-action/analyze@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 3215897f03b..b76ddb09f6f 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # 3.29.5 + uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 with: sarif_file: results.sarif From 60f411cbff62725c484d1ab6b4ded5cc9298431b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:54:00 -0500 Subject: [PATCH 066/174] Bump actions/dependency-review-action from 4.8.1 to 4.8.2 (#813) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4.8.1 to 4.8.2. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/40c09b7dc99638e5ddb0bfd91c1673effc064d8a...3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-version: 4.8.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index a657a4ae2cd..11834ed9d1e 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -28,4 +28,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: 'Dependency Review PR' - uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1 + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 From 6c44e829ff0a10726b8f3b0fb04026f895e2e395 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 08:25:04 -0500 Subject: [PATCH 067/174] Bump org.apache.commons:commons-parent from 91 to 92 (#816) Bumps [org.apache.commons:commons-parent](https://github.com/apache/commons-parent) from 91 to 92. - [Changelog](https://github.com/apache/commons-parent/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-parent/commits) --- updated-dependencies: - dependency-name: org.apache.commons:commons-parent dependency-version: '92' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4412e13dfa0..f61cb690a62 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 91 + 92 4.0.0 commons-io From 6a003a616cdc99b2111b13b36208bf5809eac57e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 14 Nov 2025 08:25:35 -0500 Subject: [PATCH 068/174] Bump org.apache.commons:commons-parent from 91 to 92 #816 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 89fafc47369..fa54c2254f3 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The type attribute can be add,update,fix,remove. + Bump org.apache.commons:commons-parent from 91 to 92 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. From adf79ee11a9cb8ddb14fcf67e1b21f6a0e652248 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 08:25:55 -0500 Subject: [PATCH 069/174] Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 (#814) Bumps `commons.bytebuddy.version` from 1.17.8 to 1.18.1. Updates `net.bytebuddy:byte-buddy` from 1.17.8 to 1.18.1 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.8...byte-buddy-1.18.1) Updates `net.bytebuddy:byte-buddy-agent` from 1.17.8 to 1.18.1 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.17.8...byte-buddy-1.18.1) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.1 dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f61cb690a62..e1678777807 100644 --- a/pom.xml +++ b/pom.xml @@ -145,7 +145,7 @@ file comparators, endian transformation classes, and much more. https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ site-content - 1.17.8 + 1.18.1 false true From 2227467038e8b1c44ed9b474136e60ad15d609c9 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 14 Nov 2025 08:26:26 -0500 Subject: [PATCH 070/174] Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 #814 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index fa54c2254f3..80985b3cd82 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -51,6 +51,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 91 to 92 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. + Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 #814. From 0e5b109650c0fca710ccaa5bd2c9371f8768abfc Mon Sep 17 00:00:00 2001 From: Sebb Date: Sat, 15 Nov 2025 17:45:47 +0000 Subject: [PATCH 071/174] Dependabot => quarterly --- .github/dependabot.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 00079caf1bc..90ec55f742e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,10 +18,8 @@ updates: - package-ecosystem: "maven" directory: "/" schedule: - interval: "weekly" - day: "friday" + interval: "quarterly" - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" - day: "friday" + interval: "quarterly" From 7aeb468d30704cf3a59da8fd0a4a2b62e0bdfb21 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 16 Nov 2025 09:18:23 -0500 Subject: [PATCH 072/174] Bump commons-lang3 from 3.19.0 to 3.20.0 --- pom.xml | 2 +- src/changes/changes.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e1678777807..0564612c87a 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ file comparators, endian transformation classes, and much more. org.apache.commons commons-lang3 - 3.19.0 + 3.20.0 test diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 80985b3cd82..660d3d4ea08 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -52,6 +52,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 91 to 92 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 #814. + Bump commons-lang3 from 3.19.0 to 3.20.0. From 2758094c62ab8cdf806bf68d1c8e8c210806604a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 21 Nov 2025 14:24:08 +0000 Subject: [PATCH 073/174] Use HTTPS to download XML Schema --- src/site/xdoc/download_io.xml | 2 +- src/site/xdoc/issue-tracking.xml | 2 +- src/site/xdoc/mail-lists.xml | 2 +- src/site/xdoc/security.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 6a0ba144cd9..6ca018e32ca 100644 --- a/src/site/xdoc/download_io.xml +++ b/src/site/xdoc/download_io.xml @@ -58,7 +58,7 @@ limitations under the License. --> + xsi:schemaLocation="https://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Download Apache Commons IO Apache Commons Team diff --git a/src/site/xdoc/issue-tracking.xml b/src/site/xdoc/issue-tracking.xml index 3cda13d50c6..714f68c3e1b 100644 --- a/src/site/xdoc/issue-tracking.xml +++ b/src/site/xdoc/issue-tracking.xml @@ -43,7 +43,7 @@ limitations under the License. --> + xsi:schemaLocation="https://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons IO Issue tracking Apache Commons Team diff --git a/src/site/xdoc/mail-lists.xml b/src/site/xdoc/mail-lists.xml index bfb01dd0539..97815e3d51d 100644 --- a/src/site/xdoc/mail-lists.xml +++ b/src/site/xdoc/mail-lists.xml @@ -41,7 +41,7 @@ limitations under the License. --> + xsi:schemaLocation="https://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons IO Mailing Lists Apache Commons Team diff --git a/src/site/xdoc/security.xml b/src/site/xdoc/security.xml index 90e0d19e87b..6999a217027 100644 --- a/src/site/xdoc/security.xml +++ b/src/site/xdoc/security.xml @@ -5,7 +5,7 @@ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> + xsi:schemaLocation="https://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons Security Reports Apache Commons Team From ffc72994dd9eb20b9065746dba68f38b30130042 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 21 Nov 2025 14:41:47 +0000 Subject: [PATCH 074/174] Bump CodeQL 4.31.4 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5525f89ae53..e7ee12a9b84 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 + uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 + uses: github/codeql-action/autobuild@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 + uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index b76ddb09f6f..3bd4258db20 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@014f16e7ab1402f30e7c3329d33797e7948572db # 3.29.5 + uses: github/codeql-action/upload-sarif@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 with: sarif_file: results.sarif From a47e410203492a1e6725d3541c3ecb8f92bc8b93 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 21 Nov 2025 19:44:30 +0000 Subject: [PATCH 075/174] Bump actions/checkout from v5.0.0 to v6.0.0 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/maven.yml | 2 +- .github/workflows/scorecards-analysis.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e7ee12a9b84..ccd06a9cb94 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,7 +50,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 11834ed9d1e..b58ce930163 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -26,6 +26,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - name: 'Dependency Review PR' uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 77997ee2faf..70c9e12b3a9 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -60,7 +60,7 @@ jobs: experimental: true fail-fast: false steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 3bd4258db20..fa9439512e2 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -42,7 +42,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: persist-credentials: false From e9aeb4c4b43eca6033f8e1b394737a9d198a09d6 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 22 Nov 2025 08:49:16 -0500 Subject: [PATCH 076/174] Bump org.apache.commons:commons-parent from 92 to 93 - Inherit scm element - Inherit ciManagement element - Inherit issueManagement element --- pom.xml | 15 +-------------- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 0564612c87a..b0da515511d 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 92 + 93 4.0.0 commons-io @@ -32,9 +32,6 @@ The Apache Commons IO library contains utility classes, stream implementations, file comparators, endian transformation classes, and much more. https://commons.apache.org/proper/commons-io/ - - https://issues.apache.org/jira/browse/IO - apache.website @@ -42,16 +39,6 @@ file comparators, endian transformation classes, and much more. scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ - - scm:git:https://gitbox.apache.org/repos/asf/commons-io.git - scm:git:https://gitbox.apache.org/repos/asf/commons-io.git - https://gitbox.apache.org/repos/asf?p=commons-io.git - rel/commons-io-2.21.0 - - - GitHub - https://github.com/apache/commons-io/actions - org.junit.jupiter diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 660d3d4ea08..78f66f43fb4 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,7 +49,7 @@ The type attribute can be add,update,fix,remove. - Bump org.apache.commons:commons-parent from 91 to 92 #816. + Bump org.apache.commons:commons-parent from 91 to 93 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 #814. Bump commons-lang3 from 3.19.0 to 3.20.0. From dcdbdf33b2880156d4ca9b2f034b8de19df9ecac Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 23 Nov 2025 09:16:03 -0500 Subject: [PATCH 077/174] Fix Apache RAT plugin console warnings --- pom.xml | 10 +++++----- src/changes/changes.xml | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index b0da515511d..7c09d7e3c54 100644 --- a/pom.xml +++ b/pom.xml @@ -156,11 +156,11 @@ file comparators, endian transformation classes, and much more. org.apache.rat apache-rat-plugin - - src/test/resources/**/*.bin - src/test/resources/dir-equals-tests/** - test/** - + + src/test/resources/**/*.bin + src/test/resources/dir-equals-tests/** + test/** + diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 78f66f43fb4..153d0c6f4ee 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -47,6 +47,7 @@ The type attribute can be add,update,fix,remove. + Fix Apache RAT plugin console warnings. Bump org.apache.commons:commons-parent from 91 to 93 #816. From 7001cee43f800c02b4409cb59d2c26d7b55cc9f6 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 28 Nov 2025 14:55:40 +0000 Subject: [PATCH 078/174] Javadoc --- src/main/java/org/apache/commons/io/file/PathUtils.java | 2 +- .../java/org/apache/commons/io/file/StandardDeleteOption.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java index 055bbe06a0b..bafcf86ca81 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -1412,7 +1412,7 @@ private static boolean notExists(final Path path, final LinkOption... options) { /** * Returns true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}. * - * @param deleteOptions the array to test + * @param deleteOptions the array to test. * @return true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}. */ private static boolean overrideReadOnly(final DeleteOption... deleteOptions) { diff --git a/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java b/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java index e66dff6473e..b4cc6cb1d5e 100644 --- a/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java +++ b/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java @@ -38,7 +38,7 @@ public enum StandardDeleteOption implements DeleteOption { * * For now, assume the array is not sorted. * - * @param options the array to test + * @param options the array to test. * @return true if the given options contain {@link StandardDeleteOption#OVERRIDE_READ_ONLY}. */ public static boolean overrideReadOnly(final DeleteOption[] options) { From 903b4d414b8985faaf4e4037075f47cde5cc48e4 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 28 Nov 2025 21:29:13 +0000 Subject: [PATCH 079/174] Bump github/codeql-action from 4.31.4 to 4.31.5 --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ccd06a9cb94..9579e8edb01 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 + uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. From 6678f81ae4f7be0f2b74a42c923eee135c65d712 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 28 Nov 2025 21:43:09 +0000 Subject: [PATCH 080/174] Bump github/codeql-action from 4.31.4 to 4.31.5 --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9579e8edb01..22c098c62a8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 + uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 + uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index fa9439512e2..80db73ab299 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # 4.31.4 + uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 with: sarif_file: results.sarif From 4e6c051a0cf9490437a98f04c2dff5a2109b464a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 1 Dec 2025 09:57:41 -0500 Subject: [PATCH 081/174] Bump github/codeql-action from 4.31.5 to 4.31.6 --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 22c098c62a8..ebe1b727389 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 + uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 + uses: github/codeql-action/autobuild@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 + uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 From 313950c10e4ca997d0e29fb697af2aa4d82a663f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 1 Dec 2025 16:12:29 -0500 Subject: [PATCH 082/174] Bump github/codeql-action from 4.31.5 to 4.31.6 --- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 80db73ab299..d2534be3e75 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # 4.31.5 + uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 with: sarif_file: results.sarif From 62d7cbe88f283a6f153a00814a22727d870532d8 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 3 Dec 2025 06:18:37 -0500 Subject: [PATCH 083/174] Bump commons.bytebuddy.version from 1.18.1 to 1.18.2 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7c09d7e3c54..b297ce09ae9 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ file comparators, endian transformation classes, and much more. https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ site-content - 1.18.1 + 1.18.2 false true diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 153d0c6f4ee..49ec68e14ce 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -52,7 +52,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 91 to 93 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. - Bump commons.bytebuddy.version from 1.17.8 to 1.18.1 #814. + Bump commons.bytebuddy.version from 1.17.8 to 1.18.2 #814. Bump commons-lang3 from 3.19.0 to 3.20.0. From 0309fe36b77c4fd309c6e3e3ec2848224d6fa89e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 3 Dec 2025 16:05:39 -0500 Subject: [PATCH 084/174] Bump actions/checkout from 6.0.0 to 6.0.1 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/maven.yml | 2 +- .github/workflows/scorecards-analysis.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ebe1b727389..7210b467d09 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,7 +50,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index b58ce930163..1df86660448 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -26,6 +26,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: 'Dependency Review PR' uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 70c9e12b3a9..c3105291518 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -60,7 +60,7 @@ jobs: experimental: true fail-fast: false steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index d2534be3e75..517413f4637 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -42,7 +42,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false From 05e49560b95bad6b1616675316b72494b08ea605 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 4 Dec 2025 07:41:09 -0500 Subject: [PATCH 085/174] Bump actions/setup-java from 5.0.0 to 5.1.0 --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index c3105291518..2b245e642d5 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -70,7 +70,7 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 with: distribution: ${{ runner.os == 'macOS' && matrix.java == '8' && 'zulu' || 'temurin' }} java-version: ${{ matrix.java }} From a6652024d2d3ee4efd32c96ba9ba862bbe28a1ea Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 5 Dec 2025 08:03:43 -0500 Subject: [PATCH 086/174] Fix benchmarks --- .../io/jmh/IOUtilsContentEqualsInputStreamsBenchmark.java | 8 ++++---- .../io/jmh/IOUtilsContentEqualsReadersBenchmark.java | 6 +++--- .../commons/io/jmh/PathUtilsContentEqualsBenchmark.java | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsInputStreamsBenchmark.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsInputStreamsBenchmark.java index 028f55a9fc5..68009ab3b8c 100644 --- a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsInputStreamsBenchmark.java +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsInputStreamsBenchmark.java @@ -234,7 +234,7 @@ public boolean[] testFileRelease_2_8_0() throws IOException { } @Benchmark - void testStringCurrent(final Blackhole blackhole) throws IOException { + public void testStringCurrent(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (InputStream inputReader1 = IOUtils.toInputStream(STRINGS[i], DEFAULT_CHARSET); @@ -246,7 +246,7 @@ void testStringCurrent(final Blackhole blackhole) throws IOException { } @Benchmark - void testStringFileChannels(final Blackhole blackhole) throws IOException { + public void testStringFileChannels(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (InputStream input1 = IOUtils.toInputStream(STRINGS[i], DEFAULT_CHARSET); @@ -258,7 +258,7 @@ void testStringFileChannels(final Blackhole blackhole) throws IOException { } @Benchmark - void testStringPr118(final Blackhole blackhole) throws IOException { + public void testStringPr118(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (InputStream input1 = IOUtils.toInputStream(STRINGS[i], DEFAULT_CHARSET); @@ -270,7 +270,7 @@ void testStringPr118(final Blackhole blackhole) throws IOException { } @Benchmark - void testStringRelease_2_8_0(final Blackhole blackhole) throws IOException { + public void testStringRelease_2_8_0(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (InputStream input1 = IOUtils.toInputStream(STRINGS[i], DEFAULT_CHARSET); diff --git a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java index d7282d8ea98..394989d4f72 100644 --- a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java @@ -203,7 +203,7 @@ public boolean[] testFileRelease_2_8_0() throws IOException { } @Benchmark - void testStringCurrent(final Blackhole blackhole) throws IOException { + public void testStringCurrent(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (StringReader input1 = new StringReader(STRINGS[i]); @@ -215,7 +215,7 @@ void testStringCurrent(final Blackhole blackhole) throws IOException { } @Benchmark - void testStringPr118(final Blackhole blackhole) throws IOException { + public void testStringPr118(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (StringReader input1 = new StringReader(STRINGS[i]); @@ -227,7 +227,7 @@ void testStringPr118(final Blackhole blackhole) throws IOException { } @Benchmark - void testStringRelease_2_8_0(final Blackhole blackhole) throws IOException { + public void testStringRelease_2_8_0(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { try (StringReader input1 = new StringReader(STRINGS[i]); diff --git a/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java b/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java index 2fd9688cc83..92913525641 100644 --- a/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java +++ b/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java @@ -92,7 +92,7 @@ public boolean[] testCurrent_fileContentEquals() throws IOException { } @Benchmark - void testCurrent_fileContentEquals_Blackhole(final Blackhole blackhole) throws IOException { + public void testCurrent_fileContentEquals_Blackhole(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { blackhole.consume(PathUtils.fileContentEquals(bigFile1, bigFile2)); @@ -108,7 +108,7 @@ public boolean[] testProposal_contentEquals() throws IOException { } @Benchmark - void testProposal_contentEquals_Blackhole(final Blackhole blackhole) throws IOException { + public void testProposal_contentEquals_Blackhole(final Blackhole blackhole) throws IOException { for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { blackhole.consume(newFileContentEquals(bigFile1, bigFile2)); From d2e39b6453de8b030a701bd5bbdbb02fe839abe9 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 5 Dec 2025 10:13:44 -0500 Subject: [PATCH 087/174] Javadoc --- src/main/java/org/apache/commons/io/function/IOIterable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/function/IOIterable.java b/src/main/java/org/apache/commons/io/function/IOIterable.java index 238040d1d65..bfaccc103b2 100644 --- a/src/main/java/org/apache/commons/io/function/IOIterable.java +++ b/src/main/java/org/apache/commons/io/function/IOIterable.java @@ -44,8 +44,8 @@ default Iterable asIterable() { * Like {@link Iterable#iterator()}. * * @param action The action to be performed for each element. - * @throws NullPointerException if the specified action is null. - * @throws IOException thrown by the given action. + * @throws NullPointerException Thrown if the specified action is null. + * @throws IOException Thrown if an I/O error occurs for a remaining element, or the given action throws. * @see Iterable#iterator() */ default void forEach(final IOConsumer action) throws IOException { From 013aae21a9ee35f903ab13bb350cc2e15ef01f28 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 5 Dec 2025 15:06:18 -0500 Subject: [PATCH 088/174] Bump github/codeql-action from 4.31.6 to 4.31.7 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 7210b467d09..adb989633ea 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 517413f4637..37ad379e71b 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@fe4161a26a8629af62121b670040955b330f9af2 # v4.31.6 + uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 with: sarif_file: results.sarif From d0af7d561bf6da3261fafbb6154c50ead2d32326 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 5 Dec 2025 17:02:58 -0500 Subject: [PATCH 089/174] Ask for details on AI usage in creating a pull request --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4cbe168c3e8..9ff35c83e79 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -23,7 +23,7 @@ Before you push a pull request, review this list: - [ ] Read the [contribution guidelines](CONTRIBUTING.md) for this project. - [ ] Read the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) if you use Artificial Intelligence (AI). -- [ ] I used AI to create any part of, or all of, this pull request. +- [ ] I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute? - [ ] Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself. - [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice. - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. From 3557766ab48bb876008b0a2cb9bd1933275a306a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 6 Dec 2025 11:39:55 -0500 Subject: [PATCH 090/174] Add NetBean IDE metadata files to .gitignore --- .gitignore | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f43fea02686..91824e5be73 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -### https://raw.github.com/github/gitignore/14b7566ce157ce95b07006466bacee160f242284/maven.gitignore - target/ pom.xml.tag pom.xml.releaseBackup @@ -7,16 +5,19 @@ pom.xml.versionsBackup pom.xml.next release.properties - site-content /.classpath /.project /.settings/ -### Ignore IntelliJ files +# Ignore IntelliJ files /.idea/ *.iml /bin/ -### Ignore Visual Studio code files +# Ignore Visual Studio code files /.vscode/ + +# NetBeans files +nb-configuration.xml +nbactions.xml From 208887b4e351a3e2ef3cec77238b0677136fb051 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 8 Dec 2025 16:57:19 -0500 Subject: [PATCH 091/174] ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large (#817) * [IO-856] Try test on all OSs for GitHub CI * ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large * Throw IOException instead of OutOfMemoryError * Refactor internals for safer and less type casting --- .../ByteArraySeekableByteChannel.java | 59 +++++++++++-------- .../AbstractSeekableByteChannelTest.java | 30 +++++++++- ...eArraySeekableByteChannelCompressTest.java | 31 ++++++++-- .../ByteArraySeekableByteChannelTest.java | 16 +++++ 4 files changed, 106 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java index 4135a815e83..2cd8009203f 100644 --- a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java +++ b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java @@ -68,7 +68,7 @@ public static ByteArraySeekableByteChannel wrap(final byte[] bytes) { private byte[] data; private volatile boolean closed; - private int position; + private long position; private int size; private final ReentrantLock lock = new ReentrantLock(); @@ -126,11 +126,10 @@ private void checkOpen() throws ClosedChannelException { } } - private int checkRange(final long newSize, final String method) { - if (newSize < 0L || newSize > IOUtils.SOFT_MAX_ARRAY_LENGTH) { - throw new IllegalArgumentException(String.format("%s must be in range [0..%,d]: %,d", method, IOUtils.SOFT_MAX_ARRAY_LENGTH, newSize)); + private void checkRange(final long newSize, final String method) { + if (newSize < 0L) { + throw new IllegalArgumentException(String.format("%s must be positive: %,d", method, newSize)); } - return (int) newSize; } @Override @@ -166,10 +165,10 @@ public long position() throws ClosedChannelException { @Override public SeekableByteChannel position(final long newPosition) throws IOException { checkOpen(); - final int intPos = checkRange(newPosition, "position()"); + checkRange(newPosition, "position()"); lock.lock(); try { - position = intPos; + position = newPosition; } finally { lock.unlock(); } @@ -181,15 +180,18 @@ public int read(final ByteBuffer buf) throws IOException { checkOpen(); lock.lock(); try { + if (position > Integer.MAX_VALUE) { + return IOUtils.EOF; + } int wanted = buf.remaining(); - final int possible = size - position; + final int possible = size - (int) position; if (possible <= 0) { return IOUtils.EOF; } if (wanted > possible) { wanted = possible; } - buf.put(data, position, wanted); + buf.put(data, (int) position, wanted); position += wanted; return wanted; } finally { @@ -238,14 +240,14 @@ public byte[] toByteArray() { @Override public SeekableByteChannel truncate(final long newSize) throws ClosedChannelException { checkOpen(); - final int intSize = checkRange(newSize, "truncate()"); + checkRange(newSize, "truncate()"); lock.lock(); try { - if (size > intSize) { - size = intSize; + if (size > newSize) { + size = (int) newSize; } - if (position > intSize) { - position = intSize; + if (position > newSize) { + position = newSize; } } finally { lock.unlock(); @@ -256,21 +258,28 @@ public SeekableByteChannel truncate(final long newSize) throws ClosedChannelExce @Override public int write(final ByteBuffer b) throws IOException { checkOpen(); + if (position > Integer.MAX_VALUE) { + throw new IOException("position > Integer.MAX_VALUE"); + } lock.lock(); try { final int wanted = b.remaining(); - final int possibleWithoutResize = Math.max(0, size - position); - if (wanted > possibleWithoutResize) { - final int newSize = position + wanted; - if (newSize < 0 || newSize > IOUtils.SOFT_MAX_ARRAY_LENGTH) { // overflow - throw new OutOfMemoryError("required array size " + Integer.toUnsignedString(newSize) + " too large"); - } - resize(newSize); + // intPos <= Integer.MAX_VALUE + final int intPos = (int) position; + final long newPosition = position + wanted; + if (newPosition > IOUtils.SOFT_MAX_ARRAY_LENGTH) { + throw new IOException(String.format("Requested array size %,d is too large.", newPosition)); } - b.get(data, position, wanted); - position += wanted; - if (size < position) { - size = position; + if (newPosition > size) { + final int newPositionInt = (int) newPosition; + // Ensure that newPositionInt ≤ data.length + resize(newPositionInt); + size = newPositionInt; + } + b.get(data, intPos, wanted); + position = newPosition; + if (size < intPos) { + size = intPos; } return wanted; } finally { diff --git a/src/test/java/org/apache/commons/io/channels/AbstractSeekableByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/AbstractSeekableByteChannelTest.java index abf96d8f47d..afb2245a49f 100644 --- a/src/test/java/org/apache/commons/io/channels/AbstractSeekableByteChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/AbstractSeekableByteChannelTest.java @@ -47,7 +47,7 @@ */ abstract class AbstractSeekableByteChannelTest { - private SeekableByteChannel channel; + protected SeekableByteChannel channel; @TempDir protected Path tempDir; @@ -87,6 +87,7 @@ void testCloseMultipleTimes() throws IOException { assertFalse(channel.isOpen()); } + @Test void testConcurrentPositionAndSizeQueries() throws IOException { final byte[] data = "test data".getBytes(); @@ -136,6 +137,20 @@ void testPositionBeyondSize() throws IOException { assertEquals(4, channel.size()); // Size should not change } + @Test + void testPositionBeyondSizeRead() throws IOException { + final ByteBuffer buffer = ByteBuffer.allocate(1); + channel.position(channel.size() + 1); + assertEquals(channel.size() + 1, channel.position()); + assertEquals(-1, channel.read(buffer)); + channel.position(Integer.MAX_VALUE + 1L); + assertEquals(Integer.MAX_VALUE + 1L, channel.position()); + assertEquals(-1, channel.read(buffer)); + assertThrows(IllegalArgumentException.class, () -> channel.position(-1)); + assertThrows(IllegalArgumentException.class, () -> channel.position(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> channel.position(Long.MIN_VALUE)); + } + @ParameterizedTest @CsvSource({ "0, 0", "5, 5", "10, 10", "100, 100" }) void testPositionInBounds(final long newPosition, final long expectedPosition) throws IOException { @@ -149,6 +164,7 @@ void testPositionInBounds(final long newPosition, final long expectedPosition) t assertEquals(expectedPosition, channel.position()); } + @Test void testPositionNegative() { assertThrows(IllegalArgumentException.class, () -> channel.position(-1)); @@ -292,6 +308,18 @@ void testSizeSameOnOverwrite() throws IOException { assertEquals(11, channel.size()); // Size should not change } + @Test + void testTrucateBeyondSizeReadWrite() throws IOException { + final ByteBuffer buffer = ByteBuffer.allocate(1); + channel.truncate(channel.size() + 1); + assertEquals(-1, channel.read(buffer)); + channel.truncate(Integer.MAX_VALUE + 1L); + assertEquals(-1, channel.read(buffer)); + assertThrows(IllegalArgumentException.class, () -> channel.truncate(-1)); + assertThrows(IllegalArgumentException.class, () -> channel.truncate(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> channel.truncate(Long.MIN_VALUE)); + } + @Test void testTruncateNegative() { assertThrows(IllegalArgumentException.class, () -> channel.truncate(-1)); diff --git a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java index 66c8e60b91a..60c294f0d65 100644 --- a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java +++ b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java @@ -162,16 +162,39 @@ void testShouldThrowExceptionOnWritingToClosedChannel() { } @Test - void testShouldThrowExceptionWhenSettingIncorrectPosition() { + void testThrowWhenSettingIncorrectPosition() throws IOException { try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MAX_VALUE + 1L)); + final ByteBuffer buffer = ByteBuffer.allocate(1); + // write + c.write(buffer); + assertEquals(1, c.position()); + // bad pos A + c.position(c.size() + 1); + assertEquals(c.size() + 1, c.position()); + assertEquals(-1, c.read(buffer)); + // bad pos B + c.position(Integer.MAX_VALUE + 1L); + assertEquals(Integer.MAX_VALUE + 1L, c.position()); + assertEquals(-1, c.read(buffer)); + assertThrows(IOException.class, () -> c.write(buffer)); + // negative input is the only illegal input + assertThrows(IllegalArgumentException.class, () -> c.position(-1)); + assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> c.position(Long.MIN_VALUE)); } } @Test - void testShouldThrowExceptionWhenTruncatingToIncorrectSize() { + void testThrowWhenTruncatingToIncorrectSize() throws IOException { try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MAX_VALUE + 1L)); + final ByteBuffer buffer = ByteBuffer.allocate(1); + c.truncate(c.size() + 1); + assertEquals(-1, c.read(buffer)); + c.truncate(Integer.MAX_VALUE + 1L); + assertEquals(-1, c.read(buffer)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(-1)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(Long.MIN_VALUE)); } } diff --git a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelTest.java b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelTest.java index 5b29b3f1be0..79f971e4a0c 100644 --- a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelTest.java +++ b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelTest.java @@ -84,6 +84,22 @@ void testConstructorInvalid() { assertThrows(NullPointerException.class, () -> ByteArraySeekableByteChannel.wrap(null)); } + @Test + void testPositionBeyondSizeReadWrite() throws IOException { + final ByteBuffer buffer = ByteBuffer.allocate(1); + channel.position(channel.size() + 1); + assertEquals(channel.size() + 1, channel.position()); + assertEquals(-1, channel.read(buffer)); + channel.position(Integer.MAX_VALUE + 1L); + assertEquals(Integer.MAX_VALUE + 1L, channel.position()); + assertEquals(-1, channel.read(buffer)); + // ByteArraySeekableByteChannel has a hard boundary at Integer.MAX_VALUE, files don't. + assertThrows(IOException.class, () -> channel.write(buffer)); + assertThrows(IllegalArgumentException.class, () -> channel.position(-1)); + assertThrows(IllegalArgumentException.class, () -> channel.position(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> channel.position(Long.MIN_VALUE)); + } + @ParameterizedTest @MethodSource void testShouldResizeWhenWritingMoreDataThanCapacity(final byte[] data, final int wanted) throws IOException { From 8f66b3212c3d35c74cc96e7d0b3258f0fb9305f1 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 8 Dec 2025 16:58:12 -0500 Subject: [PATCH 092/174] ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817 --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 49ec68e14ce..da3cd56c805 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -48,6 +48,7 @@ The type attribute can be add,update,fix,remove. Fix Apache RAT plugin console warnings. + ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Bump org.apache.commons:commons-parent from 91 to 93 #816. From 68be2fbbe46d26a854d6a8af6e38a8f60a4b49a0 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 11 Dec 2025 16:20:55 -0500 Subject: [PATCH 093/174] Add and use IOUtils.closeQuietly(Closeable, Throwable) (#818) * [IO-856] Try test on all OSs for GitHub CI * Add and use IOUtils.closeQuietly(Closeable, Throwable) --- .../java/org/apache/commons/io/FileUtils.java | 2 +- .../java/org/apache/commons/io/IOUtils.java | 37 ++++++++++++++++++- .../org/apache/commons/io/LineIterator.java | 3 +- .../io/output/FileWriterWithEncoding.java | 6 +-- .../org/apache/commons/io/IOUtilsTest.java | 13 +++++++ 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index 523c2c1fd26..a24ab813a73 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -2290,7 +2290,7 @@ public static LineIterator lineIterator(final File file, final String charsetNam inputStream = Files.newInputStream(file.toPath()); return IOUtils.lineIterator(inputStream, charsetName); } catch (final IOException | RuntimeException ex) { - IOUtils.closeQuietly(inputStream, ex::addSuppressed); + IOUtils.closeQuietly(inputStream, ex); throw ex; } } diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 09a018b036d..8a4057ae514 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -780,7 +780,7 @@ public static void close(final URLConnection conn) { * @param closeable the object to close, may be null. */ private static void closeQ(final Closeable closeable) { - closeQuietly(closeable, null); + closeQuietly(closeable, (Consumer) null); } /** @@ -824,7 +824,40 @@ private static void closeQ(final Closeable closeable) { * @see Throwable#addSuppressed(Throwable) */ public static void closeQuietly(final Closeable closeable) { - closeQuietly(closeable, null); + closeQuietly(closeable, (Consumer) null); + } + + /** + * Closes a {@link Closeable} unconditionally and adds any exception thrown by the {@code close()} to the given Throwable. + * + *

      + * For example: + *

      + * + *
      +     * Closeable closeable = ...;
      +     * try {
      +     *     // process closeable
      +     *     closeable.close();
      +     * } catch (Exception e) {
      +     *     // error handling
      +     *     throw IOUtils.closeQuietly(closeable, e);
      +     * }
      +     * 
      + *

      + * Also consider using a try-with-resources statement where appropriate. + *

      + * + * @param The Throwable type. + * @param closeable The object to close, may be null or already closed. + * @param throwable Add the exception throw by the closeable to the given Throwable. + * @return The given Throwable. + * @since 2.22.0 + * @see Throwable#addSuppressed(Throwable) + */ + public static T closeQuietly(final Closeable closeable, final T throwable) { + closeQuietly(closeable, (Consumer) throwable::addSuppressed); + return throwable; } /** diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index 293847e7a72..2e1bf0169ab 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -135,8 +135,7 @@ public boolean hasNext() { } } } catch (final IOException ioe) { - IOUtils.closeQuietly(this, ioe::addSuppressed); - throw new IllegalStateException(ioe); + throw new IllegalStateException(IOUtils.closeQuietly(this, ioe)); } } 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 42d378cc0a5..1bb15a37a19 100644 --- a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java +++ b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java @@ -188,11 +188,7 @@ private static OutputStreamWriter initWriter(final File file, final Object encod } return new OutputStreamWriter(outputStream, (String) encoding); } catch (final IOException | RuntimeException ex) { - try { - IOUtils.close(outputStream); - } catch (final IOException e) { - ex.addSuppressed(e); - } + IOUtils.closeQuietly(outputStream, ex); if (!fileExistedAlready) { FileUtils.deleteQuietly(file); } diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 033fdffdd76..df90ab66e11 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; @@ -539,6 +540,18 @@ void testCloseQuietly_AllCloseableIOException() { assertDoesNotThrow(() -> IOUtils.closeQuietly((Iterable) null)); } + @SuppressWarnings("resource") + @Test + void testCloseQuietly_CloseableIOExceptionAddSuppressed() { + final Throwable e = new Exception("test").fillInStackTrace(); + assertEquals(0, e.getSuppressed().length); + assertSame(e, IOUtils.closeQuietly(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); + assertEquals(1, e.getSuppressed().length); + final Throwable suppressed0 = e.getSuppressed()[0]; + assertInstanceOf(EOFException.class, suppressed0); + assertEquals("Suppressed", suppressed0.getMessage()); + } + @Test void testCloseQuietly_CloseableException() { // IOException From 6b20316b827099882b34252d0f56ac91a9d3ac42 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 11 Dec 2025 16:21:39 -0500 Subject: [PATCH 094/174] Add and use IOUtils.closeQuietly(Closeable, Throwable) #818 --- src/changes/changes.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index da3cd56c805..20407682432 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,11 +45,12 @@ The type attribute can be add,update,fix,remove. Apache Commons IO Release Notes
      - + Fix Apache RAT plugin console warnings. ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. + Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. Bump org.apache.commons:commons-parent from 91 to 93 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. From 55c6b20a7e3af19a59558f2b4042f16eb8ebf2a7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 11 Dec 2025 16:23:05 -0500 Subject: [PATCH 095/174] Bump next version to feature level --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b297ce09ae9..0baa433cabc 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ 4.0.0 commons-io commons-io - 2.21.1-SNAPSHOT + 2.22.0-SNAPSHOT Apache Commons IO 2002 @@ -102,8 +102,8 @@ file comparators, endian transformation classes, and much more. org.apache.commons.io RC1 2.21.0 - 2.21.1 - 2.21.2 + 2.22.0 + 2.22.1 2025-11-06T21:58:17Z (requires Java 8) From 85ef57b1a7292120fc231a4e5d389fc173ea5197 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 12 Dec 2025 08:17:05 -0500 Subject: [PATCH 096/174] Bump github/codeql-action from 4.31.7 to 4.31.8 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index adb989633ea..179f767d2c1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 + uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 + uses: github/codeql-action/autobuild@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 + uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 37ad379e71b..5f76ef06bed 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v4.31.7 + uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 with: sarif_file: results.sarif From 5e08e76bfe410a731eb5bf5ef2c7886873390fdc Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 12 Dec 2025 14:27:21 -0500 Subject: [PATCH 097/174] Bump actions/cache from 4.3.0 to 5.0.1 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/maven.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 179f767d2c1..8c344d4b777 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -53,7 +53,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 2b245e642d5..b5daa9a6ee6 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -63,7 +63,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false - - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From 11c0562b0b0159484fcb412339914f7de498a289 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 13 Dec 2025 07:53:04 -0500 Subject: [PATCH 098/174] Javadoc --- .../java/org/apache/commons/io/IOUtils.java | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 8a4057ae514..e263e118c19 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -558,11 +558,11 @@ private static char[] charArray(final int size) { * } * * - * @param array the array against which the range is validated - * @param off the starting offset into the array (inclusive) - * @param len the number of elements to access - * @throws NullPointerException if {@code array} is {@code null} - * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array} + * @param array the array against which the range is validated. + * @param off the starting offset into the array (inclusive). + * @param len the number of elements to access. + * @throws NullPointerException if {@code array} is {@code null}. + * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}. * @see InputStream#read(byte[], int, int) * @see OutputStream#write(byte[], int, int) * @since 2.21.0 @@ -605,11 +605,11 @@ public static void checkFromIndexSize(final byte[] array, final int off, final i * } * * - * @param array the array against which the range is validated - * @param off the starting offset into the array (inclusive) - * @param len the number of characters to access - * @throws NullPointerException if {@code array} is {@code null} - * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array} + * @param array the array against which the range is validated. + * @param off the starting offset into the array (inclusive). + * @param len the number of characters to access. + * @throws NullPointerException if {@code array} is {@code null}. + * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code array}. * @see Reader#read(char[], int, int) * @see Writer#write(char[], int, int) * @since 2.21.0 @@ -648,11 +648,11 @@ static void checkFromIndexSize(final int off, final int len, final int arrayLeng * } * * - * @param str the string against which the range is validated - * @param off the starting offset into the string (inclusive) - * @param len the number of characters to write - * @throws NullPointerException if {@code str} is {@code null} - * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code str} + * @param str the string against which the range is validated. + * @param off the starting offset into the string (inclusive). + * @param len the number of characters to write. + * @throws NullPointerException if {@code str} is {@code null}. + * @throws IndexOutOfBoundsException if the range {@code [off, off + len)} is out of bounds for {@code str}. * @see Writer#write(String, int, int) * @since 2.21.0 */ @@ -684,10 +684,10 @@ public static void checkFromIndexSize(final String str, final int off, final int * } * * - * @param seq the character sequence to validate (may be {@code null}, treated as {@code "null"}) - * @param fromIndex the starting index (inclusive) - * @param toIndex the ending index (exclusive) - * @throws IndexOutOfBoundsException if the range {@code [fromIndex, toIndex)} is out of bounds for {@code seq} + * @param seq the character sequence to validate (may be {@code null}, treated as {@code "null"}). + * @param fromIndex the starting index (inclusive). + * @param toIndex the ending index (exclusive). + * @throws IndexOutOfBoundsException if the range {@code [fromIndex, toIndex)} is out of bounds for {@code seq}. * @see Appendable#append(CharSequence, int, int) * @since 2.21.0 */ @@ -1889,10 +1889,10 @@ public static long copyLarge(final Reader reader, final Writer writer) throws IO * * @param reader the {@link Reader} to source. * @param writer the {@link Writer} to target. - * @param buffer the buffer to be used for the copy - * @return the number of characters copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs + * @param buffer the buffer to be used for the copy. + * @return the number of characters copied. + * @throws NullPointerException if the input or output is null. + * @throws IOException if an I/O error occurs. * @since 2.2 */ public static long copyLarge(final Reader reader, final Writer writer, final char[] buffer) throws IOException { From b953e196138234f2295b0a4e12d9c3d8a00520ec Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 13 Dec 2025 07:53:18 -0500 Subject: [PATCH 099/174] Javadoc: Add missing tags --- src/main/java/org/apache/commons/io/file/PathUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java index bafcf86ca81..6672df7ac71 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -499,7 +499,7 @@ public static Path current() { *

      *
        *
      • A directory to delete does not have to be empty.
      • - *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean. + *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean.
      • *
      * * @param path file or directory to delete, must not be {@code null} @@ -518,7 +518,7 @@ public static PathCounters delete(final Path path) throws IOException { *

      *
        *
      • A directory to delete does not have to be empty.
      • - *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean. + *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean.
      • *
      * * @param path file or directory to delete, must not be {@code null} @@ -540,7 +540,7 @@ public static PathCounters delete(final Path path, final DeleteOption... deleteO *

      *
        *
      • A directory to delete does not have to be empty.
      • - *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean. + *
      • You get exceptions when a file or directory cannot be deleted; {@link File#delete()} returns a boolean.
      • *
      * * @param path file or directory to delete, must not be {@code null} From 56f1f77c20f696058bb265a4a43ebbef0fc8d27a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 13 Dec 2025 08:03:17 -0500 Subject: [PATCH 100/174] Fix malformed Javadoc comments --- src/changes/changes.xml | 1 + .../apache/commons/io/DirectoryWalker.java | 2 +- .../java/org/apache/commons/io/FileUtils.java | 20 +++++++++---------- .../java/org/apache/commons/io/IOUtils.java | 10 +++++----- .../commons/io/input/ProxyInputStream.java | 4 ++-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 20407682432..12cf9018531 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -49,6 +49,7 @@ The type attribute can be add,update,fix,remove. Fix Apache RAT plugin console warnings. ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. + Fix malformed Javadoc comments. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java index ac3d8bd5fd7..23f5f14f2a8 100644 --- a/src/main/java/org/apache/commons/io/DirectoryWalker.java +++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java @@ -167,7 +167,7 @@ *
        *
      • The decision logic on whether to cancel processing or not.
      • *
      • Constructing and throwing a {@link CancelException}.
      • - *
      • Custom cancel processing in the {@code handleCancelled()} method. + *
      • Custom cancel processing in the {@code handleCancelled()} method.
      • *
      *

      * Two possible scenarios are envisaged for cancellation: diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index a24ab813a73..b86f5504814 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -93,16 +93,16 @@ * Facilities are provided in the following areas: *

      *
        - *
      • writing to a file - *
      • reading from a file - *
      • make a directory including parent directories - *
      • copying files and directories - *
      • deleting files and directories - *
      • converting to and from a URL - *
      • listing files and directories by filter and extension - *
      • comparing file content - *
      • file last changed date - *
      • calculating a checksum + *
      • writing to a file
      • + *
      • reading from a file
      • + *
      • make a directory including parent directories
      • + *
      • copying files and directories
      • + *
      • deleting files and directories
      • + *
      • converting to and from a URL
      • + *
      • listing files and directories by filter and extension
      • + *
      • comparing file content
      • + *
      • file last changed date
      • + *
      • calculating a checksum
      • *
      *

      * Note that a specific charset should be specified whenever possible. Relying on the platform default means that the diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index e263e118c19..cb375e07b4b 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -81,11 +81,11 @@ * This class provides static utility methods for input/output operations. *

      *
        - *
      • closeQuietly - these methods close a stream ignoring nulls and exceptions - *
      • toXxx/read - these methods read data from a stream - *
      • write - these methods write data to a stream - *
      • copy - these methods copy all the data from one stream to another - *
      • contentEquals - these methods compare the content of two streams + *
      • closeQuietly - these methods close a stream ignoring nulls and exceptions
      • + *
      • toXxx/read - these methods read data from a stream
      • + *
      • write - these methods write data to a stream
      • + *
      • copy - these methods copy all the data from one stream to another
      • + *
      • contentEquals - these methods compare the content of two streams
      • *
      *

      * The byte-to-char methods and char-to-byte methods involve a conversion step. diff --git a/src/main/java/org/apache/commons/io/input/ProxyInputStream.java b/src/main/java/org/apache/commons/io/input/ProxyInputStream.java index b2e04c334b5..7530e3399c2 100644 --- a/src/main/java/org/apache/commons/io/input/ProxyInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ProxyInputStream.java @@ -298,7 +298,7 @@ public int read() throws IOException { * @return the number of bytes read or {@link IOUtils#EOF EOF} if we reached the end of stream. * @throws IOException *

        - *
      • If the first byte cannot be read for any reason other than the end of the file, + *
      • If the first byte cannot be read for any reason other than the end of the file,
      • *
      • if the input stream has been closed, or
      • *
      • if some other I/O error occurs.
      • *
      @@ -325,7 +325,7 @@ public int read(final byte[] b) throws IOException { * @return the number of bytes read or {@link IOUtils#EOF EOF} if we reached the end of stream. * @throws IOException *
        - *
      • If the first byte cannot be read for any reason other than the end of the file, + *
      • If the first byte cannot be read for any reason other than the end of the file,
      • *
      • if the input stream has been closed, or
      • *
      • if some other I/O error occurs.
      • *
      From 42fe06c330b4899aad0d4851d010017d600e3f7c Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 17 Dec 2025 07:50:53 -0500 Subject: [PATCH 101/174] Bump github/codeql-action from 4.31.8 to 4.31.9 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8c344d4b777..c83bf59255c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 + uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 + uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 + uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 5f76ef06bed..26298d050c5 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@1b168cd39490f61582a9beae412bb7057a6b2c4e # v4.31.8 + uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 with: sarif_file: results.sarif From a053988297aae0447620080d54c553ae0eb4d7ea Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 19 Dec 2025 13:51:31 -0500 Subject: [PATCH 102/174] Bump actions/upload-artifact from 5.0.0 to 6.0.0 --- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 26298d050c5..980935089e8 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -59,7 +59,7 @@ jobs: publish_results: true - name: "Upload artifact" - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # 5.0.0 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: SARIF file path: results.sarif From 1f80529bc386e0b32e7674caebd83f8edb0eadfb Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 20 Dec 2025 09:15:57 -0500 Subject: [PATCH 103/174] Replace JUnit @DisplayName to make Maven output meaningful --- .../org/apache/commons/io/input/QueueInputStreamTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java b/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java index 5ea695095f8..3a97c8dc24f 100644 --- a/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java @@ -50,7 +50,6 @@ import org.apache.commons.io.output.QueueOutputStream; import org.apache.commons.io.output.QueueOutputStreamTest; import org.apache.commons.lang3.StringUtils; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; @@ -312,7 +311,7 @@ void testResetArguments() throws IOException { } @Test - @DisplayName("If read is interrupted while waiting, then exception is thrown") + /** If read is interrupted while waiting, then exception is thrown */ void testTimeoutInterrupted() throws Exception { try (QueueInputStream inputStream = QueueInputStream.builder().setTimeout(Duration.ofMinutes(2)).get(); QueueOutputStream outputStream = inputStream.newQueueOutputStream()) { @@ -338,7 +337,7 @@ void testTimeoutInterrupted() throws Exception { } @Test - @DisplayName("If data is not available in queue, then read will wait until wait time elapses") + /** If data is not available in queue, then read will wait until wait time elapses */ void testTimeoutUnavailableData() throws IOException { try (QueueInputStream inputStream = QueueInputStream.builder().setTimeout(Duration.ofMillis(500)).get(); QueueOutputStream outputStream = inputStream.newQueueOutputStream()) { From 65f8e5d55d02c2503e122a1d35601eba3c315e73 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 24 Dec 2025 08:23:29 -0500 Subject: [PATCH 104/174] Sppedup IOUtils.contentEquals(Reader, Reader) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ~2.6x speedup on StringReader input - ~10% speed on file resource as InputStreamReader Benchmark Mode Cnt Score Error Units IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileCurrent avgt 5 105274.452 ± 1466.048 ns/op IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileRelease2_22_0 avgt 5 107500.847 ± 1752.422 ns/op IOUtilsContentEqualsReadersBenchmark_2_22_0.testFile_2_21_0 avgt 5 115720.416 ± 1209.652 ns/op IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringCurrent avgt 5 113330719.330 ± 1187191.151 ns/op IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringRelease2_22_0 avgt 5 110389392.582 ± 785367.455 ns/op IOUtilsContentEqualsReadersBenchmark_2_22_0.testString_2_21_0 avgt 5 284939866.619 ± 9969793.485 ns/op Apache Maven 3.9.12 (848fbb4bf2d427b72bdb2471c22fced7ebd9a7a1) Maven home: /opt/homebrew/Cellar/maven/3.9.12/libexec Java version: 21.0.9, vendor: Homebrew, runtime: /opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home Default locale: en_US, platform encoding: UTF-8 OS name: "mac os x", version: "26.2", arch: "aarch64", family: "mac" --- .../java/org/apache/commons/io/IOUtils.java | 50 +-- ...sContentEqualsReadersBenchmark_2_22_0.java | 255 ++++++++++++++ ...sContentEqualsReadersBenchmark_2_9_0.java} | 3 +- ...sContentEqualsReadersBenchmark_2_22_0.json | 316 ++++++++++++++++++ 4 files changed, 589 insertions(+), 35 deletions(-) create mode 100644 src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java rename src/test/java/org/apache/commons/io/jmh/{IOUtilsContentEqualsReadersBenchmark.java => IOUtilsContentEqualsReadersBenchmark_2_9_0.java} (99%) create mode 100644 src/test/java/org/apache/commons/io/jmh/jmh-result.IOUtilsContentEqualsReadersBenchmark_2_22_0.json diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index cb375e07b4b..ee2f5510fb1 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1256,10 +1256,7 @@ public static boolean contentEquals(final InputStream input1, final InputStream // TODO Consider making public private static boolean contentEquals(final Iterator iterator1, final Iterator iterator2) { while (iterator1.hasNext()) { - if (!iterator2.hasNext()) { - return false; - } - if (!Objects.equals(iterator1.next(), iterator2.next())) { + if (!iterator2.hasNext() || !Objects.equals(iterator1.next(), iterator2.next())) { return false; } } @@ -1280,45 +1277,32 @@ private static boolean contentEquals(final Iterator iterator1, final Iterator * @since 1.1 */ public static boolean contentEquals(final Reader input1, final Reader input2) throws IOException { + // See IOUtilsContentEqualsReadersBenchmark_2_22_0 for performance testing. if (input1 == input2) { return true; } if (input1 == null || input2 == null) { return false; } - - // reuse one try (ScratchChars scratch = IOUtils.ScratchChars.get()) { final char[] array1 = scratch.array(); - // but allocate another final char[] array2 = charArray(); - int pos1; - int pos2; - int count1; - int count2; + int read1; + int read2; while (true) { - pos1 = 0; - pos2 = 0; - for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { - if (pos1 == index) { - do { - count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); - } while (count1 == 0); - if (count1 == EOF) { - return pos2 == index && input2.read() == EOF; - } - pos1 += count1; - } - if (pos2 == index) { - do { - count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); - } while (count2 == 0); - if (count2 == EOF) { - return pos1 == index && input1.read() == EOF; - } - pos2 += count2; - } - if (array1[index] != array2[index]) { + read1 = input1.read(array1, 0, DEFAULT_BUFFER_SIZE); + read2 = input2.read(array2, 0, DEFAULT_BUFFER_SIZE); + // If both read EOF here, they're equal. + if (read1 == EOF && read2 == EOF) { + return true; + } + // If only one read EOF or different amounts, they're not equal. + if (read1 != read2) { + return false; + } + // Compare the buffers - bulk comparison is faster than character-by-character + for (int i = 0; i < read1; i++) { + if (array1[i] != array2[i]) { return false; } } diff --git a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java new file mode 100644 index 00000000000..e90b6425518 --- /dev/null +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java @@ -0,0 +1,255 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.jmh; + +import static org.apache.commons.io.IOUtils.DEFAULT_BUFFER_SIZE; +import static org.apache.commons.io.IOUtils.EOF; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.nio.charset.Charset; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +/** + * Test different implementations of {@link IOUtils#contentEquals(Reader, Reader)}. + * + *
      + * RESULTS:
      + * Benchmark                                                            Mode  Cnt          Score         Error  Units
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileCurrent          avgt    5     105274.452 ±    1466.048  ns/op
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileRelease2_22_0    avgt    5     107500.847 ±    1752.422  ns/op
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testFile_2_21_0          avgt    5     115720.416 ±    1209.652  ns/op
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringCurrent        avgt    5  113330719.330 ± 1187191.151  ns/op
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringRelease2_22_0  avgt    5  110389392.582 ±  785367.455  ns/op
      + * IOUtilsContentEqualsReadersBenchmark_2_22_0.testString_2_21_0        avgt    5  284939866.619 ± 9969793.485  ns/op
      + *
      + * Run: mvn clean test -P benchmark -Dbenchmark=IOUtilsContentEqualsReadersBenchmark_2_22_0
      + * 
      + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) +@Fork(value = 1, jvmArgs = {"-server"}) +public class IOUtilsContentEqualsReadersBenchmark_2_22_0 { + + private static final int STRING_LEN = 1 << 24; + private static final String TEST_PATH_A = "/org/apache/commons/io/testfileBOM.xml"; + private static final String TEST_PATH_16K_A = "/org/apache/commons/io/abitmorethan16k.txt"; + private static final String TEST_PATH_16K_A_COPY = "/org/apache/commons/io/abitmorethan16kcopy.txt"; + private static final String TEST_PATH_B = "/org/apache/commons/io/testfileNoBOM.xml"; + private static final Charset DEFAULT_CHARSET = Charset.defaultCharset(); + static String[] STRINGS = new String[5]; + + static { + STRINGS[0] = StringUtils.repeat("ab", STRING_LEN); + STRINGS[1] = STRINGS[0] + 'c'; + STRINGS[2] = STRINGS[0] + 'd'; + STRINGS[3] = StringUtils.repeat("ab\rab\n", STRING_LEN); + STRINGS[4] = StringUtils.repeat("ab\r\nab\r", STRING_LEN); + } + + static String SPECIAL_CASE_STRING_0 = StringUtils.repeat(StringUtils.repeat("ab", STRING_LEN) + '\n', 2); + static String SPECIAL_CASE_STRING_1 = StringUtils.repeat(StringUtils.repeat("cd", STRING_LEN) + '\n', 2); + + public static boolean contentEquals_2_21_0(final Reader input1, final Reader input2) throws IOException { + if (input1 == input2) { + return true; + } + if (input1 == null || input2 == null) { + return false; + } + final char[] array1 = new char[DEFAULT_BUFFER_SIZE]; + final char[] array2 = new char[DEFAULT_BUFFER_SIZE]; + int pos1; + int pos2; + int count1; + int count2; + while (true) { + pos1 = 0; + pos2 = 0; + for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { + if (pos1 == index) { + do { + count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); + } while (count1 == 0); + if (count1 == EOF) { + return pos2 == index && input2.read() == EOF; + } + pos1 += count1; + } + if (pos2 == index) { + do { + count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); + } while (count2 == 0); + if (count2 == EOF) { + return pos1 == index && input1.read() == EOF; + } + pos2 += count2; + } + if (array1[index] != array2[index]) { + return false; + } + } + } + } + + /** + * Version 2.22.0 (December 2025). + */ + public static boolean contentEqualsRelease2_22_0(final Reader input1, final Reader input2) throws IOException { + if (input1 == input2) { + return true; + } + if (input1 == null || input2 == null) { + return false; + } + final char[] array1 = new char[DEFAULT_BUFFER_SIZE]; + final char[] array2 = new char[DEFAULT_BUFFER_SIZE]; + int read1; + int read2; + while (true) { + read1 = input1.read(array1, 0, DEFAULT_BUFFER_SIZE); + read2 = input2.read(array2, 0, DEFAULT_BUFFER_SIZE); + // If both read EOF here, they're equal. + if (read1 == EOF && read2 == EOF) { + return true; + } + // If only one read EOF or different amounts, they're not equal. + if (read1 != read2) { + return false; + } + // Compare the buffers - bulk comparison is faster than character-by-character + for (int i = 0; i < read1; i++) { + if (array1[i] != array2[i]) { + return false; + } + } + } + } + + @Benchmark + public boolean[] testFile_2_21_0() throws IOException { + final boolean[] res = new boolean[3]; + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_B), DEFAULT_CHARSET)) { + res[0] = contentEquals_2_21_0(input1, input1); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET)) { + res[1] = contentEquals_2_21_0(input1, input2); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A)); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A_COPY))) { + res[2] = contentEquals_2_21_0(input1, input2); + } + return res; + } + + @Benchmark + public boolean[] testFileCurrent() throws IOException { + final boolean[] res = new boolean[3]; + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_B), DEFAULT_CHARSET)) { + res[0] = IOUtils.contentEquals(input1, input1); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET)) { + res[1] = IOUtils.contentEquals(input1, input2); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A_COPY), + DEFAULT_CHARSET)) { + res[2] = IOUtils.contentEquals(input1, input2); + } + return res; + } + + @Benchmark + public boolean[] testFileRelease2_22_0() throws IOException { + final boolean[] res = new boolean[3]; + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_B), DEFAULT_CHARSET)) { + res[0] = contentEqualsRelease2_22_0(input1, input1); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_A), DEFAULT_CHARSET)) { + res[1] = contentEqualsRelease2_22_0(input1, input2); + } + try (Reader input1 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A), DEFAULT_CHARSET); + Reader input2 = new InputStreamReader(getClass().getResourceAsStream(TEST_PATH_16K_A_COPY), + DEFAULT_CHARSET)) { + res[2] = contentEqualsRelease2_22_0(input1, input2); + } + return res; + } + + @Benchmark + public void testString_2_21_0(final Blackhole blackhole) throws IOException { + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + try (StringReader input1 = new StringReader(STRINGS[i]); + StringReader input2 = new StringReader(STRINGS[j])) { + blackhole.consume(contentEquals_2_21_0(input1, input2)); + } + } + } + } + + @Benchmark + public void testStringCurrent(final Blackhole blackhole) throws IOException { + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + try (StringReader input1 = new StringReader(STRINGS[i]); + StringReader input2 = new StringReader(STRINGS[j])) { + blackhole.consume(IOUtils.contentEquals(input1, input2)); + } + } + } + } + + @Benchmark + public void testStringRelease2_22_0(final Blackhole blackhole) throws IOException { + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + try (StringReader input1 = new StringReader(STRINGS[i]); + StringReader input2 = new StringReader(STRINGS[j])) { + blackhole.consume(contentEqualsRelease2_22_0(input1, input2)); + } + } + } + } + +} diff --git a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_9_0.java similarity index 99% rename from src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java rename to src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_9_0.java index 394989d4f72..b548e10e760 100644 --- a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark.java +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_9_0.java @@ -59,7 +59,7 @@ @Warmup(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) @Fork(value = 1, jvmArgs = {"-server"}) -public class IOUtilsContentEqualsReadersBenchmark { +public class IOUtilsContentEqualsReadersBenchmark_2_9_0 { private static final int STRING_LEN = 1 << 24; private static final String TEST_PATH_A = "/org/apache/commons/io/testfileBOM.xml"; @@ -80,7 +80,6 @@ public class IOUtilsContentEqualsReadersBenchmark { static String SPECIAL_CASE_STRING_0 = StringUtils.repeat(StringUtils.repeat("ab", STRING_LEN) + '\n', 2); static String SPECIAL_CASE_STRING_1 = StringUtils.repeat(StringUtils.repeat("cd", STRING_LEN) + '\n', 2); - @SuppressWarnings("resource") public static boolean contentEquals_release_2_8_0(final Reader input1, final Reader input2) throws IOException { if (input1 == input2) { return true; diff --git a/src/test/java/org/apache/commons/io/jmh/jmh-result.IOUtilsContentEqualsReadersBenchmark_2_22_0.json b/src/test/java/org/apache/commons/io/jmh/jmh-result.IOUtilsContentEqualsReadersBenchmark_2_22_0.json new file mode 100644 index 00000000000..b9866381304 --- /dev/null +++ b/src/test/java/org/apache/commons/io/jmh/jmh-result.IOUtilsContentEqualsReadersBenchmark_2_22_0.json @@ -0,0 +1,316 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileCurrent", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 105274.45150949701, + "scoreError" : 1466.048137250757, + "scoreConfidence" : [ + 103808.40337224625, + 106740.49964674778 + ], + "scorePercentiles" : { + "0.0" : 104886.00264178636, + "50.0" : 105288.5813030386, + "90.0" : 105680.8236754792, + "95.0" : 105680.8236754792, + "99.0" : 105680.8236754792, + "99.9" : 105680.8236754792, + "99.99" : 105680.8236754792, + "99.999" : 105680.8236754792, + "99.9999" : 105680.8236754792, + "100.0" : 105680.8236754792 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 104886.00264178636, + 104895.74661620239, + 105288.5813030386, + 105621.1033109785, + 105680.8236754792 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testFileRelease2_22_0", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 107500.84684379803, + "scoreError" : 1752.4217586039497, + "scoreConfidence" : [ + 105748.42508519409, + 109253.26860240198 + ], + "scorePercentiles" : { + "0.0" : 106873.3514249701, + "50.0" : 107628.91570477307, + "90.0" : 107940.15830545062, + "95.0" : 107940.15830545062, + "99.0" : 107940.15830545062, + "99.9" : 107940.15830545062, + "99.99" : 107940.15830545062, + "99.999" : 107940.15830545062, + "99.9999" : 107940.15830545062, + "100.0" : 107940.15830545062 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 106873.3514249701, + 107196.61074616629, + 107940.15830545062, + 107865.19803763006, + 107628.91570477307 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testFile_2_21_0", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 115720.41582367099, + "scoreError" : 1209.6519258037997, + "scoreConfidence" : [ + 114510.76389786719, + 116930.0677494748 + ], + "scorePercentiles" : { + "0.0" : 115404.00708540568, + "50.0" : 115555.87606112054, + "90.0" : 116064.94892289132, + "95.0" : 116064.94892289132, + "99.0" : 116064.94892289132, + "99.9" : 116064.94892289132, + "99.99" : 116064.94892289132, + "99.999" : 116064.94892289132, + "99.9999" : 116064.94892289132, + "100.0" : 116064.94892289132 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 115524.47655447145, + 115555.87606112054, + 115404.00708540568, + 116052.77049446598, + 116064.94892289132 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringCurrent", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.1333071932957098E8, + "scoreError" : 1187191.1514731636, + "scoreConfidence" : [ + 1.1214352817809781E8, + 1.1451791048104414E8 + ], + "scorePercentiles" : { + "0.0" : 1.130216048764045E8, + "50.0" : 1.1326928604494382E8, + "90.0" : 1.138494346590909E8, + "95.0" : 1.138494346590909E8, + "99.0" : 1.138494346590909E8, + "99.9" : 1.138494346590909E8, + "99.99" : 1.138494346590909E8, + "99.999" : 1.138494346590909E8, + "99.9999" : 1.138494346590909E8, + "100.0" : 1.138494346590909E8 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1.138494346590909E8, + 1.1323600233707865E8, + 1.1327726873033708E8, + 1.130216048764045E8, + 1.1326928604494382E8 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testStringRelease2_22_0", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1.1038939258241758E8, + "scoreError" : 785367.4549160029, + "scoreConfidence" : [ + 1.0960402512750158E8, + 1.1117476003733358E8 + ], + "scorePercentiles" : { + "0.0" : 1.1018472527472527E8, + "50.0" : 1.1037075183516483E8, + "90.0" : 1.106605673076923E8, + "95.0" : 1.106605673076923E8, + "99.0" : 1.106605673076923E8, + "99.9" : 1.106605673076923E8, + "99.99" : 1.106605673076923E8, + "99.999" : 1.106605673076923E8, + "99.9999" : 1.106605673076923E8, + "100.0" : 1.106605673076923E8 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1.1052274404395604E8, + 1.1020817445054945E8, + 1.1037075183516483E8, + 1.1018472527472527E8, + 1.106605673076923E8 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "org.apache.commons.io.jmh.IOUtilsContentEqualsReadersBenchmark_2_22_0.testString_2_21_0", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/opt/homebrew/Cellar/openjdk@21/21.0.9/libexec/openjdk.jdk/Contents/Home/bin/java", + "jvmArgs" : [ + "-server" + ], + "jdkVersion" : "21.0.9", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "21.0.9", + "warmupIterations" : 5, + "warmupTime" : "10 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "10 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2.849398666193651E8, + "scoreError" : 9969793.485202054, + "scoreConfidence" : [ + 2.74970073134163E8, + 2.9490966010456717E8 + ], + "scorePercentiles" : { + "0.0" : 2.803803090277778E8, + "50.0" : 2.858566214285714E8, + "90.0" : 2.866562731666667E8, + "95.0" : 2.866562731666667E8, + "99.0" : 2.866562731666667E8, + "99.9" : 2.866562731666667E8, + "99.99" : 2.866562731666667E8, + "99.999" : 2.866562731666667E8, + "99.9999" : 2.866562731666667E8, + "100.0" : 2.866562731666667E8 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2.8634049405714285E8, + 2.803803090277778E8, + 2.858566214285714E8, + 2.866562731666667E8, + 2.854656354166667E8 + ] + ] + }, + "secondaryMetrics" : { + } + } +] + + From 21ac35863b7677c814f4d34405f237dc5df2c069 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 24 Dec 2025 08:31:44 -0500 Subject: [PATCH 105/174] Remove unused import --- .../io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java index e90b6425518..1a3ac4929da 100644 --- a/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java @@ -20,7 +20,6 @@ import static org.apache.commons.io.IOUtils.DEFAULT_BUFFER_SIZE; import static org.apache.commons.io.IOUtils.EOF; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; From 8e88c6e0d847cbaa6068be98705cc2bc61b934ea Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 24 Dec 2025 09:59:42 -0500 Subject: [PATCH 106/174] Javadoc --- src/main/java/org/apache/commons/io/FileSystem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/FileSystem.java b/src/main/java/org/apache/commons/io/FileSystem.java index 4169e1a53b1..e05b52c189e 100644 --- a/src/main/java/org/apache/commons/io/FileSystem.java +++ b/src/main/java/org/apache/commons/io/FileSystem.java @@ -294,7 +294,7 @@ public static FileSystem getCurrent() { * Decides if the operating system matches. * * @param osNamePrefix - * the prefix for the os name + * the prefix for the operating system name * @return true if matches, or false if not or can't determine */ private static boolean getOsMatchesName(final String osNamePrefix) { From 6f2b06b9719fe6cad6e6e9f6ea3f8155ff43679a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 24 Dec 2025 10:25:19 -0500 Subject: [PATCH 107/174] Fix: The type parameter T is hiding the type T --- .../commons/io/output/AbstractByteArrayOutputStream.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java index dc2de64a4a2..fe54f5a7960 100644 --- a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java @@ -246,7 +246,7 @@ protected byte[] toByteArrayImpl() { * returned stream is backed by buffers of {@code this} stream, * avoiding memory allocation and copy, thus saving space and time.
      * - * @param the type of the InputStream which makes up + * @param the type of the InputStream which makes up * the {@link SequenceInputStream}. * @param isConstructor A constructor for an InputStream which makes * up the {@link SequenceInputStream}. @@ -257,12 +257,12 @@ protected byte[] toByteArrayImpl() { * @since 2.7 */ @SuppressWarnings("resource") // The result InputStream MUST be managed by the call site. - protected InputStream toInputStream(final InputStreamConstructor isConstructor) { + protected InputStream toInputStream(final InputStreamConstructor isConstructor) { int remaining = count; if (remaining == 0) { return ClosedInputStream.INSTANCE; } - final List list = new ArrayList<>(buffers.size()); + final List list = new ArrayList<>(buffers.size()); for (final byte[] buf : buffers) { final int c = Math.min(buf.length, remaining); list.add(isConstructor.construct(buf, 0, c)); From c5adbaf78f9e4a730d43d410c441843dac6e6d23 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 24 Dec 2025 10:25:54 -0500 Subject: [PATCH 108/174] Remove @SuppressWarnings("deprecation") --- .../java/org/apache/commons/io/file/AccumulatorPathVisitor.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java index 1551231cfaf..5465e4dd569 100644 --- a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java @@ -195,7 +195,6 @@ public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter f * @since 2.12.0 * @deprecated Use {@link #builder()}. */ - @SuppressWarnings("deprecation") @Deprecated public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter, final IOBiFunction visitFileFailed) { From 90c9d3936d5169637f6aa3be0cf5900211620612 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 25 Dec 2025 07:29:52 -0500 Subject: [PATCH 109/174] Fix deprecation comments and end sentence with a period - Add missing comment. - Close HTML tags. - Typos --- .../org/apache/commons/io/ByteOrderMark.java | 24 +- .../apache/commons/io/ByteOrderParser.java | 4 +- .../java/org/apache/commons/io/Charsets.java | 4 +- .../java/org/apache/commons/io/CopyUtils.java | 84 ++-- .../apache/commons/io/DirectoryWalker.java | 124 +++--- .../org/apache/commons/io/EndianUtils.java | 202 ++++----- .../org/apache/commons/io/FileCleaner.java | 32 +- .../commons/io/FileCleaningTracker.java | 62 +-- .../apache/commons/io/FileDeleteStrategy.java | 28 +- .../commons/io/FileExistsException.java | 4 +- .../org/apache/commons/io/FileSystem.java | 18 +- .../apache/commons/io/FileSystemUtils.java | 22 +- .../java/org/apache/commons/io/FileUtils.java | 394 +++++++++--------- .../org/apache/commons/io/FilenameUtils.java | 230 +++++----- .../java/org/apache/commons/io/HexDump.java | 46 +- .../java/org/apache/commons/io/IOCase.java | 8 +- .../apache/commons/io/IOExceptionList.java | 2 +- .../commons/io/IOExceptionWithCause.java | 4 +- .../apache/commons/io/IORandomAccessFile.java | 4 +- .../java/org/apache/commons/io/IOUtils.java | 24 +- .../org/apache/commons/io/LineIterator.java | 22 +- .../commons/io/RandomAccessFileMode.java | 16 +- .../apache/commons/io/TaggedIOException.java | 18 +- .../org/apache/commons/io/ThreadMonitor.java | 2 +- .../commons/io/build/AbstractOrigin.java | 10 +- .../io/build/AbstractStreamBuilder.java | 14 +- .../ByteArraySeekableByteChannel.java | 2 +- .../commons/io/channels/FileChannels.java | 2 +- .../comparator/CompositeFileComparator.java | 10 +- .../io/comparator/DefaultFileComparator.java | 4 +- .../comparator/ExtensionFileComparator.java | 8 +- .../io/comparator/NameFileComparator.java | 8 +- .../io/comparator/PathFileComparator.java | 8 +- .../io/comparator/SizeFileComparator.java | 6 +- .../io/file/AccumulatorPathVisitor.java | 12 +- .../commons/io/file/CopyDirectoryVisitor.java | 8 +- .../org/apache/commons/io/file/Counters.java | 2 +- .../apache/commons/io/file/PathFilter.java | 2 +- .../org/apache/commons/io/file/PathUtils.java | 26 +- .../commons/io/file/attribute/FileTimes.java | 2 +- .../io/file/spi/FileSystemProviders.java | 6 +- .../io/filefilter/AbstractFileFilter.java | 12 +- .../commons/io/filefilter/AgeFileFilter.java | 18 +- .../commons/io/filefilter/AndFileFilter.java | 8 +- .../io/filefilter/CanWriteFileFilter.java | 4 +- .../io/filefilter/ConditionalFileFilter.java | 10 +- .../io/filefilter/DelegateFileFilter.java | 16 +- .../io/filefilter/DirectoryFileFilter.java | 8 +- .../io/filefilter/EmptyFileFilter.java | 4 +- .../io/filefilter/FalseFileFilter.java | 14 +- .../commons/io/filefilter/FileFileFilter.java | 8 +- .../io/filefilter/FileFilterUtils.java | 134 +++--- .../io/filefilter/HiddenFileFilter.java | 4 +- .../commons/io/filefilter/NameFileFilter.java | 50 +-- .../commons/io/filefilter/NotFileFilter.java | 20 +- .../commons/io/filefilter/OrFileFilter.java | 8 +- .../io/filefilter/PrefixFileFilter.java | 50 +-- .../io/filefilter/RegexFileFilter.java | 24 +- .../commons/io/filefilter/SizeFileFilter.java | 20 +- .../io/filefilter/SuffixFileFilter.java | 50 +-- .../io/filefilter/SymbolicLinkFileFilter.java | 6 +- .../commons/io/filefilter/TrueFileFilter.java | 14 +- .../io/filefilter/WildcardFileFilter.java | 66 +-- .../commons/io/filefilter/WildcardFilter.java | 28 +- .../commons/io/function/IOBiConsumer.java | 18 +- .../commons/io/function/IOBiFunction.java | 20 +- .../commons/io/function/IOBinaryOperator.java | 12 +- .../io/function/IOBooleanSupplier.java | 2 +- .../commons/io/function/IOComparator.java | 4 +- .../commons/io/function/IOConsumer.java | 8 +- .../commons/io/function/IOFunction.java | 64 +-- .../commons/io/function/IOIntConsumer.java | 8 +- .../commons/io/function/IOIntSupplier.java | 2 +- .../commons/io/function/IOIterator.java | 10 +- .../commons/io/function/IOLongSupplier.java | 2 +- .../commons/io/function/IOPredicate.java | 24 +- .../commons/io/function/IOQuadFunction.java | 28 +- .../commons/io/function/IOSpliterator.java | 18 +- .../apache/commons/io/function/IOStream.java | 8 +- .../commons/io/function/IOTriConsumer.java | 24 +- .../commons/io/function/IOTriFunction.java | 24 +- .../io/function/UncheckedIOIterable.java | 2 +- .../io/function/UncheckedIOIterator.java | 2 +- .../input/AbstractCharacterFilterReader.java | 2 +- .../io/input/AutoCloseInputStream.java | 10 +- .../commons/io/input/BOMInputStream.java | 70 ++-- .../commons/io/input/BoundedReader.java | 24 +- .../input/BufferedFileChannelInputStream.java | 10 +- .../commons/io/input/CharSequenceReader.java | 26 +- .../input/ClassLoaderObjectInputStream.java | 24 +- .../io/input/CloseShieldInputStream.java | 6 +- .../commons/io/input/CloseShieldReader.java | 6 +- .../commons/io/input/CountingInputStream.java | 20 +- .../commons/io/input/DemuxInputStream.java | 10 +- .../io/input/MarkShieldInputStream.java | 2 +- .../MessageDigestCalculatingInputStream.java | 12 +- .../io/input/MessageDigestInputStream.java | 4 +- .../commons/io/input/NullInputStream.java | 2 +- .../apache/commons/io/input/NullReader.java | 4 +- .../io/input/ObservableInputStream.java | 4 +- .../apache/commons/io/input/ProxyReader.java | 42 +- .../commons/io/input/ReaderInputStream.java | 36 +- .../io/input/ReversedLinesFileReader.java | 46 +- .../commons/io/input/SequenceReader.java | 4 +- .../io/input/SwappedDataInputStream.java | 76 ++-- .../commons/io/input/TaggedInputStream.java | 12 +- .../apache/commons/io/input/TaggedReader.java | 12 +- .../org/apache/commons/io/input/Tailer.java | 34 +- .../commons/io/input/TeeInputStream.java | 32 +- .../apache/commons/io/input/TeeReader.java | 38 +- .../io/input/ThrottledInputStream.java | 4 +- .../io/input/UncheckedFilterInputStream.java | 2 +- .../io/input/UnixLineEndingInputStream.java | 6 +- .../input/UnsupportedOperationExceptions.java | 8 +- .../input/UnsynchronizedBufferedReader.java | 8 +- .../UnsynchronizedByteArrayInputStream.java | 16 +- .../commons/io/input/XmlStreamReader.java | 70 ++-- .../buffer/CircularBufferInputStream.java | 4 +- .../io/input/buffer/CircularByteBuffer.java | 20 +- .../io/input/buffer/PeekableInputStream.java | 14 +- .../io/monitor/FileAlterationListener.java | 16 +- .../FileAlterationListenerAdaptor.java | 16 +- .../io/monitor/FileAlterationMonitor.java | 14 +- .../io/monitor/FileAlterationObserver.java | 4 +- .../apache/commons/io/monitor/FileEntry.java | 36 +- .../output/AbstractByteArrayOutputStream.java | 6 +- .../io/output/AppendableOutputStream.java | 6 +- .../commons/io/output/AppendableWriter.java | 8 +- .../io/output/ByteArrayOutputStream.java | 4 +- .../io/output/ChunkedOutputStream.java | 2 +- .../io/output/CloseShieldOutputStream.java | 2 +- .../commons/io/output/ClosedOutputStream.java | 2 +- .../commons/io/output/ClosedWriter.java | 2 +- .../apache/commons/io/output/NullWriter.java | 2 +- .../apache/commons/io/output/ProxyWriter.java | 4 +- .../commons/io/output/TeeOutputStream.java | 4 +- .../commons/io/output/WriterOutputStream.java | 2 +- .../io/serialization/ClassNameMatcher.java | 4 +- .../serialization/FullClassNameMatcher.java | 2 +- .../ObjectStreamClassPredicate.java | 10 +- .../serialization/RegexpClassNameMatcher.java | 6 +- .../ValidatingObjectInputStream.java | 16 +- .../commons/io/FileUtilsCopyToFileTest.java | 4 +- .../io/FileUtilsDirectoryContainsTest.java | 5 +- .../commons/io/FileUtilsFileNewerTest.java | 10 +- .../org/apache/commons/io/IOUtilsTest.java | 4 +- .../apache/commons/io/LineIteratorTest.java | 20 +- .../apache/commons/io/file/TempDirectory.java | 4 +- .../org/apache/commons/io/file/TempFile.java | 4 +- .../io/filefilter/RegexFileFilterTest.java | 2 +- .../SymbolicLinkFileFilterTest.java | 2 +- .../commons/io/function/IOBiFunctionTest.java | 4 +- .../io/function/IOQuadFunctionTest.java | 4 +- .../commons/io/function/IORunnableTest.java | 2 +- .../io/function/IOTriFunctionTest.java | 4 +- .../commons/io/function/UncheckTest.java | 2 +- .../commons/io/input/XmlStreamReaderTest.java | 12 +- .../input/compatibility/XmlStreamReader.java | 2 +- .../io/monitor/AbstractMonitorTest.java | 24 +- .../io/monitor/CollectionFileListener.java | 28 +- .../io/monitor/FileAlterationMonitorTest.java | 7 +- .../io/output/ChunkedOutputStreamTest.java | 4 +- .../output/DeferredFileOutputStreamTest.java | 17 +- .../AbstractCloseableListTest.java | 2 +- .../org/apache/commons/io/test/TestUtils.java | 24 +- .../ThrowOnFlushAndCloseOutputStream.java | 4 +- 166 files changed, 1728 insertions(+), 1719 deletions(-) diff --git a/src/main/java/org/apache/commons/io/ByteOrderMark.java b/src/main/java/org/apache/commons/io/ByteOrderMark.java index 9624a0ba8b4..b9209cb316f 100644 --- a/src/main/java/org/apache/commons/io/ByteOrderMark.java +++ b/src/main/java/org/apache/commons/io/ByteOrderMark.java @@ -128,10 +128,10 @@ public class ByteOrderMark implements Serializable { /** * Constructs a new instance. * - * @param charsetName The name of the charset the BOM represents - * @param bytes The BOM's bytes - * @throws IllegalArgumentException if the charsetName is zero length - * @throws IllegalArgumentException if the bytes are zero length + * @param charsetName The name of the charset the BOM represents. + * @param bytes The BOM's bytes. + * @throws IllegalArgumentException if the charsetName is zero length. + * @throws IllegalArgumentException if the bytes are zero length. */ public ByteOrderMark(final String charsetName, final int... bytes) { Objects.requireNonNull(charsetName, "charsetName"); @@ -149,9 +149,9 @@ public ByteOrderMark(final String charsetName, final int... bytes) { /** * Indicates if this instance's bytes equals another. * - * @param obj The object to compare to + * @param obj The object to compare to. * @return true if the bom's bytes are equal, otherwise - * false + * false. */ @Override public boolean equals(final Object obj) { @@ -173,8 +173,8 @@ public boolean equals(final Object obj) { /** * Gets the byte at the specified position. * - * @param pos The position - * @return The specified byte + * @param pos The position. + * @return The specified byte. */ public int get(final int pos) { return bytes[pos]; @@ -183,7 +183,7 @@ public int get(final int pos) { /** * Gets a copy of the BOM's bytes. * - * @return a copy of the BOM's bytes + * @return a copy of the BOM's bytes. */ public byte[] getBytes() { final byte[] copy = IOUtils.byteArray(bytes.length); @@ -196,7 +196,7 @@ public byte[] getBytes() { /** * Gets the name of the {@link java.nio.charset.Charset} the BOM represents. * - * @return the character set name + * @return the character set name. */ public String getCharsetName() { return charsetName; @@ -224,7 +224,7 @@ public int hashCode() { /** * Gets the length of the BOM's bytes. * - * @return the length of the BOM's bytes + * @return the length of the BOM's bytes. */ public int length() { return bytes.length; @@ -260,7 +260,7 @@ public boolean matches(final int[] test) { /** * Converts this instance to a String representation of the BOM. * - * @return the length of the BOM's bytes + * @return the length of the BOM's bytes. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/ByteOrderParser.java b/src/main/java/org/apache/commons/io/ByteOrderParser.java index 33a263e4966..6684c04c23f 100644 --- a/src/main/java/org/apache/commons/io/ByteOrderParser.java +++ b/src/main/java/org/apache/commons/io/ByteOrderParser.java @@ -41,8 +41,8 @@ public final class ByteOrderParser { *

    * * @param value - * the {@link String} containing the ByteOrder representation to be parsed - * @return the ByteOrder represented by the string argument + * the {@link String} containing the ByteOrder representation to be parsed. + * @return the ByteOrder represented by the string argument. * @throws IllegalArgumentException * if the {@link String} containing the ByteOrder representation to be parsed is unknown. */ diff --git a/src/main/java/org/apache/commons/io/Charsets.java b/src/main/java/org/apache/commons/io/Charsets.java index ef6a6264f77..cd5454f5834 100644 --- a/src/main/java/org/apache/commons/io/Charsets.java +++ b/src/main/java/org/apache/commons/io/Charsets.java @@ -210,7 +210,7 @@ public static SortedMap requiredCharsets() { * * @param charset * A charset or null. - * @return the given Charset or the default Charset if the given Charset is null + * @return the given Charset or the default Charset if the given Charset is null. * @see Charset#defaultCharset() */ public static Charset toCharset(final Charset charset) { @@ -277,7 +277,7 @@ public static Charset toCharsetDefault(final String charsetName, final Charset d /** * Construct a new instance. * - * @deprecated Will be private in 4.0 + * @deprecated Will be private in 3.0. */ @Deprecated public Charsets() { diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index bb9ac470c75..1c88614a213 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -117,9 +117,9 @@ public class CopyUtils { /** * Copies bytes from a {@code byte[]} to an {@link OutputStream}. - * @param input the byte array to read from - * @param output the {@link OutputStream} to write to - * @throws IOException In case of an I/O problem + * @param input the byte array to read from. + * @param output the {@link OutputStream} to write to. + * @throws IOException In case of an I/O problem. */ public static void copy(final byte[] input, final OutputStream output) throws IOException { output.write(input); @@ -130,10 +130,10 @@ public static void copy(final byte[] input, final OutputStream output) throws IO * {@link Writer}. * The platform's default encoding is used for the byte-to-char conversion. * - * @param input the byte array to read from - * @param output the {@link Writer} to write to - * @throws IOException In case of an I/O problem - * @deprecated Use {@link #copy(byte[], Writer, String)} instead + * @param input the byte array to read from. + * @param output the {@link Writer} to write to. + * @throws IOException In case of an I/O problem. + * @deprecated Use {@link #copy(byte[], Writer, String)} instead. */ @Deprecated public static void copy(final byte[] input, final Writer output) throws IOException { @@ -145,12 +145,12 @@ public static void copy(final byte[] input, final Writer output) throws IOExcept * Copies and convert bytes from a {@code byte[]} to chars on a * {@link Writer}, using the specified encoding. * - * @param input the byte array to read from - * @param output the {@link Writer} to write to + * @param input the byte array to read from. + * @param output the {@link Writer} to write to. * @param encoding The name of a supported character encoding. See the * IANA * Charset Registry for a list of valid encoding types. - * @throws IOException In case of an I/O problem + * @throws IOException In case of an I/O problem. */ public static void copy(final byte[] input, final Writer output, final String encoding) throws IOException { final ByteArrayInputStream inputStream = new ByteArrayInputStream(input); @@ -161,10 +161,10 @@ public static void copy(final byte[] input, final Writer output, final String en * Copies bytes from an {@link InputStream} to an * {@link OutputStream}. * - * @param input the {@link InputStream} to read from - * @param output the {@link OutputStream} to write to - * @return the number of bytes copied - * @throws IOException In case of an I/O problem + * @param input the {@link InputStream} to read from. + * @param output the {@link OutputStream} to write to. + * @return the number of bytes copied. + * @throws IOException In case of an I/O problem. */ public static int copy(final InputStream input, final OutputStream output) throws IOException { final byte[] buffer = IOUtils.byteArray(); @@ -184,10 +184,10 @@ public static int copy(final InputStream input, final OutputStream output) throw * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

    * - * @param input the {@link InputStream} to read from - * @param output the {@link Writer} to write to - * @throws IOException In case of an I/O problem - * @deprecated Use {@link #copy(InputStream, Writer, String)} instead + * @param input the {@link InputStream} to read from. + * @param output the {@link Writer} to write to. + * @throws IOException In case of an I/O problem. + * @deprecated Use {@link #copy(InputStream, Writer, String)} instead. */ @Deprecated public static void copy( @@ -203,12 +203,12 @@ public static void copy( * Copies and convert bytes from an {@link InputStream} to chars on a * {@link Writer}, using the specified encoding. * - * @param input the {@link InputStream} to read from - * @param output the {@link Writer} to write to + * @param input the {@link InputStream} to read from. + * @param output the {@link Writer} to write to. * @param encoding The name of a supported character encoding. See the * IANA * Charset Registry for a list of valid encoding types. - * @throws IOException In case of an I/O problem + * @throws IOException In case of an I/O problem. */ public static void copy( final InputStream input, @@ -226,10 +226,10 @@ public static void copy( * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

    * - * @param input the {@link Reader} to read from - * @param output the {@link OutputStream} to write to - * @throws IOException In case of an I/O problem - * @deprecated Use {@link #copy(Reader, OutputStream, String)} instead + * @param input the {@link Reader} to read from. + * @param output the {@link OutputStream} to write to. + * @throws IOException In case of an I/O problem. + * @deprecated Use {@link #copy(Reader, OutputStream, String)} instead. */ @Deprecated public static void copy( @@ -248,12 +248,12 @@ public static void copy( * Serialize chars from a {@link Reader} to bytes on an * {@link OutputStream}, and flush the {@link OutputStream}. * - * @param input the {@link Reader} to read from - * @param output the {@link OutputStream} to write to + * @param input the {@link Reader} to read from. + * @param output the {@link OutputStream} to write to. * @param encoding The name of a supported character encoding. See the * IANA * Charset Registry for a list of valid encoding types. - * @throws IOException In case of an I/O problem + * @throws IOException In case of an I/O problem. * @since 2.5 */ public static void copy( @@ -271,10 +271,10 @@ public static void copy( /** * Copies chars from a {@link Reader} to a {@link Writer}. * - * @param input the {@link Reader} to read from - * @param output the {@link Writer} to write to - * @return the number of characters copied - * @throws IOException In case of an I/O problem + * @param input the {@link Reader} to read from. + * @param output the {@link Writer} to write to. + * @return the number of characters copied. + * @throws IOException In case of an I/O problem. */ public static int copy( final Reader input, @@ -300,10 +300,10 @@ public static int copy( * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset} for byte-to-char conversion. *

    * - * @param input the {@link String} to read from - * @param output the {@link OutputStream} to write to - * @throws IOException In case of an I/O problem - * @deprecated Use {@link #copy(String, OutputStream, String)} instead + * @param input the {@link String} to read from. + * @param output the {@link OutputStream} to write to. + * @throws IOException In case of an I/O problem. + * @deprecated Use {@link #copy(String, OutputStream, String)} instead. */ @Deprecated public static void copy( @@ -324,12 +324,12 @@ public static void copy( * {@link OutputStream}, and * flush the {@link OutputStream}. * - * @param input the {@link String} to read from - * @param output the {@link OutputStream} to write to + * @param input the {@link String} to read from. + * @param output the {@link OutputStream} to write to. * @param encoding The name of a supported character encoding. See the * IANA * Charset Registry for a list of valid encoding types. - * @throws IOException In case of an I/O problem + * @throws IOException In case of an I/O problem. * @since 2.5 */ public static void copy( @@ -348,9 +348,9 @@ public static void copy( /** * Copies chars from a {@link String} to a {@link Writer}. * - * @param input the {@link String} to read from - * @param output the {@link Writer} to write to - * @throws IOException In case of an I/O problem + * @param input the {@link String} to read from. + * @param output the {@link Writer} to write to. + * @throws IOException In case of an I/O problem. */ public static void copy(final String input, final Writer output) throws IOException { diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java index 23f5f14f2a8..1bc9d44b030 100644 --- a/src/main/java/org/apache/commons/io/DirectoryWalker.java +++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java @@ -272,8 +272,8 @@ public static class CancelException extends IOException { * Constructs a {@link CancelException} with * the file and depth when cancellation occurred. * - * @param file the file when the operation was cancelled, may be null - * @param depth the depth when the operation was cancelled, may be null + * @param file the file when the operation was cancelled, may be null. + * @param depth the depth when the operation was cancelled, may be null. */ public CancelException(final File file, final int depth) { this("Operation Cancelled", file, depth); @@ -284,9 +284,9 @@ public CancelException(final File file, final int depth) { * an appropriate message and the file and depth when * cancellation occurred. * - * @param message the detail message - * @param file the file when the operation was cancelled - * @param depth the depth when the operation was cancelled + * @param message the detail message. + * @param file the file when the operation was cancelled. + * @param depth the depth when the operation was cancelled. */ public CancelException(final String message, final File file, final int depth) { super(message); @@ -297,7 +297,7 @@ public CancelException(final String message, final File file, final int depth) { /** * Returns the depth when the operation was cancelled. * - * @return the depth when the operation was cancelled + * @return the depth when the operation was cancelled. */ public int getDepth() { return depth; @@ -306,7 +306,7 @@ public int getDepth() { /** * Returns the file when the operation was cancelled. * - * @return the file when the operation was cancelled + * @return the file when the operation was cancelled. */ public File getFile() { return file; @@ -338,9 +338,9 @@ protected DirectoryWalker() { * filtering should occur and all files and directories will be visited. *

    * - * @param filter the filter to apply, null means visit all files + * @param filter the filter to apply, null means visit all files. * @param depthLimit controls how deep the hierarchy is - * navigated to (less than 0 means unlimited) + * navigated to (less than 0 means unlimited). */ protected DirectoryWalker(final FileFilter filter, final int depthLimit) { this.filter = filter; @@ -357,10 +357,10 @@ protected DirectoryWalker(final FileFilter filter, final int depthLimit) { * A {@code null} filter means that no filtering should occur. *

    * - * @param directoryFilter the filter to apply to directories, null means visit all directories - * @param fileFilter the filter to apply to files, null means visit all files + * @param directoryFilter the filter to apply to directories, null means visit all directories. + * @param fileFilter the filter to apply to files, null means visit all files. * @param depthLimit controls how deep the hierarchy is - * navigated to (less than 0 means unlimited) + * navigated to (less than 0 means unlimited). */ protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, final int depthLimit) { if (directoryFilter == null && fileFilter == null) { @@ -385,10 +385,10 @@ protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter, * you may wish to check for cancellation by calling this method. *

    * - * @param file the current file being processed - * @param depth the current file level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param file the current file being processed. + * @param depth the current file level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ protected final void checkIfCancelled(final File file, final int depth, final Collection results) throws IOException { @@ -403,11 +403,11 @@ protected final void checkIfCancelled(final File file, final int depth, final Co * This implementation returns the files unchanged *

    * - * @param directory the current directory being processed - * @param depth the current directory level (starting directory = 0) + * @param directory the current directory being processed. + * @param depth the current directory level (starting directory = 0). * @param files the files (possibly filtered) in the directory, may be {@code null} - * @return the filtered list of files - * @throws IOException if an I/O Error occurs + * @return the filtered list of files. + * @throws IOException if an I/O Error occurs. * @since 2.0 */ @SuppressWarnings("unused") // Possibly thrown from subclasses. @@ -424,11 +424,11 @@ protected File[] filterDirectoryContents(final File directory, final int depth, * This implementation just re-throws the {@link CancelException}. *

    * - * @param startDirectory the directory that the walk started from - * @param results the collection of result objects, may be updated + * @param startDirectory the directory that the walk started from. + * @param results the collection of result objects, may be updated. * @param cancel the exception throw to cancel further processing * containing details at the point of cancellation. - * @throws IOException if an I/O Error occurs + * @throws IOException if an I/O Error occurs. */ protected void handleCancelled(final File startDirectory, final Collection results, final CancelException cancel) throws IOException { @@ -447,11 +447,11 @@ protected void handleCancelled(final File startDirectory, final Collection re * This implementation does nothing and returns true. *

    * - * @param directory the current directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @return true to process this directory, false to skip this directory - * @throws IOException if an I/O Error occurs + * @param directory the current directory being processed. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @return true to process this directory, false to skip this directory. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected boolean handleDirectory(final File directory, final int depth, final Collection results) throws @@ -466,10 +466,10 @@ protected boolean handleDirectory(final File directory, final int depth, final C * This implementation does nothing. *

    * - * @param directory the directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param directory the directory being processed. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws @@ -483,10 +483,10 @@ protected void handleDirectoryEnd(final File directory, final int depth, final C * This implementation does nothing. *

    * - * @param directory the current directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param directory the current directory being processed. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleDirectoryStart(final File directory, final int depth, final Collection results) throws @@ -500,8 +500,8 @@ protected void handleDirectoryStart(final File directory, final int depth, final * This implementation does nothing. *

    * - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleEnd(final Collection results) throws IOException { @@ -514,10 +514,10 @@ protected void handleEnd(final Collection results) throws IOException { * This implementation does nothing. *

    * - * @param file the current file being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param file the current file being processed. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleFile(final File file, final int depth, final Collection results) throws IOException { @@ -556,11 +556,11 @@ protected void handleFile(final File file, final int depth, final Collection * This implementation returns false. *

    * - * @param file the file or directory being processed - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @return true if the walk has been cancelled - * @throws IOException if an I/O Error occurs + * @param file the file or directory being processed. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @return true if the walk has been cancelled. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected boolean handleIsCancelled( @@ -575,10 +575,10 @@ protected boolean handleIsCancelled( * This implementation does nothing. *

    * - * @param directory the restricted directory - * @param depth the current directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param directory the restricted directory. + * @param depth the current directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleRestricted(final File directory, final int depth, final Collection results) throws @@ -592,9 +592,9 @@ protected void handleRestricted(final File directory, final int depth, final Col * This implementation does nothing. *

    * - * @param startDirectory the directory to start from - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param startDirectory the directory to start from. + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected void handleStart(final File startDirectory, final Collection results) throws IOException { @@ -613,10 +613,10 @@ protected void handleStart(final File startDirectory, final Collection result * The event methods have the prefix {@code handle}. *

    * - * @param startDirectory the directory to start from, not null - * @param results the collection of result objects, may be updated - * @throws NullPointerException if the start directory is null - * @throws IOException if an I/O Error occurs + * @param startDirectory the directory to start from, not null. + * @param results the collection of result objects, may be updated. + * @throws NullPointerException if the start directory is null. + * @throws IOException if an I/O Error occurs. */ protected final void walk(final File startDirectory, final Collection results) throws IOException { Objects.requireNonNull(startDirectory, "startDirectory"); @@ -632,10 +632,10 @@ protected final void walk(final File startDirectory, final Collection results /** * Main recursive method to examine the directory hierarchy. * - * @param directory the directory to examine, not null - * @param depth the directory level (starting directory = 0) - * @param results the collection of result objects, may be updated - * @throws IOException if an I/O Error occurs + * @param directory the directory to examine, not null. + * @param depth the directory level (starting directory = 0). + * @param results the collection of result objects, may be updated. + * @throws IOException if an I/O Error occurs. */ private void walk(final File directory, final int depth, final Collection results) throws IOException { checkIfCancelled(directory, depth, results); diff --git a/src/main/java/org/apache/commons/io/EndianUtils.java b/src/main/java/org/apache/commons/io/EndianUtils.java index 6b4d58eeba3..0306a661acc 100644 --- a/src/main/java/org/apache/commons/io/EndianUtils.java +++ b/src/main/java/org/apache/commons/io/EndianUtils.java @@ -50,9 +50,9 @@ public class EndianUtils { /** * Reads the next byte from the input stream. - * @param input the stream - * @return the byte - * @throws IOException if the end of file is reached + * @param input the stream. + * @return the byte. + * @throws IOException if the end of file is reached. */ private static int read(final InputStream input) throws IOException { final int value = input.read(); @@ -65,10 +65,10 @@ private static int read(final InputStream input) throws IOException { /** * Reads a little-endian {@code double} value from a byte array at a given offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes. */ public static double readSwappedDouble(final byte[] data, final int offset) { return Double.longBitsToDouble(readSwappedLong(data, offset)); @@ -77,9 +77,9 @@ public static double readSwappedDouble(final byte[] data, final int offset) { /** * Reads a little-endian {@code double} value from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static double readSwappedDouble(final InputStream input) throws IOException { return Double.longBitsToDouble(readSwappedLong(input)); @@ -88,10 +88,10 @@ public static double readSwappedDouble(final InputStream input) throws IOExcepti /** * Reads a little-endian {@code float} value from a byte array at a given offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes. */ public static float readSwappedFloat(final byte[] data, final int offset) { return Float.intBitsToFloat(readSwappedInteger(data, offset)); @@ -100,9 +100,9 @@ public static float readSwappedFloat(final byte[] data, final int offset) { /** * Reads a little-endian {@code float} value from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static float readSwappedFloat(final InputStream input) throws IOException { return Float.intBitsToFloat(readSwappedInteger(input)); @@ -111,10 +111,10 @@ public static float readSwappedFloat(final InputStream input) throws IOException /** * Reads a little-endian {@code int} value from a byte array at a given offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes. */ public static int readSwappedInteger(final byte[] data, final int offset) { validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE); @@ -127,9 +127,9 @@ public static int readSwappedInteger(final byte[] data, final int offset) { /** * Reads a little-endian {@code int} value from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static int readSwappedInteger(final InputStream input) throws IOException { final int value1 = read(input); @@ -142,10 +142,10 @@ public static int readSwappedInteger(final InputStream input) throws IOException /** * Reads a little-endian {@code long} value from a byte array at a given offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes. */ public static long readSwappedLong(final byte[] data, final int offset) { validateByteArrayOffset(data, offset, Long.SIZE / Byte.SIZE); @@ -157,9 +157,9 @@ public static long readSwappedLong(final byte[] data, final int offset) { /** * Reads a little-endian {@code long} value from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static long readSwappedLong(final InputStream input) throws IOException { final byte[] bytes = new byte[8]; @@ -172,10 +172,10 @@ public static long readSwappedLong(final InputStream input) throws IOException { /** * Reads a little-endian {@code short} value from a byte array at a given offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes. */ public static short readSwappedShort(final byte[] data, final int offset) { validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE); @@ -185,9 +185,9 @@ public static short readSwappedShort(final byte[] data, final int offset) { /** * Reads a little-endian {@code short} value from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static short readSwappedShort(final InputStream input) throws IOException { return (short) (((read(input) & 0xff) << 0) + ((read(input) & 0xff) << 8)); @@ -197,10 +197,10 @@ public static short readSwappedShort(final InputStream input) throws IOException * Reads a little-endian unsigned integer (32-bit) value from a byte array at a given * offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes. */ public static long readSwappedUnsignedInteger(final byte[] data, final int offset) { validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE); @@ -214,9 +214,9 @@ public static long readSwappedUnsignedInteger(final byte[] data, final int offse /** * Reads a little-endian unsigned integer (32-bit) from an InputStream. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static long readSwappedUnsignedInteger(final InputStream input) throws IOException { final int value1 = read(input); @@ -232,10 +232,10 @@ public static long readSwappedUnsignedInteger(final InputStream input) throws IO * Reads an unsigned short (16-bit) value from a byte array in little-endian order at a given * offset. * - * @param data source byte array - * @param offset starting offset in the byte array - * @return the value read - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes + * @param data source byte array. + * @param offset starting offset in the byte array. + * @return the value read. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes. */ public static int readSwappedUnsignedShort(final byte[] data, final int offset) { validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE); @@ -245,9 +245,9 @@ public static int readSwappedUnsignedShort(final byte[] data, final int offset) /** * Reads an unsigned short (16-bit) from an InputStream in little-endian order. * - * @param input source InputStream - * @return the value just read - * @throws IOException in case of an I/O problem + * @param input source InputStream. + * @return the value just read. + * @throws IOException in case of an I/O problem. */ public static int readSwappedUnsignedShort(final InputStream input) throws IOException { final int value1 = read(input); @@ -263,8 +263,8 @@ public static int readSwappedUnsignedShort(final InputStream input) throws IOExc * This can be useful if you have a number that was read from the * underlying source in the wrong endianness. * - * @param value value to convert - * @return the converted value + * @param value value to convert. + * @return the converted value. */ public static double swapDouble(final double value) { return Double.longBitsToDouble(swapLong(Double.doubleToLongBits(value))); @@ -273,8 +273,8 @@ public static double swapDouble(final double value) { /** * Converts a {@code float} value from big-endian to little-endian and vice versa. * - * @param value value to convert - * @return the converted value + * @param value value to convert. + * @return the converted value. */ public static float swapFloat(final float value) { return Float.intBitsToFloat(swapInteger(Float.floatToIntBits(value))); @@ -283,8 +283,8 @@ public static float swapFloat(final float value) { /** * Converts an {@code int} value from big-endian to little-endian and vice versa. * - * @param value value to convert - * @return the converted value + * @param value value to convert. + * @return the converted value. */ public static int swapInteger(final int value) { return @@ -297,8 +297,8 @@ public static int swapInteger(final int value) { /** * Converts a {@code long} value from big-endian to little-endian and vice versa. * - * @param value value to convert - * @return the converted value + * @param value value to convert. + * @return the converted value. */ public static long swapLong(final long value) { return @@ -315,8 +315,8 @@ public static long swapLong(final long value) { /** * Converts a {@code short} value from big-endian to little-endian and vice versa. * - * @param value value to convert - * @return the converted value + * @param value value to convert. + * @return the converted value. */ public static short swapShort(final short value) { return (short) (((value >> 0 & 0xff) << 8) + @@ -326,10 +326,10 @@ public static short swapShort(final short value) { /** * Validates if the provided byte array has enough data. * - * @param data the input byte array - * @param offset the input offset - * @param byteNeeded the needed number of bytes - * @throws IllegalArgumentException if the byte array does not have enough data + * @param data the input byte array. + * @param offset the input offset. + * @param byteNeeded the needed number of bytes. + * @throws IllegalArgumentException if the byte array does not have enough data. */ private static void validateByteArrayOffset(final byte[] data, final int offset, final int byteNeeded) { if (data.length < offset + byteNeeded) { @@ -340,10 +340,10 @@ private static void validateByteArrayOffset(final byte[] data, final int offset, /** * Writes the 8 bytes of a {@code double} to a byte array at a given offset in little-endian order. * - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes + * @param data target byte array. + * @param offset starting offset in the byte array. + * @param value value to write. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes. */ public static void writeSwappedDouble(final byte[] data, final int offset, final double value) { writeSwappedLong(data, offset, Double.doubleToLongBits(value)); @@ -352,9 +352,9 @@ public static void writeSwappedDouble(final byte[] data, final int offset, final /** * Writes the 8 bytes of a {@code double} to an output stream in little-endian order. * - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem + * @param output target OutputStream. + * @param value value to write. + * @throws IOException in case of an I/O problem. */ public static void writeSwappedDouble(final OutputStream output, final double value) throws IOException { writeSwappedLong(output, Double.doubleToLongBits(value)); @@ -363,10 +363,10 @@ public static void writeSwappedDouble(final OutputStream output, final double va /** * Writes the 4 bytes of a {@code float} to a byte array at a given offset in little-endian order. * - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes + * @param data target byte array. + * @param offset starting offset in the byte array. + * @param value value to write. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes. */ public static void writeSwappedFloat(final byte[] data, final int offset, final float value) { writeSwappedInteger(data, offset, Float.floatToIntBits(value)); @@ -375,9 +375,9 @@ public static void writeSwappedFloat(final byte[] data, final int offset, final /** * Writes the 4 bytes of a {@code float} to an output stream in little-endian order. * - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem + * @param output target OutputStream. + * @param value value to write. + * @throws IOException in case of an I/O problem. */ public static void writeSwappedFloat(final OutputStream output, final float value) throws IOException { writeSwappedInteger(output, Float.floatToIntBits(value)); @@ -386,10 +386,10 @@ public static void writeSwappedFloat(final OutputStream output, final float valu /** * Writes the 4 bytes of an {@code int} to a byte array at a given offset in little-endian order. * - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes + * @param data target byte array. + * @param offset starting offset in the byte array. + * @param value value to write. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 4 bytes. */ public static void writeSwappedInteger(final byte[] data, final int offset, final int value) { validateByteArrayOffset(data, offset, Integer.SIZE / Byte.SIZE); @@ -402,9 +402,9 @@ public static void writeSwappedInteger(final byte[] data, final int offset, fina /** * Writes the 4 bytes of an {@code int} to an output stream in little-endian order. * - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem + * @param output target OutputStream. + * @param value value to write. + * @throws IOException in case of an I/O problem. */ public static void writeSwappedInteger(final OutputStream output, final int value) throws IOException { output.write((byte) (value >> 0 & 0xff)); @@ -416,10 +416,10 @@ public static void writeSwappedInteger(final OutputStream output, final int valu /** * Writes the 8 bytes of a {@code long} to a byte array at a given offset in little-endian order. * - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes + * @param data target byte array. + * @param offset starting offset in the byte array. + * @param value value to write. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 8 bytes. */ public static void writeSwappedLong(final byte[] data, final int offset, final long value) { validateByteArrayOffset(data, offset, Long.SIZE / Byte.SIZE); @@ -436,9 +436,9 @@ public static void writeSwappedLong(final byte[] data, final int offset, final l /** * Writes the 8 bytes of a {@code long} to an output stream in little-endian order. * - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem + * @param output target OutputStream. + * @param value value to write. + * @throws IOException in case of an I/O problem. */ public static void writeSwappedLong(final OutputStream output, final long value) throws IOException { output.write((byte) (value >> 0 & 0xff)); @@ -454,10 +454,10 @@ public static void writeSwappedLong(final OutputStream output, final long value) /** * Writes the 2 bytes of a {@code short} to a byte array at a given offset in little-endian order. * - * @param data target byte array - * @param offset starting offset in the byte array - * @param value value to write - * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes + * @param data target byte array. + * @param offset starting offset in the byte array. + * @param value value to write. + * @throws IllegalArgumentException if the part of the byte array starting at offset does not have at least 2 bytes. */ public static void writeSwappedShort(final byte[] data, final int offset, final short value) { validateByteArrayOffset(data, offset, Short.SIZE / Byte.SIZE); @@ -468,9 +468,9 @@ public static void writeSwappedShort(final byte[] data, final int offset, final /** * Writes the 2 bytes of a {@code short} to an output stream using little-endian encoding. * - * @param output target OutputStream - * @param value value to write - * @throws IOException in case of an I/O problem + * @param output target OutputStream. + * @param value value to write. + * @throws IOException in case of an I/O problem. */ public static void writeSwappedShort(final OutputStream output, final short value) throws IOException { output.write((byte) (value >> 0 & 0xff)); diff --git a/src/main/java/org/apache/commons/io/FileCleaner.java b/src/main/java/org/apache/commons/io/FileCleaner.java index 5ffdd7db219..e874f91f903 100644 --- a/src/main/java/org/apache/commons/io/FileCleaner.java +++ b/src/main/java/org/apache/commons/io/FileCleaner.java @@ -76,7 +76,7 @@ public static synchronized void exitWhenFinished() { * {@link FileCleaningTracker} class while maintain compatibility with the * deprecated {@link FileCleaner}. * - * @return the singleton instance + * @return the singleton instance. */ public static FileCleaningTracker getInstance() { return INSTANCE; @@ -86,7 +86,7 @@ public static FileCleaningTracker getInstance() { * Gets the number of files currently being tracked, and therefore * awaiting deletion. * - * @return the number of files being tracked + * @return the number of files being tracked. * @deprecated Use {@link FileCleaningTracker#getTrackCount()}. */ @Deprecated @@ -99,9 +99,9 @@ public static int getTrackCount() { * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @throws NullPointerException if the file is null. * @deprecated Use {@link FileCleaningTracker#track(File, Object)}. */ @Deprecated @@ -114,10 +114,10 @@ public static void track(final File file, final Object marker) { * when the marker instance is garbage collected. * The specified deletion strategy is used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException if the file is null. * @deprecated Use {@link FileCleaningTracker#track(File, Object, FileDeleteStrategy)}. */ @Deprecated @@ -130,9 +130,9 @@ public static void track(final File file, final Object marker, final FileDeleteS * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the path is null + * @param path the full path to the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @throws NullPointerException if the path is null. * @deprecated Use {@link FileCleaningTracker#track(String, Object)}. */ @Deprecated @@ -145,10 +145,10 @@ public static void track(final String path, final Object marker) { * when the marker instance is garbage collected. * The specified deletion strategy is used. * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the path is null + * @param path the full path to the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException if the path is null. * @deprecated Use {@link FileCleaningTracker#track(String, Object, FileDeleteStrategy)}. */ @Deprecated diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index 98edebc518e..5bde044e333 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -99,10 +99,10 @@ private static final class Tracker extends PhantomReference { /** * Constructs an instance of this class from the supplied parameters. * - * @param path the full path to the file to be tracked, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @param marker the marker object used to track the file, not null - * @param queue the queue on to which the tracker will be pushed, not null + * @param path the full path to the file to be tracked, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @param marker the marker object used to track the file, not null. + * @param queue the queue on to which the tracker will be pushed, not null. */ Tracker(final String path, final FileDeleteStrategy deleteStrategy, final Object marker, final ReferenceQueue queue) { @@ -124,7 +124,7 @@ public boolean delete() { /** * Gets the path. * - * @return the path + * @return the path. */ public String getPath() { return path; @@ -166,9 +166,9 @@ public FileCleaningTracker() { /** * Adds a tracker to the list of trackers. * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal + * @param path the full path to the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. */ private synchronized void addTracker(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) { @@ -218,7 +218,7 @@ public synchronized void exitWhenFinished() { /** * Gets a copy of the file paths that failed to delete. * - * @return a copy of the file paths that failed to delete + * @return a copy of the file paths that failed to delete. * @since 2.0 */ public List getDeleteFailures() { @@ -229,7 +229,7 @@ public List getDeleteFailures() { * Gets the number of files currently being tracked, and therefore * awaiting deletion. * - * @return the number of files being tracked + * @return the number of files being tracked. */ public int getTrackCount() { return trackers.size(); @@ -240,9 +240,9 @@ public int getTrackCount() { * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @throws NullPointerException if the file is null. */ public void track(final File file, final Object marker) { track(file, marker, null); @@ -253,10 +253,10 @@ public void track(final File file, final Object marker) { * when the marker instance is garbage collected. * The specified deletion strategy is used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException if the file is null. */ public void track(final File file, final Object marker, final FileDeleteStrategy deleteStrategy) { Objects.requireNonNull(file, "file"); @@ -268,9 +268,9 @@ public void track(final File file, final Object marker, final FileDeleteStrategy * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @throws NullPointerException if the file is null. * @since 2.14.0 */ public void track(final Path file, final Object marker) { @@ -282,10 +282,10 @@ public void track(final Path file, final Object marker) { * when the marker instance is garbage collected. * The specified deletion strategy is used. * - * @param file the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the file is null + * @param file the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException if the file is null. * @since 2.14.0 */ public void track(final Path file, final Object marker, final FileDeleteStrategy deleteStrategy) { @@ -298,9 +298,9 @@ public void track(final Path file, final Object marker, final FileDeleteStrategy * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @throws NullPointerException if the path is null + * @param path the full path to the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @throws NullPointerException if the path is null. */ public void track(final String path, final Object marker) { track(path, marker, null); @@ -311,10 +311,10 @@ public void track(final String path, final Object marker) { * when the marker instance is garbage collected. * The specified deletion strategy is used. * - * @param path the full path to the file to be tracked, not null - * @param marker the marker object used to track the file, not null - * @param deleteStrategy the strategy to delete the file, null means normal - * @throws NullPointerException if the path is null + * @param path the full path to the file to be tracked, not null. + * @param marker the marker object used to track the file, not null. + * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException if the path is null. */ public void track(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) { Objects.requireNonNull(path, "path"); diff --git a/src/main/java/org/apache/commons/io/FileDeleteStrategy.java b/src/main/java/org/apache/commons/io/FileDeleteStrategy.java index 62cf28c1631..9ce7ab2461a 100644 --- a/src/main/java/org/apache/commons/io/FileDeleteStrategy.java +++ b/src/main/java/org/apache/commons/io/FileDeleteStrategy.java @@ -51,10 +51,10 @@ static class ForceFileDeleteStrategy extends FileDeleteStrategy { * if the file exists. *

    * - * @param fileToDelete the file to delete, not null + * @param fileToDelete the file to delete, not null. * @return Always returns {@code true} - * @throws NullPointerException if the file is null - * @throws IOException if an error occurs during file deletion + * @throws NullPointerException if the file is null. + * @throws IOException if an error occurs during file deletion. */ @Override protected boolean doDelete(final File fileToDelete) throws IOException { @@ -81,7 +81,7 @@ protected boolean doDelete(final File fileToDelete) throws IOException { /** * Restricted constructor. * - * @param name the name by which the strategy is known + * @param name the name by which the strategy is known. */ protected FileDeleteStrategy(final String name) { this.name = name; @@ -94,9 +94,9 @@ protected FileDeleteStrategy(final String name) { * Subclass writers should override {@link #doDelete(File)}, not this method. *

    * - * @param fileToDelete the file to delete, not null - * @throws NullPointerException if the file is null - * @throws IOException if an error occurs during file deletion + * @param fileToDelete the file to delete, not null. + * @throws NullPointerException if the file is null. + * @throws IOException if an error occurs during file deletion. */ public void delete(final File fileToDelete) throws IOException { if (fileToDelete.exists() && !doDelete(fileToDelete)) { @@ -112,8 +112,8 @@ public void delete(final File fileToDelete) throws IOException { * Subclass writers should override {@link #doDelete(File)}, not this method. *

    * - * @param fileToDelete the file to delete, null returns true - * @return true if the file was deleted, or there was no such file + * @param fileToDelete the file to delete, null returns true. + * @return true if the file was deleted, or there was no such file. */ public boolean deleteQuietly(final File fileToDelete) { if (fileToDelete == null || !fileToDelete.exists()) { @@ -139,10 +139,10 @@ public boolean deleteQuietly(final File fileToDelete) { * This implementation uses {@link FileUtils#delete(File)}. *

    * - * @param file the file to delete, exists, not null - * @return true if the file was deleted - * @throws NullPointerException if the file is null - * @throws IOException if an error occurs during file deletion + * @param file the file to delete, exists, not null. + * @return true if the file was deleted. + * @throws NullPointerException if the file is null. + * @throws IOException if an error occurs during file deletion. */ protected boolean doDelete(final File file) throws IOException { FileUtils.delete(file); @@ -152,7 +152,7 @@ protected boolean doDelete(final File file) throws IOException { /** * Gets a string describing the delete strategy. * - * @return a string describing the delete strategy + * @return a string describing the delete strategy. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/FileExistsException.java b/src/main/java/org/apache/commons/io/FileExistsException.java index 1f733cf11ae..2028ddc5ebd 100644 --- a/src/main/java/org/apache/commons/io/FileExistsException.java +++ b/src/main/java/org/apache/commons/io/FileExistsException.java @@ -40,7 +40,7 @@ public FileExistsException() { /** * Constructs an instance with the specified file. * - * @param file The file that exists + * @param file The file that exists. */ public FileExistsException(final File file) { super("File " + file + " exists"); @@ -49,7 +49,7 @@ public FileExistsException(final File file) { /** * Constructs an instance with the specified message. * - * @param message The error message + * @param message The error message. */ public FileExistsException(final String message) { super(message); diff --git a/src/main/java/org/apache/commons/io/FileSystem.java b/src/main/java/org/apache/commons/io/FileSystem.java index e05b52c189e..e4ba867a685 100644 --- a/src/main/java/org/apache/commons/io/FileSystem.java +++ b/src/main/java/org/apache/commons/io/FileSystem.java @@ -266,7 +266,7 @@ final boolean isWithinLimit(final CharSequence value, final int limit, final Cha /** * Gets the current file system. * - * @return the current file system + * @return the current file system. */ private static FileSystem current() { if (IS_OS_LINUX) { @@ -284,7 +284,7 @@ private static FileSystem current() { /** * Gets the current file system. * - * @return the current file system + * @return the current file system. */ public static FileSystem getCurrent() { return CURRENT; @@ -294,8 +294,8 @@ public static FileSystem getCurrent() { * Decides if the operating system matches. * * @param osNamePrefix - * the prefix for the operating system name - * @return true if matches, or false if not or can't determine + * the prefix for the operating system name. + * @return true if matches, or false if not or can't determine. */ private static boolean getOsMatchesName(final String osNamePrefix) { return isOsNameMatch(getSystemProperty("os.name"), osNamePrefix); @@ -309,8 +309,8 @@ private static boolean getOsMatchesName(final String osNamePrefix) { *

    * * @param property - * the system property name - * @return the system property value or {@code null} if a security problem occurs + * the system property name. + * @return the system property value or {@code null} if a security problem occurs. */ private static String getSystemProperty(final String property) { try { @@ -345,10 +345,10 @@ private static int indexOfFirstDot(final CharSequence cs) { *

    * * @param osName - * the actual OS name + * the actual OS name. * @param osNamePrefix - * the prefix for the expected OS name - * @return true if matches, or false if not or can't determine + * the prefix for the expected OS name. + * @return true if matches, or false if not or can't determine. */ private static boolean isOsNameMatch(final String osName, final String osNamePrefix) { if (osName == null) { diff --git a/src/main/java/org/apache/commons/io/FileSystemUtils.java b/src/main/java/org/apache/commons/io/FileSystemUtils.java index 4c0af0d3671..7455dca8d09 100644 --- a/src/main/java/org/apache/commons/io/FileSystemUtils.java +++ b/src/main/java/org/apache/commons/io/FileSystemUtils.java @@ -53,12 +53,12 @@ public class FileSystemUtils { * FileSystemUtils.freeSpace("/volume"); // *nix * * - * @param path the path to get free space for, not null, not empty on Unix - * @return the amount of free drive space on the drive or volume + * @param path the path to get free space for, not null, not empty on Unix. + * @return the amount of free drive space on the drive or volume. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. * @since 1.1, enhanced OS support in 1.2 and 1.3 - * @deprecated Use freeSpaceKb(String) Deprecated from 1.3, may be removed in 2.0 + * @deprecated Use freeSpaceKb(String) Deprecated from 1.3, may be removed in 2.0. */ @Deprecated public static long freeSpace(final String path) throws IOException { @@ -75,7 +75,7 @@ public static long freeSpace(final String path) throws IOException { * freeSpaceKb(FileUtils.current().getAbsolutePath()) * * - * @return the amount of free drive space on the drive or volume in kilobytes + * @return the amount of free drive space on the drive or volume in kilobytes. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. * @since 2.0 @@ -97,7 +97,7 @@ public static long freeSpaceKb() throws IOException { * * * @param timeout ignored. - * @return the amount of free drive space on the drive or volume in kilobytes + * @return the amount of free drive space on the drive or volume in kilobytes. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. * @since 2.0 @@ -116,8 +116,8 @@ public static long freeSpaceKb(final long timeout) throws IOException { * FileSystemUtils.freeSpaceKb("/volume"); // *nix * * - * @param path the path to get free space for, not null, not empty on Unix - * @return the amount of free drive space on the drive or volume in kilobytes + * @param path the path to get free space for, not null, not empty on Unix. + * @return the amount of free drive space on the drive or volume in kilobytes. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. * @since 1.2, enhanced OS support in 1.3 @@ -136,9 +136,9 @@ public static long freeSpaceKb(final String path) throws IOException { * FileSystemUtils.freeSpaceKb("/volume"); // *nix * * - * @param path the path to get free space for, not null, not empty on Unix + * @param path the path to get free space for, not null, not empty on Unix. * @param timeout ignored. - * @return the amount of free drive space on the drive or volume in kilobytes + * @return the amount of free drive space on the drive or volume in kilobytes. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. * @since 2.0 @@ -157,8 +157,8 @@ public static long freeSpaceKb(final String path, final long timeout) throws IOE * FileSystemUtils.freeSpace("/volume"); // *nix * * - * @param pathStr the path to get free space for, not null, not empty on Unix - * @return the amount of free drive space on the drive or volume + * @param pathStr the path to get free space for, not null, not empty on Unix. + * @return the amount of free drive space on the drive or volume. * @throws IOException if an I/O error occurs. * @throws IllegalArgumentException if the path is invalid. */ diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index b86f5504814..d340a2baadc 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -112,7 +112,7 @@ * {@link SecurityException} are not documented in the Javadoc. *

    *

    - * Provenance: Excalibur, Alexandria, Commons-Utils + * Provenance: Excalibur, Alexandria, Commons-Utils. *

    */ public class FileUtils { @@ -230,8 +230,8 @@ public class FileUtils { * Similarly for the 1MB and 1KB boundaries. *

    * - * @param size the number of bytes - * @return a human-readable display value (includes units - QB, RB, YB, ZB, EB, PB, TB, GB, MB, KB or bytes) + * @param size the number of bytes. + * @return a human-readable display value (includes units - QB, RB, YB, ZB, EB, PB, TB, GB, MB, KB or bytes). * @throws NullPointerException if the given {@link BigInteger} is {@code null}. * @see IO-226 - should the rounding be changed? * @since 2.4 @@ -276,8 +276,8 @@ public static String byteCountToDisplaySize(final BigInteger size) { * Similarly for the 1MB and 1KB boundaries. *

    * - * @param size the number of bytes - * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes) + * @param size the number of bytes. + * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes). * @see IO-226 - should the rounding be changed? */ // See https://issues.apache.org/jira/browse/IO-226 - should the rounding be changed? @@ -295,8 +295,8 @@ public static String byteCountToDisplaySize(final long size) { * Similarly for the 1MB and 1KB boundaries. *

    * - * @param size the number of bytes - * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes) + * @param size the number of bytes. + * @return a human-readable display value (includes units - EB, PB, TB, GB, MB, KB or bytes). * @see IO-226 - should the rounding be changed? * @since 2.12.0 */ @@ -357,11 +357,11 @@ private static File checkIsFile(final File file, final String name) { * * @param file the file to checksum, must not be {@code null} * @param checksum the checksum object to be used, must not be {@code null} - * @return the checksum specified, updated with the content of the file + * @return the checksum specified, updated with the content of the file. * @throws NullPointerException if the given {@link File} is {@code null}. * @throws NullPointerException if the given {@link Checksum} is {@code null}. * @throws IllegalArgumentException if the given {@link File} is not a file. - * @throws FileNotFoundException if the file does not exist + * @throws FileNotFoundException if the file does not exist. * @throws IOException if an IO error occurs reading the file. * @since 1.3 */ @@ -379,7 +379,7 @@ public static Checksum checksum(final File file, final Checksum checksum) throws * The value of the checksum is returned. * * @param file the file to checksum, must not be {@code null} - * @return the checksum value + * @return the checksum value. * @throws NullPointerException if the {@code file} is {@code null}. * @throws IllegalArgumentException if the {@code file} does not exist or is not a file. * @throws IOException if an IO error occurs reading the file. @@ -392,7 +392,7 @@ public static long checksumCRC32(final File file) throws IOException { /** * Cleans a directory without deleting it. * - * @param directory directory to clean + * @param directory directory to clean. * @throws NullPointerException if the given {@link File} is {@code null}. * @throws IllegalArgumentException if the {@code directory} does not exist or is not a directory. * @throws IOException if an I/O error occurs. @@ -422,9 +422,9 @@ private static void cleanDirectoryOnExit(final File directory) throws IOExceptio * resorting to byte-by-byte comparison of the contents. *

    * - * @param file1 the first file - * @param file2 the second file - * @return true if the content of the files are equal or they both don't exist, false otherwise + * @param file1 the first file. + * @param file2 the second file. + * @return true if the content of the files are equal or they both don't exist, false otherwise. * @throws IllegalArgumentException when an input is not a file. * @throws IOException If an I/O error occurs. * @see PathUtils#fileContentEquals(Path,Path) @@ -464,12 +464,12 @@ public static boolean contentEquals(final File file1, final File file2) throws I * before resorting to line-by-line comparison of the contents. *

    * - * @param file1 the first file - * @param file2 the second file + * @param file1 the first file. + * @param file2 the second file. * @param charsetName the name of the requested charset. - * May be null, in which case the platform default is used + * May be null, in which case the platform default is used. * @return true if the content of the files are equal or neither exists, - * false otherwise + * false otherwise. * @throws IllegalArgumentException when an input is not a file. * @throws IOException in case of an I/O error. * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception). @@ -509,7 +509,7 @@ public static boolean contentEqualsIgnoreEOL(final File file1, final File file2, * representation. This is to account for the difference between * File.listFiles() and FileUtils.listFiles(). * - * @param files a Collection containing {@link File} instances + * @param files a Collection containing {@link File} instances. * @return an array of {@link File} */ public static File[] convertFileCollectionToFileArray(final Collection files) { @@ -545,9 +545,9 @@ public static File[] convertFileCollectionToFileArray(final Collection fil * @param destDir the new directory, must not be {@code null}. * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IllegalArgumentException if {@code srcDir} exists but is not a directory, - * the source and the destination directory are the same + * the source and the destination directory are the same. * @throws FileNotFoundException if the source does not exist. - * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed + * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed. * @since 1.1 */ public static void copyDirectory(final File srcDir, final File destDir) throws IOException { @@ -573,9 +573,9 @@ public static void copyDirectory(final File srcDir, final File destDir) throws I * @param destDir the new directory, must not be {@code null}. * @param preserveFileDate true if the file date of the copy should be the same as the original. * @throws IllegalArgumentException if {@code srcDir} exists but is not a directory, or - * the source and the destination directory are the same + * the source and the destination directory are the same. * @throws FileNotFoundException if the source does not exist. - * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed + * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed. * @since 1.1 */ public static void copyDirectory(final File srcDir, final File destDir, final boolean preserveFileDate) @@ -623,9 +623,9 @@ public static void copyDirectory(final File srcDir, final File destDir, final bo * @param filter the filter to apply, null means copy all directories and files should be the same as the original. * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IllegalArgumentException if {@code srcDir} exists but is not a directory, or - * the source and the destination directory are the same + * the source and the destination directory are the same. * @throws FileNotFoundException if the source does not exist. - * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed + * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed. * @since 1.4 */ public static void copyDirectory(final File srcDir, final File destDir, final FileFilter filter) @@ -675,7 +675,7 @@ public static void copyDirectory(final File srcDir, final File destDir, final Fi * @param preserveFileDate true if the file date of the copy should be the same as the original. * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IllegalArgumentException if {@code srcDir} exists but is not a directory, - * the source and the destination directory are the same, or the destination is not writable + * the source and the destination directory are the same, or the destination is not writable. * @throws FileNotFoundException if the source does not exist. * @throws IOException if an error occurs or setting the last-modified time didn't succeed. * @since 1.4 @@ -722,14 +722,14 @@ public static void copyDirectory(final File srcDir, final File destDir, final Fi * * @param srcDir an existing directory to copy, must not be {@code null} * @param destDir the new directory, must not be {@code null} - * @param fileFilter the filter to apply, null means copy all directories and files - * @param preserveFileDate true if the file date of the copy should be the same as the original + * @param fileFilter the filter to apply, null means copy all directories and files. + * @param preserveFileDate true if the file date of the copy should be the same as the original. * @param copyOptions options specifying how the copy should be done, for example {@link StandardCopyOption}. * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IllegalArgumentException if {@code srcDir} exists but is not a directory, or - * the source and the destination directory are the same + * the source and the destination directory are the same. * @throws FileNotFoundException if the source does not exist. - * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed + * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed. * @since 2.8.0 */ public static void copyDirectory(final File srcDir, final File destDir, final FileFilter fileFilter, final boolean preserveFileDate, @@ -775,7 +775,7 @@ public static void copyDirectory(final File srcDir, final File destDir, final Fi * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IllegalArgumentException if the source or destination is invalid. * @throws FileNotFoundException if the source does not exist. - * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed + * @throws IOException if an error occurs, the destination is not writable, or setting the last-modified time didn't succeed. * @since 1.2 */ public static void copyDirectoryToDirectory(final File sourceDir, final File destinationDir) throws IOException { @@ -831,7 +831,7 @@ public static void copyFile(final File srcFile, final File destFile) throws IOEx * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws IOException if source or destination is invalid. * @throws IOException if an error occurs or setting the last-modified time didn't succeed. - * @throws IOException if the output file length is not the same as the input file length after the copy completes + * @throws IOException if the output file length is not the same as the input file length after the copy completes. * @see #copyFile(File, File, boolean, CopyOption...) */ public static void copyFile(final File srcFile, final File destFile, final boolean preserveFileDate) throws IOException { @@ -864,10 +864,10 @@ public static void copyFile(final File srcFile, final File destFile, final boole * @param copyOptions options specifying how the copy should be done, for example {@link StandardCopyOption}. * @throws NullPointerException if any of the given {@link File}s are {@code null}. * @throws FileNotFoundException if the source does not exist. - * @throws IllegalArgumentException if {@code srcFile} or {@code destFile} is not a file + * @throws IllegalArgumentException if {@code srcFile} or {@code destFile} is not a file. * @throws IOException if the output file length is not the same as the input file length after the copy completes. * @throws IOException if an I/O error occurs, setting the last-modified time didn't succeed, - * or the destination is not writable + * or the destination is not writable. * @see #copyFileToDirectory(File, File, boolean) * @since 2.8.0 */ @@ -917,7 +917,7 @@ public static void copyFile(final File srcFile, final File destFile, final CopyO * * @param input the {@link File} to read. * @param output the {@link OutputStream} to write. - * @return the number of bytes copied + * @return the number of bytes copied. * @throws NullPointerException if the File is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. * @throws IOException if an I/O error occurs. @@ -995,13 +995,13 @@ public static void copyFileToDirectory(final File sourceFile, final File destina * See {@link #copyToFile(InputStream, File)} for a method that does not close the input stream. *

    * - * @param source the {@link InputStream} to copy bytes from, must not be {@code null}, will be closed + * @param source the {@link InputStream} to copy bytes from, must not be {@code null}, will be closed. * @param destination the non-directory {@link File} to write bytes to * (possibly overwriting), must not be {@code null} - * @throws IOException if {@code destination} is a directory - * @throws IOException if {@code destination} cannot be written - * @throws IOException if {@code destination} needs creating but can't be - * @throws IOException if an IO error occurs during copying + * @throws IOException if {@code destination} is a directory. + * @throws IOException if {@code destination} cannot be written. + * @throws IOException if {@code destination} needs creating but can't be. + * @throws IOException if an IO error occurs during copying. * @since 2.0 */ public static void copyInputStreamToFile(final InputStream source, final File destination) throws IOException { @@ -1116,11 +1116,11 @@ public static void copyToFile(final InputStream inputStream, final File file) th * @param source the {@link URL} to copy bytes from, must not be {@code null} * @param destination the non-directory {@link File} to write bytes to * (possibly overwriting), must not be {@code null} - * @throws IOException if {@code source} URL cannot be opened - * @throws IOException if {@code destination} is a directory - * @throws IOException if {@code destination} cannot be written - * @throws IOException if {@code destination} needs creating but can't be - * @throws IOException if an IO error occurs during copying + * @throws IOException if {@code source} URL cannot be opened. + * @throws IOException if {@code destination} is a directory. + * @throws IOException if {@code destination} cannot be written. + * @throws IOException if {@code destination} needs creating but can't be. + * @throws IOException if an IO error occurs during copying. */ public static void copyURLToFile(final URL source, final File destination) throws IOException { final Path path = destination.toPath(); @@ -1140,11 +1140,11 @@ public static void copyURLToFile(final URL source, final File destination) throw * be established to the {@code source} * @param readTimeoutMillis the number of milliseconds until this method will time out if no data could be read from * the {@code source} - * @throws IOException if {@code source} URL cannot be opened - * @throws IOException if {@code destination} is a directory - * @throws IOException if {@code destination} cannot be written - * @throws IOException if {@code destination} needs creating but can't be - * @throws IOException if an IO error occurs during copying + * @throws IOException if {@code source} URL cannot be opened. + * @throws IOException if {@code destination} is a directory. + * @throws IOException if {@code destination} cannot be written. + * @throws IOException if {@code destination} needs creating but can't be. + * @throws IOException if an IO error occurs during copying. * @since 2.0 */ public static void copyURLToFile(final URL source, final File destination, final int connectionTimeoutMillis, final int readTimeoutMillis) @@ -1235,7 +1235,7 @@ static String decodeUrl(final String url) { * * @param file The file to delete. * @return the given file. - * @throws NullPointerException if the parameter is {@code null} + * @throws NullPointerException if the parameter is {@code null}. * @throws IOException if the file cannot be deleted. * @see File#delete() * @since 2.9.0 @@ -1249,10 +1249,10 @@ public static File delete(final File file) throws IOException { /** * Deletes a directory recursively. * - * @param directory directory to delete - * @throws IOException in case deletion is unsuccessful - * @throws NullPointerException if the parameter is {@code null} - * @throws IllegalArgumentException if {@code directory} is not a directory + * @param directory directory to delete. + * @throws IOException in case deletion is unsuccessful. + * @throws NullPointerException if the parameter is {@code null}. + * @throws IllegalArgumentException if {@code directory} is not a directory. */ public static void deleteDirectory(final File directory) throws IOException { Objects.requireNonNull(directory, "directory"); @@ -1269,8 +1269,8 @@ public static void deleteDirectory(final File directory) throws IOException { * Requests a directory for deletion recursively when the virtual machine terminates. * * @param directory directory to delete, must not be {@code null} - * @throws NullPointerException if the directory is {@code null} - * @throws IOException in case deletion is unsuccessful + * @throws NullPointerException if the directory is {@code null}. + * @throws IOException in case deletion is unsuccessful. */ private static void deleteDirectoryOnExit(final File directory) throws IOException { if (!directory.exists()) { @@ -1292,9 +1292,9 @@ private static void deleteDirectoryOnExit(final File directory) throws IOExcepti *
  1. No exceptions are thrown when a file or directory cannot be deleted.
  2. * * - * @param file file or directory to delete, can be {@code null} + * @param file file or directory to delete, can be {@code null}. * @return {@code true} if the file or directory was deleted, otherwise - * {@code false} + * {@code false}. * @since 1.4 */ public static boolean deleteQuietly(final File file) { @@ -1360,7 +1360,7 @@ public static boolean directoryContains(final File directory, final File child) * @param preserveDirDate preserve the directories last modified dates. * @param copyOptions options specifying how the copy should be done, see {@link StandardCopyOption}. * @throws IOException if the directory was not created along with all its parent directories. - * @throws IllegalArgumentException if {@code destDir} is not writable + * @throws IllegalArgumentException if {@code destDir} is not writable. * @throws SecurityException See {@link File#mkdirs()}. */ private static void doCopyDirectory(final File srcDir, final File destDir, final FileFilter fileFilter, final List exclusionList, @@ -1542,7 +1542,7 @@ private static File getParentFile(final File file) { /** * Gets a {@link File} representing the system temporary directory. * - * @return the system temporary directory as a File + * @return the system temporary directory as a File. * @since 2.0 */ public static File getTempDirectory() { @@ -1557,7 +1557,7 @@ public static File getTempDirectory() { * This can affect code that uses String processing to manipulate pathnames rather * than the standard libary methods in classes such as {@link File} * - * @return the path to the system temporary directory as a String + * @return the path to the system temporary directory as a String. * @since 2.0 */ public static String getTempDirectoryPath() { @@ -1589,7 +1589,7 @@ public static String getUserDirectoryPath() { * null-safe delegate to {@link Files#isDirectory(Path path, LinkOption... options)}. * * @param file the path to the file. - * @param options options indicating how symbolic links are handled + * @param options options indicating how symbolic links are handled. * @return {@code true} if the file is a directory; {@code false} if * the path is null, the file does not exist, is not a directory, or it cannot * be determined if the file is a directory or not. @@ -1632,7 +1632,7 @@ public static boolean isEmptyDirectory(final File directory) throws IOException * @param chronoLocalDate the date reference. * @return true if the {@link File} exists and has been modified after the given * {@link ChronoLocalDate} at the current time. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file or local date is {@code null}. * @since 2.8.0 */ @@ -1656,7 +1656,7 @@ public static boolean isFileNewer(final File file, final ChronoLocalDate chronoL * @param localTime the time reference. * @return true if the {@link File} exists and has been modified after the given * {@link ChronoLocalDate} at the given time. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file, local date or zone ID is {@code null}. * @since 2.8.0 */ @@ -1670,13 +1670,13 @@ public static boolean isFileNewer(final File file, final ChronoLocalDate chronoL * Tests if the specified {@link File} is newer than the specified {@link ChronoLocalDate} at the specified * {@link OffsetTime}. * - * @param file the {@link File} of which the modification date must be compared - * @param chronoLocalDate the date reference - * @param offsetTime the time reference + * @param file the {@link File} of which the modification date must be compared. + * @param chronoLocalDate the date reference. + * @param offsetTime the time reference. * @return true if the {@link File} exists and has been modified after the given {@link ChronoLocalDate} at the given * {@link OffsetTime}. - * @throws UncheckedIOException if an I/O error occurs - * @throws NullPointerException if the file, local date or zone ID is {@code null} + * @throws UncheckedIOException if an I/O error occurs. + * @throws NullPointerException if the file, local date or zone ID is {@code null}. * @since 2.12.0 */ public static boolean isFileNewer(final File file, final ChronoLocalDate chronoLocalDate, final OffsetTime offsetTime) { @@ -1700,7 +1700,7 @@ public static boolean isFileNewer(final File file, final ChronoLocalDate chronoL * @param chronoLocalDateTime the date reference. * @return true if the {@link File} exists and has been modified after the given * {@link ChronoLocalDateTime} at the system-default time zone. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file or local date time is {@code null}. * @since 2.8.0 */ @@ -1717,7 +1717,7 @@ public static boolean isFileNewer(final File file, final ChronoLocalDateTime * @param zoneId the time zone. * @return true if the {@link File} exists and has been modified after the given * {@link ChronoLocalDateTime} at the given {@link ZoneId}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file, local date time or zone ID is {@code null}. * @since 2.8.0 */ @@ -1735,7 +1735,7 @@ public static boolean isFileNewer(final File file, final ChronoLocalDateTime * @return true if the {@link File} exists and has been modified after the given * {@link ChronoZonedDateTime}. * @throws NullPointerException if the file or zoned date time is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @since 2.8.0 */ public static boolean isFileNewer(final File file, final ChronoZonedDateTime chronoZonedDateTime) { @@ -1751,7 +1751,7 @@ public static boolean isFileNewer(final File file, final ChronoZonedDateTime * @param date the date reference. * @return true if the {@link File} exists and has been modified * after the given {@link Date}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file or date is {@code null}. */ public static boolean isFileNewer(final File file, final Date date) { @@ -1795,7 +1795,7 @@ public static boolean isFileNewer(final File file, final FileTime fileTime) thro * @param instant the date reference. * @return true if the {@link File} exists and has been modified after the given {@link Instant}. * @throws NullPointerException if the file or instant is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @since 2.8.0 */ public static boolean isFileNewer(final File file, final Instant instant) { @@ -1810,7 +1810,7 @@ public static boolean isFileNewer(final File file, final Instant instant) { * @param timeMillis the time reference measured in milliseconds since the * epoch (00:00:00 GMT, January 1, 1970). * @return true if the {@link File} exists and has been modified after the given time reference. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file is {@code null}. */ public static boolean isFileNewer(final File file, final long timeMillis) { @@ -1821,11 +1821,11 @@ public static boolean isFileNewer(final File file, final long timeMillis) { /** * Tests if the specified {@link File} is newer than the specified {@link OffsetDateTime}. * - * @param file the {@link File} of which the modification date must be compared - * @param offsetDateTime the date reference + * @param file the {@link File} of which the modification date must be compared. + * @param offsetDateTime the date reference. * @return true if the {@link File} exists and has been modified before the given {@link OffsetDateTime}. - * @throws UncheckedIOException if an I/O error occurs - * @throws NullPointerException if the file or zoned date time is {@code null} + * @throws UncheckedIOException if an I/O error occurs. + * @throws NullPointerException if the file or zoned date time is {@code null}. * @since 2.12.0 */ public static boolean isFileNewer(final File file, final OffsetDateTime offsetDateTime) { @@ -1850,7 +1850,7 @@ public static boolean isFileNewer(final File file, final OffsetDateTime offsetDa * @return true if the {@link File} exists and has been modified before the given * {@link ChronoLocalDate} at the current time. * @throws NullPointerException if the file or local date is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @see ZoneId#systemDefault() * @see LocalTime#now() * @since 2.8.0 @@ -1875,7 +1875,7 @@ public static boolean isFileOlder(final File file, final ChronoLocalDate chronoL * @param localTime the time reference. * @return true if the {@link File} exists and has been modified before the * given {@link ChronoLocalDate} at the specified time. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @throws NullPointerException if the file, local date or local time is {@code null}. * @see ZoneId#systemDefault() * @since 2.8.0 @@ -1890,13 +1890,13 @@ public static boolean isFileOlder(final File file, final ChronoLocalDate chronoL * Tests if the specified {@link File} is older than the specified {@link ChronoLocalDate} at the specified * {@link OffsetTime}. * - * @param file the {@link File} of which the modification date must be compared - * @param chronoLocalDate the date reference - * @param offsetTime the time reference + * @param file the {@link File} of which the modification date must be compared. + * @param chronoLocalDate the date reference. + * @param offsetTime the time reference. * @return true if the {@link File} exists and has been modified after the given {@link ChronoLocalDate} at the given * {@link OffsetTime}. - * @throws NullPointerException if the file, local date or zone ID is {@code null} - * @throws UncheckedIOException if an I/O error occurs + * @throws NullPointerException if the file, local date or zone ID is {@code null}. + * @throws UncheckedIOException if an I/O error occurs. * @since 2.12.0 */ public static boolean isFileOlder(final File file, final ChronoLocalDate chronoLocalDate, final OffsetTime offsetTime) { @@ -1921,7 +1921,7 @@ public static boolean isFileOlder(final File file, final ChronoLocalDate chronoL * @return true if the {@link File} exists and has been modified before the given * {@link ChronoLocalDateTime} at the system-default time zone. * @throws NullPointerException if the file or local date time is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @see ZoneId#systemDefault() * @since 2.8.0 */ @@ -1939,7 +1939,7 @@ public static boolean isFileOlder(final File file, final ChronoLocalDateTime * @return true if the {@link File} exists and has been modified before the given * {@link ChronoLocalDateTime} at the given {@link ZoneId}. * @throws NullPointerException if the file, local date time or zone ID is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @since 2.8.0 */ public static boolean isFileOlder(final File file, final ChronoLocalDateTime chronoLocalDateTime, final ZoneId zoneId) { @@ -1956,7 +1956,7 @@ public static boolean isFileOlder(final File file, final ChronoLocalDateTime * @return true if the {@link File} exists and has been modified before the given * {@link ChronoZonedDateTime}. * @throws NullPointerException if the file or zoned date time is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. * @since 2.8.0 */ public static boolean isFileOlder(final File file, final ChronoZonedDateTime chronoZonedDateTime) { @@ -1971,7 +1971,7 @@ public static boolean isFileOlder(final File file, final ChronoZonedDateTime * @param date the date reference. * @return true if the {@link File} exists and has been modified before the given {@link Date}. * @throws NullPointerException if the file or date is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. */ public static boolean isFileOlder(final File file, final Date date) { Objects.requireNonNull(date, "date"); @@ -1986,7 +1986,7 @@ public static boolean isFileOlder(final File file, final Date date) { * @return true if the {@link File} exists and has been modified before the reference {@link File}. * @throws NullPointerException if the file or reference file is {@code null}. * @throws FileNotFoundException if the reference file doesn't exist. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. */ public static boolean isFileOlder(final File file, final File reference) throws FileNotFoundException { return Uncheck.getAsBoolean(() -> PathUtils.isOlder(file.toPath(), reference.toPath())); @@ -2029,7 +2029,7 @@ public static boolean isFileOlder(final File file, final Instant instant) { * epoch (00:00:00 GMT, January 1, 1970). * @return true if the {@link File} exists and has been modified before the given time reference. * @throws NullPointerException if the file is {@code null}. - * @throws UncheckedIOException if an I/O error occurs + * @throws UncheckedIOException if an I/O error occurs. */ public static boolean isFileOlder(final File file, final long timeMillis) { Objects.requireNonNull(file, PROTOCOL_FILE); @@ -2039,8 +2039,8 @@ public static boolean isFileOlder(final File file, final long timeMillis) { /** * Tests if the specified {@link File} is older than the specified {@link OffsetDateTime}. * - * @param file the {@link File} of which the modification date must be compared - * @param offsetDateTime the date reference + * @param file the {@link File} of which the modification date must be compared. + * @param offsetDateTime the date reference. * @return true if the {@link File} exists and has been modified before the given {@link OffsetDateTime}. * @throws NullPointerException if the file or zoned date time is {@code null} * @since 2.12.0 @@ -2065,7 +2065,7 @@ private static boolean isFileProtocol(final URL url) { * null-safe delegate to {@link Files#isRegularFile(Path path, LinkOption... options)}. * * @param file the path to the file. - * @param options options indicating how symbolic links are handled + * @param options options indicating how symbolic links are handled. * @return {@code true} if the file is a regular file; {@code false} if * the path is null, the file does not exist, is not a regular file, or it cannot * be determined if the file is a regular file or not. @@ -2693,9 +2693,9 @@ public static FileInputStream openInputStream(final File file) throws IOExceptio *

    * * @param file the file to open for output, must not be {@code null}. - * @return a new {@link FileOutputStream} for the specified file + * @return a new {@link FileOutputStream} for the specified file. * @throws NullPointerException if the file object is {@code null}. - * @throws IllegalArgumentException if the file object is a directory + * @throws IllegalArgumentException if the file object is a directory. * @throws IllegalArgumentException if the file is not writable. * @throws IOException if the directories could not be created. * @since 1.3 @@ -3271,11 +3271,11 @@ public static void write(final File file, final CharSequence data, final Charset /** * Writes a CharSequence to a file creating the file if it does not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charsetName the name of the requested charset, {@code null} means platform default - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @param file the file to write. + * @param data the content to write to the file. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 2.0 */ public static void write(final File file, final CharSequence data, final String charsetName) throws IOException { @@ -3285,13 +3285,13 @@ public static void write(final File file, final CharSequence data, final String /** * Writes a CharSequence to a file creating the file if it does not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charsetName the name of the requested charset, {@code null} means platform default + * @param file the file to write. + * @param data the content to write to the file. + * @param charsetName the name of the requested charset, {@code null} means platform default. * @param append if {@code true}, then the data will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error - * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported by the VM + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. + * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported by the VM. * @since 2.1 */ public static void write(final File file, final CharSequence data, final String charsetName, final boolean append) throws IOException { @@ -3304,9 +3304,9 @@ public static void write(final File file, final CharSequence data, final String * Writes a byte array to a file creating the file if it does not exist. * The parent directories of the file will be created if they do not exist. * - * @param file the file to write to - * @param data the content to write to the file - * @throws IOException in case of an I/O error + * @param file the file to write to. + * @param data the content to write to the file. + * @throws IOException in case of an I/O error. * @since 1.1 */ public static void writeByteArrayToFile(final File file, final byte[] data) throws IOException { @@ -3316,11 +3316,11 @@ public static void writeByteArrayToFile(final File file, final byte[] data) thro /** * Writes a byte array to a file creating the file if it does not exist. * - * @param file the file to write to - * @param data the content to write to the file + * @param file the file to write to. + * @param data the content to write to the file. * @param append if {@code true}, then bytes will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.1 */ public static void writeByteArrayToFile(final File file, final byte[] data, final boolean append) throws IOException { @@ -3332,11 +3332,11 @@ public static void writeByteArrayToFile(final File file, final byte[] data, fina * at offset {@code off} to a file, creating the file if it does * not exist. * - * @param file the file to write to - * @param data the content to write to the file - * @param off the start offset in the data - * @param len the number of bytes to write - * @throws IOException in case of an I/O error + * @param file the file to write to. + * @param data the content to write to the file. + * @param off the start offset in the data. + * @param len the number of bytes to write. + * @throws IOException in case of an I/O error. * @since 2.5 */ public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len) throws IOException { @@ -3348,13 +3348,13 @@ public static void writeByteArrayToFile(final File file, final byte[] data, fina * at offset {@code off} to a file, creating the file if it does * not exist. * - * @param file the file to write to - * @param data the content to write to the file - * @param off the start offset in the data - * @param len the number of bytes to write + * @param file the file to write to. + * @param data the content to write to the file. + * @param off the start offset in the data. + * @param len the number of bytes to write. * @param append if {@code true}, then bytes will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.5 */ public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len, final boolean append) throws IOException { @@ -3368,9 +3368,9 @@ public static void writeByteArrayToFile(final File file, final byte[] data, fina * the specified {@link File} line by line. * The default VM encoding and the default line ending will be used. * - * @param file the file to write to - * @param lines the lines to write, {@code null} entries produce blank lines - * @throws IOException in case of an I/O error + * @param file the file to write to. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @throws IOException in case of an I/O error. * @since 1.3 */ public static void writeLines(final File file, final Collection lines) throws IOException { @@ -3382,11 +3382,11 @@ public static void writeLines(final File file, final Collection lines) throws * the specified {@link File} line by line. * The default VM encoding and the default line ending will be used. * - * @param file the file to write to - * @param lines the lines to write, {@code null} entries produce blank lines + * @param file the file to write to. + * @param lines the lines to write, {@code null} entries produce blank lines. * @param append if {@code true}, then the lines will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.1 */ public static void writeLines(final File file, final Collection lines, final boolean append) throws IOException { @@ -3398,10 +3398,10 @@ public static void writeLines(final File file, final Collection lines, final * the specified {@link File} line by line. * The default VM encoding and the specified line ending will be used. * - * @param file the file to write to - * @param lines the lines to write, {@code null} entries produce blank lines - * @param lineEnding the line separator to use, {@code null} is system default - * @throws IOException in case of an I/O error + * @param file the file to write to. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @param lineEnding the line separator to use, {@code null} is system default. + * @throws IOException in case of an I/O error. * @since 1.3 */ public static void writeLines(final File file, final Collection lines, final String lineEnding) throws IOException { @@ -3413,12 +3413,12 @@ public static void writeLines(final File file, final Collection lines, final * the specified {@link File} line by line. * The default VM encoding and the specified line ending will be used. * - * @param file the file to write to - * @param lines the lines to write, {@code null} entries produce blank lines - * @param lineEnding the line separator to use, {@code null} is system default + * @param file the file to write to. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @param lineEnding the line separator to use, {@code null} is system default. * @param append if {@code true}, then the lines will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.1 */ public static void writeLines(final File file, final Collection lines, final String lineEnding, final boolean append) throws IOException { @@ -3431,11 +3431,11 @@ public static void writeLines(final File file, final Collection lines, final * The specified character encoding and the default line ending will be used. * The parent directories of the file will be created if they do not exist. * - * @param file the file to write to - * @param charsetName the name of the requested charset, {@code null} means platform default - * @param lines the lines to write, {@code null} entries produce blank lines - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @param file the file to write to. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 1.1 */ public static void writeLines(final File file, final String charsetName, final Collection lines) throws IOException { @@ -3447,13 +3447,13 @@ public static void writeLines(final File file, final String charsetName, final C * the specified {@link File} line by line, optionally appending. * The specified character encoding and the default line ending will be used. * - * @param file the file to write to - * @param charsetName the name of the requested charset, {@code null} means platform default - * @param lines the lines to write, {@code null} entries produce blank lines + * @param file the file to write to. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @param lines the lines to write, {@code null} entries produce blank lines. * @param append if {@code true}, then the lines will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 2.1 */ public static void writeLines(final File file, final String charsetName, final Collection lines, final boolean append) throws IOException { @@ -3466,12 +3466,12 @@ public static void writeLines(final File file, final String charsetName, final C * The specified character encoding and the line ending will be used. * The parent directories of the file will be created if they do not exist. * - * @param file the file to write to - * @param charsetName the name of the requested charset, {@code null} means platform default - * @param lines the lines to write, {@code null} entries produce blank lines - * @param lineEnding the line separator to use, {@code null} is system default - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @param file the file to write to. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @param lineEnding the line separator to use, {@code null} is system default. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 1.1 */ public static void writeLines(final File file, final String charsetName, final Collection lines, final String lineEnding) throws IOException { @@ -3483,14 +3483,14 @@ public static void writeLines(final File file, final String charsetName, final C * the specified {@link File} line by line. * The specified character encoding and the line ending will be used. * - * @param file the file to write to - * @param charsetName the name of the requested charset, {@code null} means platform default - * @param lines the lines to write, {@code null} entries produce blank lines - * @param lineEnding the line separator to use, {@code null} is system default + * @param file the file to write to. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @param lines the lines to write, {@code null} entries produce blank lines. + * @param lineEnding the line separator to use, {@code null} is system default. * @param append if {@code true}, then the lines will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 2.1 */ public static void writeLines(final File file, final String charsetName, final Collection lines, final String lineEnding, final boolean append) @@ -3503,10 +3503,10 @@ public static void writeLines(final File file, final String charsetName, final C /** * Writes a String to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * - * @param file the file to write - * @param data the content to write to the file - * @throws IOException in case of an I/O error - * @deprecated Use {@link #writeStringToFile(File, String, Charset)} instead (and specify the appropriate encoding) + * @param file the file to write. + * @param data the content to write to the file. + * @throws IOException in case of an I/O error. + * @deprecated Use {@link #writeStringToFile(File, String, Charset)} instead (and specify the appropriate encoding). */ @Deprecated public static void writeStringToFile(final File file, final String data) throws IOException { @@ -3516,12 +3516,12 @@ public static void writeStringToFile(final File file, final String data) throws /** * Writes a String to a file creating the file if it does not exist using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * - * @param file the file to write - * @param data the content to write to the file - * @param append if {@code true}, then the String will be added to the end of the file rather than overwriting - * @throws IOException in case of an I/O error + * @param file the file to write. + * @param data the content to write to the file. + * @param append if {@code true}, then the String will be added to the end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.1 - * @deprecated Use {@link #writeStringToFile(File, String, Charset, boolean)} instead (and specify the appropriate encoding) + * @deprecated Use {@link #writeStringToFile(File, String, Charset, boolean)} instead (and specify the appropriate encoding). */ @Deprecated public static void writeStringToFile(final File file, final String data, final boolean append) throws IOException { @@ -3532,11 +3532,11 @@ public static void writeStringToFile(final File file, final String data, final b * Writes a String to a file creating the file if it does not exist. * The parent directories of the file will be created if they do not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charset the charset to use, {@code null} means platform default - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @param file the file to write. + * @param data the content to write to the file. + * @param charset the charset to use, {@code null} means platform default. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. * @since 2.4 */ public static void writeStringToFile(final File file, final String data, final Charset charset) throws IOException { @@ -3547,12 +3547,12 @@ public static void writeStringToFile(final File file, final String data, final C * Writes a String to a file, creating the file if it does not exist. * The parent directories of the file are created if they do not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charset the charset to use, {@code null} means platform default + * @param file the file to write. + * @param data the content to write to the file. + * @param charset the charset to use, {@code null} means platform default. * @param append if {@code true}, then the String will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. * @since 2.3 */ public static void writeStringToFile(final File file, final String data, final Charset charset, final boolean append) throws IOException { @@ -3565,11 +3565,11 @@ public static void writeStringToFile(final File file, final String data, final C * Writes a String to a file, creating the file if it does not exist. * The parent directories of the file are created if they do not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charsetName the name of the requested charset, {@code null} means platform default - * @throws IOException in case of an I/O error - * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM + * @param file the file to write. + * @param data the content to write to the file. + * @param charsetName the name of the requested charset, {@code null} means platform default. + * @throws IOException in case of an I/O error. + * @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM. */ public static void writeStringToFile(final File file, final String data, final String charsetName) throws IOException { writeStringToFile(file, data, charsetName, false); @@ -3579,13 +3579,13 @@ public static void writeStringToFile(final File file, final String data, final S * Writes a String to a file, creating the file if it does not exist. * The parent directories of the file are created if they do not exist. * - * @param file the file to write - * @param data the content to write to the file - * @param charsetName the name of the requested charset, {@code null} means platform default + * @param file the file to write. + * @param data the content to write to the file. + * @param charsetName the name of the requested charset, {@code null} means platform default. * @param append if {@code true}, then the String will be added to the - * end of the file rather than overwriting - * @throws IOException in case of an I/O error - * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported by the VM + * end of the file rather than overwriting. + * @throws IOException in case of an I/O error. + * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported by the VM. * @since 2.1 */ public static void writeStringToFile(final File file, final String data, final String charsetName, final boolean append) throws IOException { diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java index ec836e29421..fe49a1a8a6c 100644 --- a/src/main/java/org/apache/commons/io/FilenameUtils.java +++ b/src/main/java/org/apache/commons/io/FilenameUtils.java @@ -231,10 +231,10 @@ public class FilenameUtils { * use {@link #getFullPath(String)} on the base path argument. *

    * - * @param basePath the base path to attach to, always treated as a path - * @param fullFileNameToAdd the file name (or path) to attach to the base - * @return the concatenated path, or null if invalid - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param basePath the base path to attach to, always treated as a path. + * @param fullFileNameToAdd the file name (or path) to attach to the base. + * @return the concatenated path, or null if invalid. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ public static String concat(final String basePath, final String fullFileNameToAdd) { final int prefix = getPrefixLength(fullFileNameToAdd); @@ -297,10 +297,10 @@ public static boolean directoryContains(final String canonicalParent, final Stri /** * Does the work of getting the path. * - * @param fileName the file name - * @param includeSeparator true to include the end separator - * @return the path - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name. + * @param includeSeparator true to include the end separator. + * @return the path. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ private static String doGetFullPath(final String fileName, final boolean includeSeparator) { if (fileName == null) { @@ -330,10 +330,10 @@ private static String doGetFullPath(final String fileName, final boolean include /** * Does the work of getting the path. * - * @param fileName the file name - * @param separatorAdd 0 to omit the end separator, 1 to return it - * @return the path - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name. + * @param separatorAdd 0 to omit the end separator, 1 to return it. + * @return the path. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ private static String doGetPath(final String fileName, final int separatorAdd) { if (fileName == null) { @@ -354,11 +354,11 @@ private static String doGetPath(final String fileName, final int separatorAdd) { /** * Internal method to perform the normalization. * - * @param fileName the file name - * @param separator The separator character to use - * @param keepSeparator true to keep the final separator - * @return the normalized fileName - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name. + * @param separator The separator character to use. + * @param keepSeparator true to keep the final separator. + * @return the normalized fileName. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ private static String doNormalize(final String fileName, final char separator, final boolean keepSeparator) { if (fileName == null) { @@ -465,9 +465,9 @@ private static String doNormalize(final String fileName, final char separator, f * This is merely a null-safe case-sensitive string equality. *

    * - * @param fileName1 the first file name, may be null - * @param fileName2 the second file name, may be null - * @return true if the file names are equal, null equals null + * @param fileName1 the first file name, may be null. + * @param fileName2 the second file name, may be null. + * @return true if the file names are equal, null equals null. * @see IOCase#SENSITIVE */ public static boolean equals(final String fileName1, final String fileName2) { @@ -478,11 +478,11 @@ public static boolean equals(final String fileName1, final String fileName2) { * Checks whether two file names are equal, optionally normalizing and providing * control over the case-sensitivity. * - * @param fileName1 the first file name, may be null - * @param fileName2 the second file name, may be null - * @param normalize whether to normalize the file names - * @param ioCase what case sensitivity rule to use, null means case-sensitive - * @return true if the file names are equal, null equals null + * @param fileName1 the first file name, may be null. + * @param fileName2 the second file name, may be null. + * @param normalize whether to normalize the file names. + * @param ioCase what case sensitivity rule to use, null means case-sensitive. + * @return true if the file names are equal, null equals null. * @since 1.3 */ public static boolean equals(String fileName1, String fileName2, final boolean normalize, final IOCase ioCase) { @@ -510,9 +510,9 @@ public static boolean equals(String fileName1, String fileName2, final boolean n * The check is then performed in a case-sensitive manner. *

    * - * @param fileName1 the first file name, may be null - * @param fileName2 the second file name, may be null - * @return true if the file names are equal, null equals null + * @param fileName1 the first file name, may be null. + * @param fileName2 the second file name, may be null. + * @return true if the file names are equal, null equals null. * @see IOCase#SENSITIVE */ public static boolean equalsNormalized(final String fileName1, final String fileName2) { @@ -528,9 +528,9 @@ public static boolean equalsNormalized(final String fileName1, final String file * case-insensitively on Windows. *

    * - * @param fileName1 the first file name, may be null - * @param fileName2 the second file name, may be null - * @return true if the file names are equal, null equals null + * @param fileName1 the first file name, may be null. + * @param fileName2 the second file name, may be null. + * @return true if the file names are equal, null equals null. * @see IOCase#SYSTEM */ public static boolean equalsNormalizedOnSystem(final String fileName1, final String fileName2) { @@ -544,9 +544,9 @@ public static boolean equalsNormalizedOnSystem(final String fileName1, final Str * The check is case-sensitive on Unix and case-insensitive on Windows. *

    * - * @param fileName1 the first file name, may be null - * @param fileName2 the second file name, may be null - * @return true if the file names are equal, null equals null + * @param fileName1 the first file name, may be null. + * @param fileName2 the second file name, may be null. + * @return true if the file names are equal, null equals null. * @see IOCase#SYSTEM */ public static boolean equalsOnSystem(final String fileName1, final String fileName2) { @@ -572,7 +572,7 @@ static char flipSeparator(final char ch) { /** * Special handling for NTFS ADS: Don't accept colon in the file name. * - * @param fileName a file name + * @param fileName a file name. * @return ADS offsets. */ private static int getAdsCriticalOffset(final String fileName) { @@ -609,9 +609,9 @@ private static int getAdsCriticalOffset(final String fileName) { * The output will be the same irrespective of the machine that the code is running on. *

    * - * @param fileName the file name, null returns null - * @return the name of the file without the path, or an empty string if none exists - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the name of the file without the path, or an empty string if none exists. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static String getBaseName(final String fileName) { return removeExtension(getName(fileName)); @@ -682,9 +682,9 @@ public static String getExtension(final String fileName) throws IllegalArgumentE * The output will be the same irrespective of the machine that the code is running on. *

    * - * @param fileName the file name, null returns null - * @return the path of the file, an empty string if none exists, null if invalid - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the path of the file, an empty string if none exists, null if invalid. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ public static String getFullPath(final String fileName) { return doGetFullPath(fileName, true); @@ -715,9 +715,9 @@ public static String getFullPath(final String fileName) { * The output will be the same irrespective of the machine that the code is running on. *

    * - * @param fileName the file name, null returns null - * @return the path of the file, an empty string if none exists, null if invalid - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the path of the file, an empty string if none exists, null if invalid. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ public static String getFullPathNoEndSeparator(final String fileName) { return doGetFullPath(fileName, false); @@ -740,9 +740,9 @@ public static String getFullPathNoEndSeparator(final String fileName) { * The output will be the same irrespective of the machine that the code is running on. *

    * - * @param fileName the file name, null returns null - * @return the name of the file without the path, or an empty string if none exists - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the name of the file without the path, or an empty string if none exists. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static String getName(final String fileName) { if (fileName == null) { @@ -773,9 +773,9 @@ public static String getName(final String fileName) { * See {@link #getFullPath(String)} for the method that retains the prefix. *

    * - * @param fileName the file name, null returns null - * @return the path of the file, an empty string if none exists, null if invalid - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the path of the file, an empty string if none exists, null if invalid. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ public static String getPath(final String fileName) { return doGetPath(fileName, 1); @@ -804,9 +804,9 @@ public static String getPath(final String fileName) { * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix. *

    * - * @param fileName the file name, null returns null - * @return the path of the file, an empty string if none exists, null if invalid - * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the path of the file, an empty string if none exists, null if invalid. + * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ public static String getPathNoEndSeparator(final String fileName) { return doGetPath(fileName, 0); @@ -839,9 +839,9 @@ public static String getPathNoEndSeparator(final String fileName) { * ie. both Unix and Windows prefixes are matched regardless. *

    * - * @param fileName the file name, null returns null - * @return the prefix of the file, null if invalid - * @throws IllegalArgumentException if the result contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the prefix of the file, null if invalid. + * @throws IllegalArgumentException if the result contains the null character ({@code U+0000}). */ public static String getPrefix(final String fileName) { if (fileName == null) { @@ -898,8 +898,8 @@ public static String getPrefix(final String fileName) { * to a single slash at the start of the file name. *

    * - * @param fileName the file name to find the prefix in, null returns -1 - * @return the length of the prefix, -1 if invalid or null + * @param fileName the file name to find the prefix in, null returns -1. + * @return the length of the prefix, -1 if invalid or null. */ public static int getPrefixLength(final String fileName) { if (fileName == null) { @@ -979,8 +979,8 @@ public static int getPrefixLength(final String fileName) { * an {@link IllegalArgumentException} for names like this. * * @param fileName - * the file name to find the last extension separator in, null returns -1 - * @return the index of the last extension separator character, or -1 if there is no such character + * the file name to find the last extension separator in, null returns -1. + * @return the index of the last extension separator character, or -1 if there is no such character. * @throws IllegalArgumentException Windows only: the file name parameter is, in fact, * the identifier of an Alternate Data Stream, for example "foo.exe:bar.txt". */ @@ -1008,9 +1008,9 @@ public static int indexOfExtension(final String fileName) throws IllegalArgument *

    * The output will be the same irrespective of the machine that the code is running on. * - * @param fileName the file name to find the last path separator in, null returns -1 + * @param fileName the file name to find the last path separator in, null returns -1. * @return the index of the last separator character, or -1 if there - * is no such character + * is no such character. */ public static int indexOfLastSeparator(final String fileName) { if (fileName == null) { @@ -1032,10 +1032,10 @@ private static boolean isEmpty(final String string) { * after the last period. There must be no directory separator after the period. * The extension check is case-sensitive on all platforms. * - * @param fileName the file name, null returns false - * @param extensions the extensions to check for, null checks for no extension - * @return true if the file name is one of the extensions - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name, null returns false. + * @param extensions the extensions to check for, null checks for no extension. + * @return true if the file name is one of the extensions. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static boolean isExtension(final String fileName, final Collection extensions) { if (fileName == null) { @@ -1056,10 +1056,10 @@ public static boolean isExtension(final String fileName, final Collection * * @see "https://tools.ietf.org/html/rfc3986#section-3.2.2" - * @param name the hostname to validate - * @return true if the given name is a valid host name + * @param name the hostname to validate. + * @return true if the given name is a valid host name. */ private static boolean isValidHostName(final String name) { return isIPv6Address(name) || isRFC3986HostName(name); @@ -1288,9 +1288,9 @@ private static boolean isValidHostName(final String name) { * * (Note the file separator will be correct for Windows/Unix.) * - * @param fileName the file name to normalize, null returns null - * @return the normalized fileName, or null if invalid - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name to normalize, null returns null. + * @return the normalized fileName, or null if invalid. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static String normalize(final String fileName) { return doNormalize(fileName, SYSTEM_NAME_SEPARATOR, true); @@ -1334,11 +1334,11 @@ public static String normalize(final String fileName) { * The output will be the same on both Unix and Windows including * the separator character. * - * @param fileName the file name to normalize, null returns null + * @param fileName the file name to normalize, null returns null. * @param unixSeparator {@code true} if a Unix separator should * be used or {@code false} if a Windows separator should be used. - * @return the normalized fileName, or null if invalid - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @return the normalized fileName, or null if invalid. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). * @since 2.0 */ public static String normalize(final String fileName, final boolean unixSeparator) { @@ -1383,9 +1383,9 @@ public static String normalize(final String fileName, final boolean unixSeparato * * (Note the file separator returned will be correct for Windows/Unix) * - * @param fileName the file name to normalize, null returns null - * @return the normalized fileName, or null if invalid - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name to normalize, null returns null. + * @return the normalized fileName, or null if invalid. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static String normalizeNoEndSeparator(final String fileName) { return doNormalize(fileName, SYSTEM_NAME_SEPARATOR, false); @@ -1428,11 +1428,11 @@ public static String normalizeNoEndSeparator(final String fileName) { * ~/../bar --> null * * - * @param fileName the file name to normalize, null returns null + * @param fileName the file name to normalize, null returns null. * @param unixSeparator {@code true} if a Unix separator should * be used or {@code false} if a Windows separator should be used. - * @return the normalized fileName, or null if invalid - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @return the normalized fileName, or null if invalid. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). * @since 2.0 */ public static String normalizeNoEndSeparator(final String fileName, final boolean unixSeparator) { @@ -1455,9 +1455,9 @@ public static String normalizeNoEndSeparator(final String fileName, final boolea *

    * The output will be the same irrespective of the machine that the code is running on. * - * @param fileName the file name, null returns null - * @return the file name minus the extension - * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}) + * @param fileName the file name, null returns null. + * @return the file name minus the extension. + * @throws IllegalArgumentException if the file name contains the null character ({@code U+0000}). */ public static String removeExtension(final String fileName) { if (fileName == null) { @@ -1477,9 +1477,9 @@ public static String removeExtension(final String fileName) { * * This may be used to defend against poison byte attacks. * - * @param path the path to check - * @return The input - * @throws IllegalArgumentException if path contains the null character ({@code U+0000}) + * @param path the path to check. + * @return The input. + * @throws IllegalArgumentException if path contains the null character ({@code U+0000}). */ private static String requireNonNullChars(final String path) { if (path.indexOf(0) >= 0) { @@ -1524,8 +1524,8 @@ public static String separatorsToWindows(final String path) { * The text is split by '?' and '*'. * Where multiple '*' occur consecutively they are collapsed into a single '*'. * - * @param text the text to split - * @return the array of tokens, never null + * @param text the text to split. + * @return the array of tokens, never null. */ static String[] splitOnTokens(final String text) { // used by wildcardMatch @@ -1589,9 +1589,9 @@ private static char toSeparator(final boolean unixSeparator) { * * The sequence "*?" does not work properly at present in match strings. * - * @param fileName the file name to match on - * @param wildcardMatcher the wildcard string to match against - * @return true if the file name matches the wildcard string + * @param fileName the file name to match on. + * @param wildcardMatcher the wildcard string to match against. + * @return true if the file name matches the wildcard string. * @see IOCase#SENSITIVE */ public static boolean wildcardMatch(final String fileName, final String wildcardMatcher) { @@ -1606,10 +1606,10 @@ public static boolean wildcardMatch(final String fileName, final String wildcard * single or multiple (zero or more) wildcard characters. * The sequence "*?" does not work properly at present in match strings. * - * @param fileName the file name to match on - * @param wildcardMatcher the wildcard string to match against - * @param ioCase what case sensitivity rule to use, null means case-sensitive - * @return true if the file name matches the wildcard string + * @param fileName the file name to match on. + * @param wildcardMatcher the wildcard string to match against. + * @param ioCase what case sensitivity rule to use, null means case-sensitive. + * @return true if the file name matches the wildcard string. * @since 1.3 */ public static boolean wildcardMatch(final String fileName, final String wildcardMatcher, IOCase ioCase) { @@ -1707,9 +1707,9 @@ public static boolean wildcardMatch(final String fileName, final String wildcard * * The sequence "*?" does not work properly at present in match strings. * - * @param fileName the file name to match on - * @param wildcardMatcher the wildcard string to match against - * @return true if the file name matches the wildcard string + * @param fileName the file name to match on. + * @param wildcardMatcher the wildcard string to match against. + * @return true if the file name matches the wildcard string. * @see IOCase#SYSTEM */ public static boolean wildcardMatchOnSystem(final String fileName, final String wildcardMatcher) { diff --git a/src/main/java/org/apache/commons/io/HexDump.java b/src/main/java/org/apache/commons/io/HexDump.java index 41c026b2fb1..38f52fdd325 100644 --- a/src/main/java/org/apache/commons/io/HexDump.java +++ b/src/main/java/org/apache/commons/io/HexDump.java @@ -62,11 +62,11 @@ public class HexDump { * characters (if any) that those bytes represent printed per each line * of output. * - * @param data the byte array to be dumped - * @param appendable the Appendable to which the data is to be written + * @param data the byte array to be dumped. + * @param appendable the Appendable to which the data is to be written. * @throws IOException is thrown if anything goes wrong writing - * the data to appendable - * @throws NullPointerException if the output appendable is null + * the data to appendable. + * @throws NullPointerException if the output appendable is null. * @since 2.12.0 */ public static void dump(final byte[] data, final Appendable appendable) @@ -89,16 +89,16 @@ public static void dump(final byte[] data, final Appendable appendable) * the first byte on that line is located. *

    * - * @param data the byte array to be dumped - * @param offset offset of the byte array within a larger entity - * @param appendable the Appendable to which the data is to be written - * @param index initial index into the byte array - * @param length number of bytes to dump from the array + * @param data the byte array to be dumped. + * @param offset offset of the byte array within a larger entity. + * @param appendable the Appendable to which the data is to be written. + * @param index initial index into the byte array. + * @param length number of bytes to dump from the array. * @throws IOException is thrown if anything goes wrong writing - * the data to appendable + * the data to appendable. * @throws ArrayIndexOutOfBoundsException if the index or length is - * outside the data array's bounds - * @throws NullPointerException if the output appendable is null + * outside the data array's bounds. + * @throws NullPointerException if the output appendable is null. * @since 2.12.0 */ public static void dump(final byte[] data, final long offset, @@ -172,16 +172,16 @@ public static void dump(final byte[] data, final long offset, * This method uses the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    * - * @param data the byte array to be dumped - * @param offset offset of the byte array within a larger entity + * @param data the byte array to be dumped. + * @param offset offset of the byte array within a larger entity. * @param stream the OutputStream to which the data is to be - * written - * @param index initial index into the byte array + * written. + * @param index initial index into the byte array. * @throws IOException is thrown if anything goes wrong writing - * the data to stream + * the data to stream. * @throws ArrayIndexOutOfBoundsException if the index is - * outside the data array's bounds - * @throws NullPointerException if the output stream is null + * outside the data array's bounds. + * @throws NullPointerException if the output stream is null. */ @SuppressWarnings("resource") // Caller closes stream public static void dump(final byte[] data, final long offset, @@ -197,8 +197,8 @@ public static void dump(final byte[] data, final long offset, /** * Dumps a byte value into a StringBuilder. * - * @param builder the StringBuilder to dump the value in - * @param value the byte value to be dumped + * @param builder the StringBuilder to dump the value in. + * @param value the byte value to be dumped. * @return StringBuilder containing the dumped value. */ private static StringBuilder dump(final StringBuilder builder, final byte value) { @@ -211,8 +211,8 @@ private static StringBuilder dump(final StringBuilder builder, final byte value) /** * Dumps a long value into a StringBuilder. * - * @param builder the StringBuilder to dump the value in - * @param value the long value to be dumped + * @param builder the StringBuilder to dump the value in. + * @param value the long value to be dumped. * @return StringBuilder containing the dumped value. */ private static StringBuilder dump(final StringBuilder builder, final long value) { diff --git a/src/main/java/org/apache/commons/io/IOCase.java b/src/main/java/org/apache/commons/io/IOCase.java index 7fee424f489..8afcdeafaf7 100644 --- a/src/main/java/org/apache/commons/io/IOCase.java +++ b/src/main/java/org/apache/commons/io/IOCase.java @@ -72,9 +72,9 @@ public enum IOCase { /** * Looks up an IOCase by name. * - * @param name the name to find - * @return the IOCase object - * @throws IllegalArgumentException if the name is invalid + * @param name the name to find. + * @return the IOCase object. + * @throws IllegalArgumentException if the name is invalid. */ public static IOCase forName(final String name) { return Stream.of(values()).filter(ioCase -> ioCase.getName().equals(name)).findFirst() @@ -236,7 +236,7 @@ public boolean checkStartsWith(final String str, final String start) { /** * Gets the name of the constant. * - * @return the name of the constant + * @return the name of the constant. */ public String getName() { return name; diff --git a/src/main/java/org/apache/commons/io/IOExceptionList.java b/src/main/java/org/apache/commons/io/IOExceptionList.java index 740bedb6789..256cebd1360 100644 --- a/src/main/java/org/apache/commons/io/IOExceptionList.java +++ b/src/main/java/org/apache/commons/io/IOExceptionList.java @@ -126,7 +126,7 @@ public List getCauseList() { * Works around Throwable and Generics, may fail at runtime depending on the argument value. * * @param type of exception to return. - * @param clazz the target type + * @param clazz the target type. * @return The list of causes. */ public List getCauseList(final Class clazz) { diff --git a/src/main/java/org/apache/commons/io/IOExceptionWithCause.java b/src/main/java/org/apache/commons/io/IOExceptionWithCause.java index af25e8b0a40..8cb451658f7 100644 --- a/src/main/java/org/apache/commons/io/IOExceptionWithCause.java +++ b/src/main/java/org/apache/commons/io/IOExceptionWithCause.java @@ -23,7 +23,7 @@ * Subclasses IOException with the {@link Throwable} constructors missing before Java 6. * * @since 1.4 - * @deprecated (since 2.5) use {@link IOException} instead + * @deprecated (since 2.5) use {@link IOException} instead. */ @Deprecated public class IOExceptionWithCause extends IOException { @@ -41,7 +41,7 @@ public class IOExceptionWithCause extends IOException { *

    * * @param message - * the message (see {@link #getMessage()}) + * the message (see {@link #getMessage()}). * @param cause * the cause (see {@link #getCause()}). A {@code null} value is allowed. */ diff --git a/src/main/java/org/apache/commons/io/IORandomAccessFile.java b/src/main/java/org/apache/commons/io/IORandomAccessFile.java index 9b4aea52dec..22d232e562d 100644 --- a/src/main/java/org/apache/commons/io/IORandomAccessFile.java +++ b/src/main/java/org/apache/commons/io/IORandomAccessFile.java @@ -37,7 +37,7 @@ public final class IORandomAccessFile extends RandomAccessFile { /** * Constructs a new instance by calling {@link RandomAccessFile#RandomAccessFile(File, String)}. * - * @param file the file object + * @param file the file object. * @param mode the access mode, as described in {@link RandomAccessFile#RandomAccessFile(File, String)}. * @throws FileNotFoundException Thrown by {@link RandomAccessFile#RandomAccessFile(File, String)}. * @see RandomAccessFile#RandomAccessFile(File, String) @@ -51,7 +51,7 @@ public IORandomAccessFile(final File file, final String mode) throws FileNotFoun /** * Constructs a new instance by calling {@link RandomAccessFile#RandomAccessFile(String, String)}. * - * @param name the file object + * @param name the file object. * @param mode the access mode, as described in {@link RandomAccessFile#RandomAccessFile(String, String)}. * @throws FileNotFoundException Thrown by {@link RandomAccessFile#RandomAccessFile(String, String)}. * @see RandomAccessFile#RandomAccessFile(String, String) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index ee2f5510fb1..df7af6a8803 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -391,7 +391,7 @@ public static BufferedInputStream buffer(final InputStream inputStream, final in * BufferedOutputStream from the given OutputStream. * * @param outputStream the OutputStream to wrap or return (not null). - * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream + * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream. * @throws NullPointerException if the input parameter is null. * @since 2.5 */ @@ -1462,8 +1462,8 @@ public static void copy(final InputStream input, final Writer writer, final Char * This method uses {@link InputStreamReader}. *

    * - * @param input the {@link InputStream} to read - * @param writer the {@link Writer} to write to + * @param input the {@link InputStream} to read. + * @param writer the {@link Writer} to write to. * @param inputCharsetName the name of the requested charset for the InputStream, null means platform default. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. @@ -1573,7 +1573,7 @@ public static long copy(final Reader reader, final Appendable output, final Char * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. * @since 1.1 - * @deprecated Use {@link #copy(Reader, OutputStream, Charset)} instead + * @deprecated Use {@link #copy(Reader, OutputStream, Charset)} instead. */ @Deprecated public static void copy(final Reader reader, final OutputStream output) throws IOException { @@ -1742,7 +1742,7 @@ public static long copyLarge(final InputStream inputStream, final OutputStream o * * @param inputStream the {@link InputStream} to read. * @param outputStream the {@link OutputStream} to write. - * @param buffer the buffer to use for the copy + * @param buffer the buffer to use for the copy. * @return the number of bytes copied. * @throws NullPointerException if the InputStream is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. @@ -2412,7 +2412,7 @@ public static List readLines(final CharSequence csq) throws UncheckedIOE * @throws NullPointerException if the input is null. * @throws UncheckedIOException if an I/O error occurs. * @since 1.1 - * @deprecated Use {@link #readLines(InputStream, Charset)} instead + * @deprecated Use {@link #readLines(InputStream, Charset)} instead. */ @Deprecated public static List readLines(final InputStream input) throws UncheckedIOException { @@ -3190,7 +3190,7 @@ public static byte[] toByteArray(final URLConnection urlConnection) throws IOExc * @throws NullPointerException if the input is null. * @throws IOException if an I/O error occurs. * @since 1.1 - * @deprecated Use {@link #toCharArray(InputStream, Charset)} instead + * @deprecated Use {@link #toCharArray(InputStream, Charset)} instead. */ @Deprecated public static char[] toCharArray(final InputStream inputStream) throws IOException { @@ -3620,7 +3620,7 @@ public static void write(final byte[] data, final OutputStream output) *

    * * @param data the byte array to write, do not modify during output, - * null ignored + * null ignored. * @param writer the {@link Writer} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3640,7 +3640,7 @@ public static void write(final byte[] data, final Writer writer) throws IOExcept *

    * * @param data the byte array to write, do not modify during output, - * null ignored + * null ignored. * @param writer the {@link Writer} to write to. * @param charset the charset to use, null means platform default. * @throws NullPointerException if output is null. @@ -3838,7 +3838,7 @@ public static void write(final CharSequence data, final Writer writer) throws IO * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. * @since 1.1 - * @deprecated Use {@link #write(String, OutputStream, Charset)} instead + * @deprecated Use {@link #write(String, OutputStream, Charset)} instead. */ @Deprecated public static void write(final String data, final OutputStream output) @@ -3920,7 +3920,7 @@ public static void write(final String data, final Writer writer) throws IOExcept * @param data the {@link StringBuffer} to write, null ignored. * @param output the {@link OutputStream} to write to. * @throws NullPointerException if output is null. - * @throws IOException if an I/O error occurs + * @throws IOException if an I/O error occurs. * @since 1.1 * @deprecated Use {@link #write(CharSequence, OutputStream)}. */ @@ -4035,7 +4035,7 @@ public static void writeChunked(final char[] data, final Writer writer) throws I * @throws NullPointerException if the output is null. * @throws IOException if an I/O error occurs. * @since 1.1 - * @deprecated Use {@link #writeLines(Collection, String, OutputStream, Charset)} instead + * @deprecated Use {@link #writeLines(Collection, String, OutputStream, Charset)} instead. */ @Deprecated public static void writeLines(final Collection lines, final String lineEnding, final OutputStream output) throws IOException { diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index 2e1bf0169ab..a96af0f224b 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -77,8 +77,8 @@ public static void closeQuietly(final LineIterator iterator) { /** * Constructs an iterator of the lines for a {@link Reader}. * - * @param reader the {@link Reader} to read from, not null - * @throws NullPointerException if the reader is null + * @param reader the {@link Reader} to read from, not null. + * @throws NullPointerException if the reader is null. */ @SuppressWarnings("resource") // Caller closes Reader public LineIterator(final Reader reader) { @@ -111,8 +111,8 @@ public void close() throws IOException { * If there is an {@link IOException} then {@link #close()} will * be called on this instance. * - * @return {@code true} if the Reader has more lines - * @throws IllegalStateException if an IO exception occurs + * @return {@code true} if the Reader has more lines. + * @throws IllegalStateException if an IO exception occurs. */ @Override public boolean hasNext() { @@ -142,8 +142,8 @@ public boolean hasNext() { /** * Overridable method to validate each line that is returned. * This implementation always returns true. - * @param line the line that is to be validated - * @return true if valid, false to remove from the iterator + * @param line the line that is to be validated. + * @return true if valid, false to remove from the iterator. */ protected boolean isValidLine(final String line) { return true; @@ -152,8 +152,8 @@ protected boolean isValidLine(final String line) { /** * Returns the next line in the wrapped {@link Reader}. * - * @return the next line from the input - * @throws NoSuchElementException if there is no line to return + * @return the next line from the input. + * @throws NoSuchElementException if there is no line to return. */ @Override public String next() { @@ -163,8 +163,8 @@ public String next() { /** * Returns the next line in the wrapped {@link Reader}. * - * @return the next line from the input - * @throws NoSuchElementException if there is no line to return + * @return the next line from the input. + * @throws NoSuchElementException if there is no line to return. * @deprecated Use {@link #next()}. */ @Deprecated @@ -180,7 +180,7 @@ public String nextLine() { /** * Unsupported. * - * @throws UnsupportedOperationException always + * @throws UnsupportedOperationException always. */ @Override public void remove() { diff --git a/src/main/java/org/apache/commons/io/RandomAccessFileMode.java b/src/main/java/org/apache/commons/io/RandomAccessFileMode.java index 88f499d120b..ea44bfa6cba 100644 --- a/src/main/java/org/apache/commons/io/RandomAccessFileMode.java +++ b/src/main/java/org/apache/commons/io/RandomAccessFileMode.java @@ -195,8 +195,8 @@ public T apply(final Path file, final IOFunction functi * Prefer {@link #create(Path)} over this. *

    * - * @param file the file object - * @return a random access file + * @param file the file object. + * @return a random access file. * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}. */ public RandomAccessFile create(final File file) throws FileNotFoundException { @@ -206,8 +206,8 @@ public RandomAccessFile create(final File file) throws FileNotFoundException { /** * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument. * - * @param file the file object - * @return a random access file + * @param file the file object. + * @return a random access file. * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}. */ public RandomAccessFile create(final Path file) throws FileNotFoundException { @@ -220,8 +220,8 @@ public RandomAccessFile create(final Path file) throws FileNotFoundException { * Prefer {@link #create(Path)} over this. *

    * - * @param name the file object - * @return a random access file + * @param name the file object. + * @return a random access file. * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}. */ public RandomAccessFile create(final String name) throws FileNotFoundException { @@ -282,8 +282,8 @@ public boolean implies(final RandomAccessFileMode other) { /** * Constructs a random access file to read from, and optionally to write to, the file specified by the {@link File} argument. * - * @param name the file object - * @return a random access file + * @param name the file object. + * @return a random access file. * @throws FileNotFoundException See {@link IORandomAccessFile#IORandomAccessFile(File, String)}. * @since 2.18.0 */ diff --git a/src/main/java/org/apache/commons/io/TaggedIOException.java b/src/main/java/org/apache/commons/io/TaggedIOException.java index 5eb0b5df596..d997ecc0433 100644 --- a/src/main/java/org/apache/commons/io/TaggedIOException.java +++ b/src/main/java/org/apache/commons/io/TaggedIOException.java @@ -57,8 +57,8 @@ public class TaggedIOException extends IOExceptionWithCause { * } * * - * @param throwable The Throwable object to check - * @param tag tag object + * @param throwable The Throwable object to check. + * @param tag tag object. * @return {@code true} if the throwable has the specified tag, * otherwise {@code false} */ @@ -86,9 +86,9 @@ public static boolean isTaggedWith(final Throwable throwable, final Object tag) * } * * - * @param throwable an exception - * @param tag tag object - * @throws IOException original exception from the tagged decorator, if any + * @param throwable an exception. + * @param tag tag object. + * @throws IOException original exception from the tagged decorator, if any. */ public static void throwCauseIfTaggedWith(final Throwable throwable, final Object tag) throws IOException { @@ -105,8 +105,8 @@ public static void throwCauseIfTaggedWith(final Throwable throwable, final Objec /** * Constructs a tagged wrapper for the given exception. * - * @param original the exception to be tagged - * @param tag tag of this exception + * @param original the exception to be tagged. + * @param tag tag of this exception. */ public TaggedIOException(final IOException original, final Serializable tag) { super(original.getMessage(), original); @@ -117,7 +117,7 @@ public TaggedIOException(final IOException original, final Serializable tag) { * Returns the wrapped exception. The only difference to the overridden * {@link Throwable#getCause()} method is the narrower return type. * - * @return wrapped exception + * @return wrapped exception. */ @Override public synchronized IOException getCause() { @@ -127,7 +127,7 @@ public synchronized IOException getCause() { /** * Returns the serializable tag object. * - * @return tag object + * @return tag object. */ public Serializable getTag() { return tag; diff --git a/src/main/java/org/apache/commons/io/ThreadMonitor.java b/src/main/java/org/apache/commons/io/ThreadMonitor.java index 4c2c37a2d3b..37e7bfabe71 100644 --- a/src/main/java/org/apache/commons/io/ThreadMonitor.java +++ b/src/main/java/org/apache/commons/io/ThreadMonitor.java @@ -52,7 +52,7 @@ static Thread start(final Duration timeout) { /** * Starts monitoring the specified thread. * - * @param thread The thread to monitor + * @param thread The thread to monitor. * @param timeout The timeout amount. or no timeout if the value is zero or less. * @return The monitor thread or {@code null} if the timeout amount is not greater than zero. */ diff --git a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java index d8edc15ea46..341c442a657 100644 --- a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java +++ b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java @@ -1102,7 +1102,7 @@ public byte[] getByteArray() throws IOException { * @param length How many bytes to copy. * @return this origin as a byte array, if possible. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. - * @throws ArithmeticException if the {@code position} overflows an int + * @throws ArithmeticException if the {@code position} overflows an int. * @throws IOException if an I/O error occurs. * @since 2.13.0 */ @@ -1176,7 +1176,7 @@ public File getFile() { /** * Gets this origin as an InputStream, if possible. * - * @param options options specifying how the file is opened + * @param options options specifying how the file is opened. * @return this origin as an InputStream, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. @@ -1188,7 +1188,7 @@ public InputStream getInputStream(final OpenOption... options) throws IOExceptio /** * Gets this origin as an OutputStream, if possible. * - * @param options options specifying how the file is opened + * @param options options specifying how the file is opened. * @return this origin as an OutputStream, if possible. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. @@ -1243,8 +1243,8 @@ private String getSimpleClassName() { /** * Gets a new Writer on the origin, buffered by default. * - * @param charset the charset to use for encoding - * @param options options specifying how the file is opened + * @param charset the charset to use for encoding. + * @param options options specifying how the file is opened. * @return a new Writer on the origin. * @throws IOException if an I/O error occurs opening or creating the file. * @throws UnsupportedOperationException if the origin cannot be converted to a Path. 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 541548c7295..50505d97716 100644 --- a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java +++ b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java @@ -142,7 +142,7 @@ public C getChannel(final Class channelType) throws IOExc /** * Gets a CharSequence from the origin with a Charset. * - * @return An input stream + * @return An input stream. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to a CharSequence. * @throws IOException if an I/O error occurs. @@ -174,7 +174,7 @@ public Charset getCharsetDefault() { /** * Gets a File from the origin. * - * @return A File + * @return A File. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to a {@link File}. * @see AbstractOrigin#getPath() @@ -187,7 +187,7 @@ public File getFile() { /** * Gets an InputStream from the origin with OpenOption[]. * - * @return An input stream + * @return An input stream. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to an {@link InputStream}. * @throws IOException if an I/O error occurs. @@ -211,7 +211,7 @@ public OpenOption[] getOpenOptions() { /** * Gets an OutputStream from the origin with OpenOption[]. * - * @return An OutputStream + * @return An OutputStream. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to an {@link OutputStream}. * @throws IOException if an I/O error occurs. @@ -226,7 +226,7 @@ public OutputStream getOutputStream() throws IOException { /** * Gets a Path from the origin. * - * @return A Path + * @return A Path. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to a {@link Path}. * @see AbstractOrigin#getPath() @@ -239,7 +239,7 @@ public Path getPath() { /** * Gets a RandomAccessFile from the origin. * - * @return A RandomAccessFile + * @return A RandomAccessFile. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to a {@link RandomAccessFile}. * @throws IOException if an I/O error occurs. @@ -252,7 +252,7 @@ public RandomAccessFile getRandomAccessFile() throws IOException { /** * Gets a Reader from the origin with a Charset. * - * @return A Reader + * @return A Reader. * @throws IllegalStateException if the {@code origin} is {@code null}. * @throws UnsupportedOperationException if the origin cannot be converted to a {@link Reader}. * @throws IOException if an I/O error occurs. diff --git a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java index 2cd8009203f..83cf9dea193 100644 --- a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java +++ b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java @@ -56,7 +56,7 @@ public class ByteArraySeekableByteChannel implements SeekableByteChannel { * automatically allocate a larger backing array and copy the existing contents.

    * * @param bytes The byte array to wrap, must not be {@code null} - * @return A new channel that uses the given array as its initial backing store + * @return A new channel that uses the given array as its initial backing store. * @throws NullPointerException If {@code bytes} is {@code null} * @see #array() * @see ByteArrayInputStream#ByteArrayInputStream(byte[]) diff --git a/src/main/java/org/apache/commons/io/channels/FileChannels.java b/src/main/java/org/apache/commons/io/channels/FileChannels.java index 30a80e8ab6b..b529c281e11 100644 --- a/src/main/java/org/apache/commons/io/channels/FileChannels.java +++ b/src/main/java/org/apache/commons/io/channels/FileChannels.java @@ -135,7 +135,7 @@ public static boolean contentEquals(final SeekableByteChannel channel1, final Se * * @param channel The source channel. * @param dst The buffer into which bytes are to be transferred. - * @return The number of bytes read, never zero, or {@code -1} if the channel has reached end-of-stream + * @return The number of bytes read, never zero, or {@code -1} if the channel has reached end-of-stream. * @throws IOException If some other I/O error occurs. * @throws IllegalArgumentException If there is room in the given buffer. */ diff --git a/src/main/java/org/apache/commons/io/comparator/CompositeFileComparator.java b/src/main/java/org/apache/commons/io/comparator/CompositeFileComparator.java index 0934f895f7a..dcc2d20428e 100644 --- a/src/main/java/org/apache/commons/io/comparator/CompositeFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/CompositeFileComparator.java @@ -58,7 +58,7 @@ public class CompositeFileComparator extends AbstractFileComparator implements S /** * Constructs a composite comparator for the set of delegate comparators. * - * @param delegates The delegate file comparators + * @param delegates The delegate file comparators. */ public CompositeFileComparator(@SuppressWarnings("unchecked") final Comparator... delegates) { this.delegates = delegates == null ? emptyArray() : delegates.clone(); @@ -67,7 +67,7 @@ public CompositeFileComparator(@SuppressWarnings("unchecked") final Comparator> delegates) { this.delegates = delegates == null ? emptyArray() @@ -77,8 +77,8 @@ public CompositeFileComparator(final Iterable> delegates) { /** * Compares the two files using delegate comparators. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return the first non-zero result returned from the delegate comparators or zero. */ @Override @@ -94,7 +94,7 @@ private Comparator[] emptyArray() { /** * String representation of this file comparator. * - * @return String representation of this file comparator + * @return String representation of this file comparator. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/comparator/DefaultFileComparator.java b/src/main/java/org/apache/commons/io/comparator/DefaultFileComparator.java index c447f085198..db580a1a2e1 100644 --- a/src/main/java/org/apache/commons/io/comparator/DefaultFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/DefaultFileComparator.java @@ -69,8 +69,8 @@ public DefaultFileComparator() { /** * Compares the two files using the {@link File#compareTo(File)} method. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return the result of calling file1's * {@link File#compareTo(File)} with file2 as the parameter. */ diff --git a/src/main/java/org/apache/commons/io/comparator/ExtensionFileComparator.java b/src/main/java/org/apache/commons/io/comparator/ExtensionFileComparator.java index 3b4e1e2e115..1d57ec8164f 100644 --- a/src/main/java/org/apache/commons/io/comparator/ExtensionFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/ExtensionFileComparator.java @@ -93,7 +93,7 @@ public ExtensionFileComparator() { /** * Constructs a file extension comparator instance with the specified case-sensitivity. * - * @param ioCase how to handle case sensitivity, null means case-sensitive + * @param ioCase how to handle case sensitivity, null means case-sensitive. */ public ExtensionFileComparator(final IOCase ioCase) { this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); @@ -102,8 +102,8 @@ public ExtensionFileComparator(final IOCase ioCase) { /** * Compares the extensions of two files the specified case sensitivity. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return a negative value if the first file's extension * is less than the second, zero if the extensions are the * same and a positive value if the first files extension @@ -119,7 +119,7 @@ public int compare(final File file1, final File file2) { /** * String representation of this file comparator. * - * @return String representation of this file comparator + * @return String representation of this file comparator. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/comparator/NameFileComparator.java b/src/main/java/org/apache/commons/io/comparator/NameFileComparator.java index 41590fa6636..7e92a7fcb74 100644 --- a/src/main/java/org/apache/commons/io/comparator/NameFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/NameFileComparator.java @@ -89,7 +89,7 @@ public NameFileComparator() { /** * Constructs a file name comparator instance with the specified case-sensitivity. * - * @param ioCase how to handle case sensitivity, null means case-sensitive + * @param ioCase how to handle case sensitivity, null means case-sensitive. */ public NameFileComparator(final IOCase ioCase) { this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); @@ -98,8 +98,8 @@ public NameFileComparator(final IOCase ioCase) { /** * Compares the names of two files with the specified case sensitivity. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return a negative value if the first file's name * is less than the second, zero if the names are the * same and a positive value if the first files name @@ -113,7 +113,7 @@ public int compare(final File file1, final File file2) { /** * String representation of this file comparator. * - * @return String representation of this file comparator + * @return String representation of this file comparator. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java b/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java index 1f41eb74185..dc4fb296049 100644 --- a/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java @@ -88,7 +88,7 @@ public PathFileComparator() { /** * Constructs a file path comparator instance with the specified case-sensitivity. * - * @param ioCase how to handle case sensitivity, null means case-sensitive + * @param ioCase how to handle case sensitivity, null means case-sensitive. */ public PathFileComparator(final IOCase ioCase) { this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE); @@ -97,8 +97,8 @@ public PathFileComparator(final IOCase ioCase) { /** * Compares the paths of two files the specified case sensitivity. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return a negative value if the first file's path * is less than the second, zero if the paths are the * same and a positive value if the first files path @@ -112,7 +112,7 @@ public int compare(final File file1, final File file2) { /** * String representation of this file comparator. * - * @return String representation of this file comparator + * @return String representation of this file comparator. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/comparator/SizeFileComparator.java b/src/main/java/org/apache/commons/io/comparator/SizeFileComparator.java index 5154d9b3256..a5ff78c0e59 100644 --- a/src/main/java/org/apache/commons/io/comparator/SizeFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/SizeFileComparator.java @@ -107,8 +107,8 @@ public SizeFileComparator(final boolean sumDirectoryContents) { /** * Compares the length of two files. * - * @param file1 The first file to compare - * @param file2 The second file to compare + * @param file1 The first file to compare. + * @param file2 The second file to compare. * @return a negative value if the first file's length * is less than the second, zero if the lengths are the * same and a positive value if the first files length @@ -141,7 +141,7 @@ public int compare(final File file1, final File file2) { /** * String representation of this file comparator. * - * @return String representation of this file comparator + * @return String representation of this file comparator. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java index 5465e4dd569..3be7a325315 100644 --- a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java @@ -250,10 +250,10 @@ public int hashCode() { * Relativizes each directory path with {@link Path#relativize(Path)} against the given {@code parent}, optionally * sorting the result. * - * @param parent A parent path - * @param sort Whether to sort + * @param parent A parent path. + * @param sort Whether to sort. * @param comparator How to sort, null uses default sorting. - * @return A new list + * @return A new list. */ public List relativizeDirectories(final Path parent, final boolean sort, final Comparator comparator) { @@ -264,10 +264,10 @@ public List relativizeDirectories(final Path parent, final boolean sort, * Relativizes each file path with {@link Path#relativize(Path)} against the given {@code parent}, optionally * sorting the result. * - * @param parent A parent path - * @param sort Whether to sort + * @param parent A parent path. + * @param sort Whether to sort. * @param comparator How to sort, null uses default sorting. - * @return A new list + * @return A new list. */ public List relativizeFiles(final Path parent, final boolean sort, final Comparator comparator) { diff --git a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java index 7172b2d0671..45b761c971c 100644 --- a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java +++ b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java @@ -48,8 +48,8 @@ private static CopyOption[] toCopyOption(final CopyOption... copyOptions) { * Constructs an instance that copies all files. * * @param pathCounter How to count visits. - * @param sourceDirectory The source directory - * @param targetDirectory The target directory + * @param sourceDirectory The source directory. + * @param targetDirectory The target directory. * @param copyOptions Specifies how the copying should be done. */ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDirectory, final Path targetDirectory, final CopyOption... copyOptions) { @@ -65,8 +65,8 @@ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDir * @param pathCounter How to count visits. * @param fileFilter How to filter file paths. * @param dirFilter How to filter directory paths. - * @param sourceDirectory The source directory - * @param targetDirectory The target directory + * @param sourceDirectory The source directory. + * @param targetDirectory The target directory. * @param copyOptions Specifies how the copying should be done. * @since 2.9.0 */ diff --git a/src/main/java/org/apache/commons/io/file/Counters.java b/src/main/java/org/apache/commons/io/file/Counters.java index b1abd721d9c..10e05dc48f7 100644 --- a/src/main/java/org/apache/commons/io/file/Counters.java +++ b/src/main/java/org/apache/commons/io/file/Counters.java @@ -455,7 +455,7 @@ public static PathCounters noopPathCounters() { /** * Construct a new instance. * - * @deprecated Will be private in 4.0 + * @deprecated Will be private in 3.0. */ @Deprecated public Counters() { diff --git a/src/main/java/org/apache/commons/io/file/PathFilter.java b/src/main/java/org/apache/commons/io/file/PathFilter.java index dbeef906261..ee54de29deb 100644 --- a/src/main/java/org/apache/commons/io/file/PathFilter.java +++ b/src/main/java/org/apache/commons/io/file/PathFilter.java @@ -34,7 +34,7 @@ public interface PathFilter { * * @param path The Path to test. * @param attributes the path's basic attributes (may be null). - * @return a FileVisitResult + * @return a FileVisitResult. */ FileVisitResult accept(Path path, BasicFileAttributes attributes); } diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java index 6672df7ac71..c943f5f9e4d 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -378,7 +378,7 @@ public static PathCounters copyDirectory(final Path sourceDirectory, final Path * @param sourceFile The source URL. * @param targetFile The target file. * @param copyOptions Specifies how the copying should be done. - * @return The target file + * @return The target file. * @throws IOException if an I/O error occurs. * @see Files#copy(InputStream, Path, CopyOption...) */ @@ -393,7 +393,7 @@ public static Path copyFile(final URL sourceFile, final Path targetFile, final C * @param sourceFile The source file. * @param targetDirectory The target directory. * @param copyOptions Specifies how the copying should be done. - * @return The target file + * @return The target file. * @throws IOException if an I/O error occurs. * @see Files#copy(Path, Path, CopyOption...) */ @@ -410,7 +410,7 @@ public static Path copyFileToDirectory(final Path sourceFile, final Path targetD * @param sourceFile The source URL. * @param targetDirectory The target directory. * @param copyOptions Specifies how the copying should be done. - * @return The target file + * @return The target file. * @throws IOException if an I/O error occurs. * @see Files#copy(InputStream, Path, CopyOption...) */ @@ -603,7 +603,7 @@ public static PathCounters deleteDirectory(final Path directory, final LinkOptio * @param file The file to delete. * @return A visitor with path counts set to 1 file, 0 directories, and the size of the deleted file. * @throws IOException if an I/O error occurs. - * @throws NoSuchFileException if the file is a directory + * @throws NoSuchFileException if the file is a directory. */ public static PathCounters deleteFile(final Path file) throws IOException { return deleteFile(file, EMPTY_DELETE_OPTION_ARRAY); @@ -771,7 +771,7 @@ public static boolean directoryContentEquals(final Path path1, final Path path2) * @param path2 The second directory. * @param maxDepth See {@link Files#walkFileTree(Path,Set,int,FileVisitor)}. * @param linkOptions options to follow links. - * @param fileVisitOptions options to configure the traversal + * @param fileVisitOptions options to configure the traversal. * @return Whether the two directories contain the same files without considering file contents. * @throws IOException if an I/O error is thrown by a visitor method. */ @@ -944,7 +944,7 @@ public static AclFileAttributeView getAclFileAttributeView(final Path path, fina * Will return the file name itself if it doesn't contain any periods. All leading directories of the {@code file name} parameter are skipped. *

    * - * @return the base name of file name + * @return the base name of file name. * @param path the path of the file to obtain the base name of. * @since 2.16.0 */ @@ -1136,7 +1136,7 @@ public static Path getTempDirectory() { * {@code Files.isDirectory(Path path, LinkOption... options)}. * * @param path the path to the file. - * @param options options indicating how to handle symbolic links + * @param options options indicating how to handle symbolic links. * @return {@code true} if the file is a directory; {@code false} if the path is null, the file does not exist, is not a directory, or it cannot be * determined if the file is a directory or not. * @throws SecurityException In the case of the default provider, and a security manager is installed, the {@link SecurityManager#checkRead(String) @@ -1240,7 +1240,7 @@ public static boolean isNewer(final Path file, final Instant instant, final Link * Tests if the given {@link Path} is newer than the given time reference. * * @param file the {@link Path} to test. - * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970) + * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970). * @param options options indicating how to handle symbolic links. * @return true if the {@link Path} exists and has been modified after the given time reference. * @throws IOException if an I/O error occurs. @@ -1301,7 +1301,7 @@ public static boolean isOlder(final Path file, final Instant instant, final Link * Tests if the given {@link Path} is older than the given time reference. * * @param file the {@link Path} to test. - * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970) + * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970). * @param options options indicating how to handle symbolic links. * @return true if the {@link Path} exists and has been modified before the given time reference. * @throws IOException if an I/O error occurs. @@ -1425,7 +1425,7 @@ private static boolean overrideReadOnly(final DeleteOption... deleteOptions) { /** * Reads the BasicFileAttributes from the given path. Returns null if the attributes can't be read. * - * @param The {@link BasicFileAttributes} type + * @param The {@link BasicFileAttributes} type. * @param path The Path to test. * @param type the {@link Class} of the file attributes required to read. * @param options options indicating how to handle symbolic links. @@ -1827,7 +1827,7 @@ private static List toSortedList(final Iterable rootDirectories) { * @param file the file to touch. * @return The given file. * @throws NullPointerException if the parameter is {@code null}. - * @throws IOException if setting the last-modified time failed or an I/O problem occurs.\ + * @throws IOException if setting the last-modified time failed or an I/O problem occurs. * @since 2.12.0 */ public static Path touch(final Path file) throws IOException { @@ -1957,8 +1957,8 @@ public static boolean waitFor(final Path file, final Duration timeout, final Lin * closed stream causes a {@link IllegalStateException}. *

    * - * @param start the start path - * @param pathFilter the path filter + * @param start the start path. + * @param pathFilter the path filter. * @param maxDepth the maximum depth of directories to walk. * @param readAttributes whether to call the filters with file attributes (false passes null). * @param options the options to configure the walk. diff --git a/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java b/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java index 35725357f9c..2878d8752d7 100644 --- a/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java +++ b/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java @@ -308,7 +308,7 @@ static long toNtfsTime(final Instant instant) { * An NTFS file time is a 64-bit value for the number of 100-nanosecond intervals since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC). *

    * - * @param javaTime the Java time + * @param javaTime the Java time. * @return the NTFS time, 100-nanosecond units since 1 January 1601. * @since 2.16.0 */ diff --git a/src/main/java/org/apache/commons/io/file/spi/FileSystemProviders.java b/src/main/java/org/apache/commons/io/file/spi/FileSystemProviders.java index 2483cef0a20..4e83ffe1e8c 100644 --- a/src/main/java/org/apache/commons/io/file/spi/FileSystemProviders.java +++ b/src/main/java/org/apache/commons/io/file/spi/FileSystemProviders.java @@ -39,7 +39,7 @@ public class FileSystemProviders { // NOPMD Class will be final in 3.0. /** * Gets the {@link FileSystemProvider} for the given Path. * - * @param path The Path to query + * @param path The Path to query. * @return the {@link FileSystemProvider} for the given Path. */ @SuppressWarnings("resource") // FileSystem is not allocated here. @@ -86,7 +86,7 @@ public FileSystemProvider getFileSystemProvider(final String scheme) { /** * Gets the {@link FileSystemProvider} for the given URI. * - * @param uri The URI to query + * @param uri The URI to query. * @return the {@link FileSystemProvider} for the given URI or null. */ public FileSystemProvider getFileSystemProvider(final URI uri) { @@ -96,7 +96,7 @@ public FileSystemProvider getFileSystemProvider(final URI uri) { /** * Gets the {@link FileSystemProvider} for the given URL. * - * @param url The URL to query + * @param url The URL to query. * @return the {@link FileSystemProvider} for the given URI or null. */ public FileSystemProvider getFileSystemProvider(final URL url) { diff --git a/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java index c71867d14da..b16e86eaf14 100644 --- a/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java @@ -77,8 +77,8 @@ protected AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResu /** * Tests to see if the File should be accepted by this filter. * - * @param file the File to check - * @return true if this file matches the test + * @param file the File to check. + * @return true if this file matches the test. */ @Override public boolean accept(final File file) { @@ -89,9 +89,9 @@ public boolean accept(final File file) { /** * Tests to see if the File should be accepted by this filter. * - * @param dir the directory File to check - * @param name the file name within the directory to check - * @return true if this file matches the test + * @param dir the directory File to check. + * @param name the file name within the directory to check. + * @return true if this file matches the test. */ @Override public boolean accept(final File dir, final String name) { @@ -167,7 +167,7 @@ FileVisitResult toFileVisitResult(final boolean accept) { /** * Provides a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/AgeFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/AgeFileFilter.java index 35542cfd486..9d95794ce28 100644 --- a/src/main/java/org/apache/commons/io/filefilter/AgeFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/AgeFileFilter.java @@ -89,7 +89,7 @@ public class AgeFileFilter extends AbstractFileFilter implements Serializable { /** * Constructs a new age file filter for files older than (at or before) a certain cutoff date. * - * @param cutoffDate the threshold age of the files + * @param cutoffDate the threshold age of the files. */ public AgeFileFilter(final Date cutoffDate) { this(cutoffDate, true); @@ -98,7 +98,7 @@ public AgeFileFilter(final Date cutoffDate) { /** * Constructs a new age file filter for files on any one side of a certain cutoff date. * - * @param cutoffDate the threshold age of the files + * @param cutoffDate the threshold age of the files. * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the * cutoff). */ @@ -110,7 +110,7 @@ public AgeFileFilter(final Date cutoffDate, final boolean acceptOlder) { * Constructs a new age file filter for files older than (at or before) a certain File (whose last modification time * will be used as reference). * - * @param cutoffReference the file whose last modification time is used as the threshold age of the files + * @param cutoffReference the file whose last modification time is used as the threshold age of the files. */ public AgeFileFilter(final File cutoffReference) { this(cutoffReference, true); @@ -120,7 +120,7 @@ public AgeFileFilter(final File cutoffReference) { * Constructs a new age file filter for files on any one side of a certain File (whose last modification time will * be used as reference). * - * @param cutoffReference the file whose last modification time is used as the threshold age of the files + * @param cutoffReference the file whose last modification time is used as the threshold age of the files. * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the * cutoff). */ @@ -179,8 +179,8 @@ public AgeFileFilter(final long cutoffMillis, final boolean acceptOlder) { * modification time equals cutoff and older files are required, file IS selected. *

    * - * @param file the File to check - * @return true if the file name matches + * @param file the File to check. + * @return true if the file name matches. */ @Override public boolean accept(final File file) { @@ -194,9 +194,9 @@ public boolean accept(final File file) { * modification time equals cutoff and older files are required, file IS selected. *

    * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name matches + * @return true if the file name matches. * @since 2.9.0 */ @Override @@ -207,7 +207,7 @@ public FileVisitResult accept(final Path file, final BasicFileAttributes attribu /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java index f8da16bcb0e..2db3e46f5a8 100644 --- a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java @@ -90,9 +90,9 @@ public AndFileFilter(final IOFileFilter... fileFilters) { /** * Constructs a new file filter that ANDs the result of other filters. * - * @param filter1 the first filter, must second be null - * @param filter2 the first filter, must not be null - * @throws IllegalArgumentException if either filter is null + * @param filter1 the first filter, must second be null. + * @param filter2 the first filter, must not be null. + * @throws IllegalArgumentException if either filter is null. */ public AndFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { this(2); @@ -187,7 +187,7 @@ public void setFileFilters(final List fileFilters) { /** * Builds a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java index 899481c6465..f06915cc239 100644 --- a/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java @@ -75,7 +75,7 @@ protected CanWriteFileFilter() { /** * Tests to see if the file can be written to. * - * @param file the File to check + * @param file the File to check. * @return {@code true} if the file can be written to, otherwise {@code false}. */ @Override @@ -86,7 +86,7 @@ public boolean accept(final File file) { /** * Tests to see if the file can be written to. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). * @return {@code true} if the file can be written to, otherwise {@code false}. * @since 2.9.0 diff --git a/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java index d59996a0461..96ff4947b5c 100644 --- a/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/ConditionalFileFilter.java @@ -29,7 +29,7 @@ public interface ConditionalFileFilter { * Adds the specified file filter to the list of file filters at the end of * the list. * - * @param ioFileFilter the filter to be added + * @param ioFileFilter the filter to be added. * @since 1.1 */ void addFileFilter(IOFileFilter ioFileFilter); @@ -37,7 +37,7 @@ public interface ConditionalFileFilter { /** * Gets this conditional file filter's list of file filters. * - * @return the file filter list + * @return the file filter list. * @since 1.1 */ List getFileFilters(); @@ -45,9 +45,9 @@ public interface ConditionalFileFilter { /** * Removes the specified file filter. * - * @param ioFileFilter filter to be removed + * @param ioFileFilter filter to be removed. * @return {@code true} if the filter was found in the list, - * {@code false} otherwise + * {@code false} otherwise. * @since 1.1 */ boolean removeFileFilter(IOFileFilter ioFileFilter); @@ -56,7 +56,7 @@ public interface ConditionalFileFilter { * Sets the list of file filters, replacing any previously configured * file filters on this filter. * - * @param fileFilters the list of filters + * @param fileFilters the list of filters. * @since 1.1 */ void setFileFilters(List fileFilters); diff --git a/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java index 4137644ca1d..f4f414753cb 100644 --- a/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java @@ -45,7 +45,7 @@ public class DelegateFileFilter extends AbstractFileFilter implements Serializab /** * Constructs a delegate file filter around an existing FileFilter. * - * @param fileFilter the filter to decorate + * @param fileFilter the filter to decorate. */ public DelegateFileFilter(final FileFilter fileFilter) { Objects.requireNonNull(fileFilter, "filter"); @@ -56,7 +56,7 @@ public DelegateFileFilter(final FileFilter fileFilter) { /** * Constructs a delegate file filter around an existing FilenameFilter. * - * @param fileNameFilter the filter to decorate + * @param fileNameFilter the filter to decorate. */ public DelegateFileFilter(final FilenameFilter fileNameFilter) { Objects.requireNonNull(fileNameFilter, "filter"); @@ -67,8 +67,8 @@ public DelegateFileFilter(final FilenameFilter fileNameFilter) { /** * Tests the filter. * - * @param file the file to check - * @return true if the filter matches + * @param file the file to check. + * @return true if the filter matches. */ @Override public boolean accept(final File file) { @@ -81,9 +81,9 @@ public boolean accept(final File file) { /** * Tests the filter. * - * @param dir the directory - * @param name the file name in the directory - * @return true if the filter matches + * @param dir the directory. + * @param name the file name in the directory. + * @return true if the filter matches. */ @Override public boolean accept(final File dir, final String name) { @@ -96,7 +96,7 @@ public boolean accept(final File dir, final String name) { /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/DirectoryFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/DirectoryFileFilter.java index bb3d615bd43..b0c54b42ec4 100644 --- a/src/main/java/org/apache/commons/io/filefilter/DirectoryFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/DirectoryFileFilter.java @@ -92,8 +92,8 @@ protected DirectoryFileFilter() { /** * Tests to see if the file is a directory. * - * @param file the File to check - * @return true if the file is a directory + * @param file the File to check. + * @return true if the file is a directory. */ @Override public boolean accept(final File file) { @@ -103,9 +103,9 @@ public boolean accept(final File file) { /** * Tests to see if the file is a directory. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file is a directory + * @return true if the file is a directory. * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/filefilter/EmptyFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/EmptyFileFilter.java index a5cdd676bb1..392d2cf0f12 100644 --- a/src/main/java/org/apache/commons/io/filefilter/EmptyFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/EmptyFileFilter.java @@ -99,7 +99,7 @@ protected EmptyFileFilter() { /** * Tests to see if the file is empty. * - * @param file the file or directory to check + * @param file the file or directory to check. * @return {@code true} if the file or directory is empty, otherwise {@code false}. */ @Override @@ -117,7 +117,7 @@ public boolean accept(final File file) { /** * Tests to see if the file is empty. * - * @param file the file or directory to check + * @param file the file or directory to check. * @param attributes the path's basic attributes (may be null). * @return {@code true} if the file or directory is empty, otherwise {@code false}. * @since 2.9.0 diff --git a/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java index ebaa77b2007..7054a7c68f2 100644 --- a/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java @@ -60,8 +60,8 @@ protected FalseFileFilter() { /** * Returns false. * - * @param file the file to check (ignored) - * @return false + * @param file the file to check (ignored). + * @return false. */ @Override public boolean accept(final File file) { @@ -71,9 +71,9 @@ public boolean accept(final File file) { /** * Returns false. * - * @param dir the directory to check (ignored) - * @param name the file name (ignored) - * @return false + * @param dir the directory to check (ignored). + * @param name the file name (ignored). + * @return false. */ @Override public boolean accept(final File dir, final String name) { @@ -83,9 +83,9 @@ public boolean accept(final File dir, final String name) { /** * Returns false. * - * @param file the file to check (ignored) + * @param file the file to check (ignored). * @param attributes the path's basic attributes (may be null). - * @return false + * @return {@link FileVisitResult#TERMINATE}. * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java index 801d39f07b4..4bab6adf49e 100644 --- a/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/FileFileFilter.java @@ -92,8 +92,8 @@ protected FileFileFilter() { /** * Tests to see if the file is a file. * - * @param file the File to check - * @return true if the file is a file + * @param file the File to check. + * @return true if the file is a file. */ @Override public boolean accept(final File file) { @@ -103,9 +103,9 @@ public boolean accept(final File file) { /** * Tests to see if the file is a file. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file is a file + * @return true if the file is a file. * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java index 937895c822c..587bb4226ee 100644 --- a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java +++ b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java @@ -55,8 +55,8 @@ public class FileFilterUtils { * Returns a filter that returns true if the file was last modified before * or at the specified cutoff date. * - * @param cutoffDate the time threshold - * @return an appropriately configured age file filter + * @param cutoffDate the time threshold. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -67,9 +67,9 @@ public static IOFileFilter ageFileFilter(final Date cutoffDate) { /** * Returns a filter that filters files based on a cutoff date. * - * @param cutoffDate the time threshold - * @param acceptOlder if true, older files get accepted, if false, newer - * @return an appropriately configured age file filter + * @param cutoffDate the time threshold. + * @param acceptOlder if true, older files get accepted, if false, newer. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -82,8 +82,8 @@ public static IOFileFilter ageFileFilter(final Date cutoffDate, final boolean ac * or at the same time as the specified reference file. * * @param cutoffReference the file whose last modification - * time is used as the threshold age of the files - * @return an appropriately configured age file filter + * time is used as the threshold age of the files. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -95,9 +95,9 @@ public static IOFileFilter ageFileFilter(final File cutoffReference) { * Returns a filter that filters files based on a cutoff reference file. * * @param cutoffReference the file whose last modification - * time is used as the threshold age of the files - * @param acceptOlder if true, older files get accepted, if false, newer - * @return an appropriately configured age file filter + * time is used as the threshold age of the files. + * @param acceptOlder if true, older files get accepted, if false, newer. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -109,8 +109,8 @@ public static IOFileFilter ageFileFilter(final File cutoffReference, final boole * Returns a filter that returns true if the file was last modified before * or at the specified cutoff time. * - * @param cutoffMillis the time threshold - * @return an appropriately configured age file filter + * @param cutoffMillis the time threshold. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -121,9 +121,9 @@ public static IOFileFilter ageFileFilter(final long cutoffMillis) { /** * Returns a filter that filters files based on a cutoff time. * - * @param cutoffMillis the time threshold - * @param acceptOlder if true, older files get accepted, if false, newer - * @return an appropriately configured age file filter + * @param cutoffMillis the time threshold. + * @param acceptOlder if true, older files get accepted, if false, newer. + * @return an appropriately configured age file filter. * @see AgeFileFilter * @since 1.2 */ @@ -135,7 +135,7 @@ public static IOFileFilter ageFileFilter(final long cutoffMillis, final boolean * Returns a filter that ANDs the specified filters. * * @param filters the IOFileFilters that will be ANDed together. - * @return a filter that ANDs the specified filters + * @return a filter that ANDs the specified filters. * @throws IllegalArgumentException if the filters are null or contain a * null value. * @see AndFileFilter @@ -148,9 +148,9 @@ public static IOFileFilter and(final IOFileFilter... filters) { /** * Returns a filter that ANDs the two specified filters. * - * @param filter1 the first filter - * @param filter2 the second filter - * @return a filter that ANDs the two specified filters + * @param filter1 the first filter. + * @param filter2 the second filter. + * @return a filter that ANDs the two specified filters. * @see #and(IOFileFilter...) * @see AndFileFilter * @deprecated Use {@link #and(IOFileFilter...)} @@ -164,8 +164,8 @@ public static IOFileFilter andFileFilter(final IOFileFilter filter1, final IOFil * Returns an {@link IOFileFilter} that wraps the * {@link FileFilter} instance. * - * @param filter the filter to be wrapped - * @return a new filter that implements IOFileFilter + * @param filter the filter to be wrapped. + * @return a new filter that implements IOFileFilter. * @see DelegateFileFilter */ public static IOFileFilter asFileFilter(final FileFilter filter) { @@ -176,8 +176,8 @@ public static IOFileFilter asFileFilter(final FileFilter filter) { * Returns an {@link IOFileFilter} that wraps the * {@link FilenameFilter} instance. * - * @param filter the filter to be wrapped - * @return a new filter that implements IOFileFilter + * @param filter the filter to be wrapped. + * @return a new filter that implements IOFileFilter. * @see DelegateFileFilter */ public static IOFileFilter asFileFilter(final FilenameFilter filter) { @@ -187,7 +187,7 @@ public static IOFileFilter asFileFilter(final FilenameFilter filter) { /** * Returns a filter that checks if the file is a directory. * - * @return file filter that accepts only directories and not files + * @return file filter that accepts only directories and not files. * @see DirectoryFileFilter#DIRECTORY */ public static IOFileFilter directoryFileFilter() { @@ -197,7 +197,7 @@ public static IOFileFilter directoryFileFilter() { /** * Returns a filter that always returns false. * - * @return a false filter + * @return a false filter. * @see FalseFileFilter#FALSE */ public static IOFileFilter falseFileFilter() { @@ -207,7 +207,7 @@ public static IOFileFilter falseFileFilter() { /** * Returns a filter that checks if the file is a file (and not a directory). * - * @return file filter that accepts only files and not directories + * @return file filter that accepts only files and not directories. * @see FileFileFilter#INSTANCE */ public static IOFileFilter fileFileFilter() { @@ -281,7 +281,7 @@ public static File[] filter(final IOFileFilter filter, final Iterable file * @param stream the stream of files on which to apply the filter. * @param collector how to collect the end result. * @param the return type. - * @param
    the mutable accumulation type of the reduction operation (often hidden as an implementation detail) + * @param the mutable accumulation type of the reduction operation (often hidden as an implementation detail). * @return a subset of files from the stream that is accepted by the filter. * @throws NullPointerException if the filter is {@code null}. */ @@ -495,8 +495,8 @@ public static IOFileFilter magicNumberFileFilter(final String magicNumber, final * Passing in {@code null} will return a filter that accepts everything * except CVS directories. * - * @param filter the filter to decorate, null means an unrestricted filter - * @return the decorated filter, never null + * @param filter the filter to decorate, null means an unrestricted filter. + * @return the decorated filter, never null. * @since 1.1 (method existed but had a bug in 1.0) */ public static IOFileFilter makeCVSAware(final IOFileFilter filter) { @@ -506,8 +506,8 @@ public static IOFileFilter makeCVSAware(final IOFileFilter filter) { /** * Decorates a filter so that it only applies to directories and not to files. * - * @param filter the filter to decorate, null means an unrestricted filter - * @return the decorated filter, never null + * @param filter the filter to decorate, null means an unrestricted filter. + * @return the decorated filter, never null. * @see DirectoryFileFilter#DIRECTORY * @since 1.3 */ @@ -521,8 +521,8 @@ public static IOFileFilter makeDirectoryOnly(final IOFileFilter filter) { /** * Decorates a filter so that it only applies to files and not to directories. * - * @param filter the filter to decorate, null means an unrestricted filter - * @return the decorated filter, never null + * @param filter the filter to decorate, null means an unrestricted filter. + * @return the decorated filter, never null. * @see FileFileFilter#INSTANCE * @since 1.3 */ @@ -538,8 +538,8 @@ public static IOFileFilter makeFileOnly(final IOFileFilter filter) { * Passing in {@code null} will return a filter that accepts everything * except SVN directories. * - * @param filter the filter to decorate, null means an unrestricted filter - * @return the decorated filter, never null + * @param filter the filter to decorate, null means an unrestricted filter. + * @return the decorated filter, never null. * @since 1.1 */ public static IOFileFilter makeSVNAware(final IOFileFilter filter) { @@ -549,8 +549,8 @@ public static IOFileFilter makeSVNAware(final IOFileFilter filter) { /** * Returns a filter that returns true if the file name matches the specified text. * - * @param name the file name - * @return a name checking filter + * @param name the file name. + * @return a name checking filter. * @see NameFileFilter */ public static IOFileFilter nameFileFilter(final String name) { @@ -560,9 +560,9 @@ public static IOFileFilter nameFileFilter(final String name) { /** * Returns a filter that returns true if the file name matches the specified text. * - * @param name the file name - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @return a name checking filter + * @param name the file name. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @return a name checking filter. * @see NameFileFilter * @since 2.0 */ @@ -573,8 +573,8 @@ public static IOFileFilter nameFileFilter(final String name, final IOCase ioCase /** * Returns a filter that NOTs the specified filter. * - * @param filter the filter to invert - * @return a filter that NOTs the specified filter + * @param filter the filter to invert. + * @return a filter that NOTs the specified filter. * @see NotFileFilter */ public static IOFileFilter notFileFilter(final IOFileFilter filter) { @@ -585,7 +585,7 @@ public static IOFileFilter notFileFilter(final IOFileFilter filter) { * Returns a filter that ORs the specified filters. * * @param filters the IOFileFilters that will be ORed together. - * @return a filter that ORs the specified filters + * @return a filter that ORs the specified filters. * @throws IllegalArgumentException if the filters are null or contain a * null value. * @see OrFileFilter @@ -598,9 +598,9 @@ public static IOFileFilter or(final IOFileFilter... filters) { /** * Returns a filter that ORs the two specified filters. * - * @param filter1 the first filter - * @param filter2 the second filter - * @return a filter that ORs the two specified filters + * @param filter1 the first filter. + * @param filter2 the second filter. + * @return a filter that ORs the two specified filters. * @see #or(IOFileFilter...) * @see OrFileFilter * @deprecated Use {@link #or(IOFileFilter...)} @@ -613,8 +613,8 @@ public static IOFileFilter orFileFilter(final IOFileFilter filter1, final IOFile /** * Returns a filter that returns true if the file name starts with the specified text. * - * @param prefix the file name prefix - * @return a prefix checking filter + * @param prefix the file name prefix. + * @return a prefix checking filter. * @see PrefixFileFilter */ public static IOFileFilter prefixFileFilter(final String prefix) { @@ -624,9 +624,9 @@ public static IOFileFilter prefixFileFilter(final String prefix) { /** * Returns a filter that returns true if the file name starts with the specified text. * - * @param prefix the file name prefix - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @return a prefix checking filter + * @param prefix the file name prefix. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @return a prefix checking filter. * @see PrefixFileFilter * @since 2.0 */ @@ -637,8 +637,8 @@ public static IOFileFilter prefixFileFilter(final String prefix, final IOCase io /** * Returns a filter that returns true if the file is bigger than a certain size. * - * @param threshold the file size threshold - * @return an appropriately configured SizeFileFilter + * @param threshold the file size threshold. + * @return an appropriately configured SizeFileFilter. * @see SizeFileFilter * @since 1.2 */ @@ -649,9 +649,9 @@ public static IOFileFilter sizeFileFilter(final long threshold) { /** * Returns a filter that filters based on file size. * - * @param threshold the file size threshold - * @param acceptLarger if true, larger files get accepted, if false, smaller - * @return an appropriately configured SizeFileFilter + * @param threshold the file size threshold. + * @param acceptLarger if true, larger files get accepted, if false, smaller. + * @return an appropriately configured SizeFileFilter. * @see SizeFileFilter * @since 1.2 */ @@ -663,9 +663,9 @@ public static IOFileFilter sizeFileFilter(final long threshold, final boolean ac * Returns a filter that accepts files whose size is >= minimum size * and <= maximum size. * - * @param minSizeInclusive the minimum file size (inclusive) - * @param maxSizeInclusive the maximum file size (inclusive) - * @return an appropriately configured IOFileFilter + * @param minSizeInclusive the minimum file size (inclusive). + * @param maxSizeInclusive the maximum file size (inclusive). + * @return an appropriately configured IOFileFilter. * @see SizeFileFilter * @since 1.3 */ @@ -678,8 +678,8 @@ public static IOFileFilter sizeRangeFileFilter(final long minSizeInclusive, fina /** * Returns a filter that returns true if the file name ends with the specified text. * - * @param suffix the file name suffix - * @return a suffix checking filter + * @param suffix the file name suffix. + * @return a suffix checking filter. * @see SuffixFileFilter */ public static IOFileFilter suffixFileFilter(final String suffix) { @@ -689,9 +689,9 @@ public static IOFileFilter suffixFileFilter(final String suffix) { /** * Returns a filter that returns true if the file name ends with the specified text. * - * @param suffix the file name suffix - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @return a suffix checking filter + * @param suffix the file name suffix. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @return a suffix checking filter. * @see SuffixFileFilter * @since 2.0 */ @@ -702,8 +702,8 @@ public static IOFileFilter suffixFileFilter(final String suffix, final IOCase io /** * Create a List of file filters. * - * @param filters The file filters - * @return The list of file filters + * @param filters The file filters. + * @return The list of file filters. * @throws NullPointerException if the filters are null or contain a * null value. * @since 2.0 @@ -715,7 +715,7 @@ public static List toList(final IOFileFilter... filters) { /** * Returns a filter that always returns true. * - * @return a true filter + * @return a true filter. * @see TrueFileFilter#TRUE */ public static IOFileFilter trueFileFilter() { diff --git a/src/main/java/org/apache/commons/io/filefilter/HiddenFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/HiddenFileFilter.java index 6fff2241ab1..a8c49bbae8e 100644 --- a/src/main/java/org/apache/commons/io/filefilter/HiddenFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/HiddenFileFilter.java @@ -95,7 +95,7 @@ protected HiddenFileFilter() { /** * Tests to see if the file is hidden. * - * @param file the File to check + * @param file the File to check. * @return {@code true} if the file is * hidden, otherwise {@code false}. */ @@ -107,7 +107,7 @@ public boolean accept(final File file) { /** * Tests to see if the file is hidden. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). * @return {@code true} if the file is hidden, otherwise {@code false}. * @since 2.9.0 diff --git a/src/main/java/org/apache/commons/io/filefilter/NameFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/NameFileFilter.java index 7eda934d906..5aa3c38a21b 100644 --- a/src/main/java/org/apache/commons/io/filefilter/NameFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/NameFileFilter.java @@ -83,9 +83,9 @@ public class NameFileFilter extends AbstractFileFilter implements Serializable { /** * Constructs a new case-sensitive name file filter for a list of names. * - * @param names the names to allow, must not be null - * @throws IllegalArgumentException if the name list is null - * @throws ClassCastException if the list does not contain Strings + * @param names the names to allow, must not be null. + * @throws IllegalArgumentException if the name list is null. + * @throws ClassCastException if the list does not contain Strings. */ public NameFileFilter(final List names) { this(names, null); @@ -94,10 +94,10 @@ public NameFileFilter(final List names) { /** * Constructs a new name file filter for a list of names specifying case-sensitivity. * - * @param names the names to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the name list is null - * @throws ClassCastException if the list does not contain Strings + * @param names the names to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the name list is null. + * @throws ClassCastException if the list does not contain Strings. */ public NameFileFilter(final List names, final IOCase ioCase) { Objects.requireNonNull(names, "names"); @@ -108,8 +108,8 @@ public NameFileFilter(final List names, final IOCase ioCase) { /** * Constructs a new case-sensitive name file filter for a single name. * - * @param name the name to allow, must not be null - * @throws IllegalArgumentException if the name is null + * @param name the name to allow, must not be null. + * @throws IllegalArgumentException if the name is null. */ public NameFileFilter(final String name) { this(name, IOCase.SENSITIVE); @@ -122,8 +122,8 @@ public NameFileFilter(final String name) { * instance. This would be inadvisable however. *

    * - * @param names the names to allow, must not be null - * @throws IllegalArgumentException if the names array is null + * @param names the names to allow, must not be null. + * @throws IllegalArgumentException if the names array is null. */ public NameFileFilter(final String... names) { this(names, IOCase.SENSITIVE); @@ -132,9 +132,9 @@ public NameFileFilter(final String... names) { /** * Constructs a new name file filter specifying case-sensitivity. * - * @param name the name to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the name is null + * @param name the name to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the name is null. */ public NameFileFilter(final String name, final IOCase ioCase) { Objects.requireNonNull(name, "name"); @@ -145,9 +145,9 @@ public NameFileFilter(final String name, final IOCase ioCase) { /** * Constructs a new name file filter for an array of names specifying case-sensitivity. * - * @param names the names to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the names array is null + * @param names the names to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the names array is null. */ public NameFileFilter(final String[] names, final IOCase ioCase) { Objects.requireNonNull(names, "names"); @@ -158,8 +158,8 @@ public NameFileFilter(final String[] names, final IOCase ioCase) { /** * Tests to see if the file name matches. * - * @param file the File to check - * @return true if the file name matches + * @param file the File to check. + * @return true if the file name matches. */ @Override public boolean accept(final File file) { @@ -169,9 +169,9 @@ public boolean accept(final File file) { /** * Tests to see if the file name matches. * - * @param dir the File directory (ignored) - * @param name the file name - * @return true if the file name matches + * @param dir the File directory (ignored). + * @param name the file name. + * @return true if the file name matches. */ @Override public boolean accept(final File dir, final String name) { @@ -181,9 +181,9 @@ public boolean accept(final File dir, final String name) { /** * Checks to see if the file name matches. * - * @param path the File to check + * @param path the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name matches + * @return true if the file name matches. * @since 2.9.0 */ @Override @@ -202,7 +202,7 @@ private IOCase toIOCase(final IOCase ioCase) { /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java index 8592e402129..4e92f9a47ac 100644 --- a/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/NotFileFilter.java @@ -43,8 +43,8 @@ public class NotFileFilter extends AbstractFileFilter implements Serializable { /** * Constructs a new file filter that NOTs the result of another filter. * - * @param filter the filter, must not be null - * @throws NullPointerException if the filter is null + * @param filter the filter, must not be null. + * @throws NullPointerException if the filter is null. */ public NotFileFilter(final IOFileFilter filter) { Objects.requireNonNull(filter, "filter"); @@ -54,8 +54,8 @@ public NotFileFilter(final IOFileFilter filter) { /** * Returns the logical NOT of the underlying filter's return value for the same File. * - * @param file the File to check - * @return true if the filter returns false + * @param file the File to check. + * @return true if the filter returns false. */ @Override public boolean accept(final File file) { @@ -65,9 +65,9 @@ public boolean accept(final File file) { /** * Returns the logical NOT of the underlying filter's return value for the same arguments. * - * @param file the File directory - * @param name the file name - * @return true if the filter returns false + * @param file the File directory. + * @param name the file name. + * @return true if the filter returns false. */ @Override public boolean accept(final File file, final String name) { @@ -77,9 +77,9 @@ public boolean accept(final File file, final String name) { /** * Returns the logical NOT of the underlying filter's return value for the same File. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the filter returns false + * @return true if the filter returns false. * @since 2.9.0 */ @Override @@ -94,7 +94,7 @@ private FileVisitResult not(final FileVisitResult accept) { /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java index 57b8bcf0560..2bc8fc7074c 100644 --- a/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java @@ -87,9 +87,9 @@ public OrFileFilter(final IOFileFilter... fileFilters) { /** * Constructs a new file filter that ORs the result of other filters. * - * @param filter1 the first filter, must not be null - * @param filter2 the second filter, must not be null - * @throws IllegalArgumentException if either filter is null + * @param filter1 the first filter, must not be null. + * @param filter2 the second filter, must not be null. + * @throws IllegalArgumentException if either filter is null. */ public OrFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { this(2); @@ -177,7 +177,7 @@ public void setFileFilters(final List fileFilters) { /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/PrefixFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/PrefixFileFilter.java index 3a85c9e8e18..a1db0ae1203 100644 --- a/src/main/java/org/apache/commons/io/filefilter/PrefixFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/PrefixFileFilter.java @@ -83,9 +83,9 @@ public class PrefixFileFilter extends AbstractFileFilter implements Serializable /** * Constructs a new Prefix file filter for a list of prefixes. * - * @param prefixes the prefixes to allow, must not be null - * @throws NullPointerException if the prefix list is null - * @throws ClassCastException if the list does not contain Strings + * @param prefixes the prefixes to allow, must not be null. + * @throws NullPointerException if the prefix list is null. + * @throws ClassCastException if the list does not contain Strings. */ public PrefixFileFilter(final List prefixes) { this(prefixes, IOCase.SENSITIVE); @@ -95,10 +95,10 @@ public PrefixFileFilter(final List prefixes) { * Constructs a new Prefix file filter for a list of prefixes * specifying case-sensitivity. * - * @param prefixes the prefixes to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the prefix list is null - * @throws ClassCastException if the list does not contain Strings + * @param prefixes the prefixes to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the prefix list is null. + * @throws ClassCastException if the list does not contain Strings. * @since 1.4 */ public PrefixFileFilter(final List prefixes, final IOCase ioCase) { @@ -110,8 +110,8 @@ public PrefixFileFilter(final List prefixes, final IOCase ioCase) { /** * Constructs a new Prefix file filter for a single prefix. * - * @param prefix the prefix to allow, must not be null - * @throws IllegalArgumentException if the prefix is null + * @param prefix the prefix to allow, must not be null. + * @throws IllegalArgumentException if the prefix is null. */ public PrefixFileFilter(final String prefix) { this(prefix, IOCase.SENSITIVE); @@ -124,8 +124,8 @@ public PrefixFileFilter(final String prefix) { * instance. This would be inadvisable however. *

    * - * @param prefixes the prefixes to allow, must not be null - * @throws IllegalArgumentException if the prefix array is null + * @param prefixes the prefixes to allow, must not be null. + * @throws IllegalArgumentException if the prefix array is null. */ public PrefixFileFilter(final String... prefixes) { this(prefixes, IOCase.SENSITIVE); @@ -135,9 +135,9 @@ public PrefixFileFilter(final String... prefixes) { * Constructs a new Prefix file filter for a single prefix * specifying case-sensitivity. * - * @param prefix the prefix to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the prefix is null + * @param prefix the prefix to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws IllegalArgumentException if the prefix is null. * @since 1.4 */ public PrefixFileFilter(final String prefix, final IOCase ioCase) { @@ -150,9 +150,9 @@ public PrefixFileFilter(final String prefix, final IOCase ioCase) { * Constructs a new Prefix file filter for any of an array of prefixes * specifying case-sensitivity. * - * @param prefixes the prefixes to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the prefix is null + * @param prefixes the prefixes to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws IllegalArgumentException if the prefix is null. * @since 1.4 */ public PrefixFileFilter(final String[] prefixes, final IOCase ioCase) { @@ -164,8 +164,8 @@ public PrefixFileFilter(final String[] prefixes, final IOCase ioCase) { /** * Tests to see if the file name starts with the prefix. * - * @param file the File to check - * @return true if the file name starts with one of our prefixes + * @param file the File to check. + * @return true if the file name starts with one of our prefixes. */ @Override public boolean accept(final File file) { @@ -175,9 +175,9 @@ public boolean accept(final File file) { /** * Tests to see if the file name starts with the prefix. * - * @param file the File directory - * @param name the file name - * @return true if the file name starts with one of our prefixes + * @param file the File directory. + * @param name the file name. + * @return true if the file name starts with one of our prefixes. */ @Override public boolean accept(final File file, final String name) { @@ -187,9 +187,9 @@ public boolean accept(final File file, final String name) { /** * Tests to see if the file name starts with the prefix. * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name starts with one of our prefixes + * @return true if the file name starts with one of our prefixes. * @since 2.9.0 */ @Override @@ -204,7 +204,7 @@ private boolean accept(final String name) { /** * Provides a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/RegexFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/RegexFileFilter.java index f044800692c..db699d9b912 100644 --- a/src/main/java/org/apache/commons/io/filefilter/RegexFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/RegexFileFilter.java @@ -132,8 +132,8 @@ public RegexFileFilter(final Pattern pattern, final Function pathT /** * Constructs a new regular expression filter. * - * @param pattern regular string expression to match - * @throws NullPointerException if the pattern is null + * @param pattern regular string expression to match. + * @throws NullPointerException if the pattern is null. */ public RegexFileFilter(final String pattern) { this(pattern, 0); @@ -142,9 +142,9 @@ public RegexFileFilter(final String pattern) { /** * Constructs a new regular expression filter with the specified flags. * - * @param pattern regular string expression to match + * @param pattern regular string expression to match. * @param flags pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE} - * @throws IllegalArgumentException if the pattern is null + * @throws IllegalArgumentException if the pattern is null. */ public RegexFileFilter(final String pattern, final int flags) { this(compile(pattern, flags)); @@ -153,9 +153,9 @@ public RegexFileFilter(final String pattern, final int flags) { /** * Constructs a new regular expression filter with the specified flags case sensitivity. * - * @param pattern regular string expression to match - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the pattern is null + * @param pattern regular string expression to match. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws IllegalArgumentException if the pattern is null. */ public RegexFileFilter(final String pattern, final IOCase ioCase) { this(compile(pattern, toFlags(ioCase))); @@ -164,9 +164,9 @@ public RegexFileFilter(final String pattern, final IOCase ioCase) { /** * Tests to see if the file name matches one of the regular expressions. * - * @param dir the file directory (ignored) - * @param name the file name - * @return true if the file name matches one of the regular expressions + * @param dir the file directory (ignored). + * @param name the file name. + * @return true if the file name matches one of the regular expressions. */ @Override public boolean accept(final File dir, final String name) { @@ -176,9 +176,9 @@ public boolean accept(final File dir, final String name) { /** * Tests to see if the file name matches one of the regular expressions. * - * @param path the path + * @param path the path. * @param attributes the path's basic attributes (may be null). - * @return true if the file name matches one of the regular expressions + * @return true if the file name matches one of the regular expressions. */ @Override public FileVisitResult accept(final Path path, final BasicFileAttributes attributes) { diff --git a/src/main/java/org/apache/commons/io/filefilter/SizeFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/SizeFileFilter.java index 24b0b57f939..185f47bf2ef 100644 --- a/src/main/java/org/apache/commons/io/filefilter/SizeFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/SizeFileFilter.java @@ -82,8 +82,8 @@ public class SizeFileFilter extends AbstractFileFilter implements Serializable { * Constructs a new size file filter for files equal to or * larger than a certain size. * - * @param size the threshold size of the files - * @throws IllegalArgumentException if the size is negative + * @param size the threshold size of the files. + * @throws IllegalArgumentException if the size is negative. */ public SizeFileFilter(final long size) { this(size, true); @@ -93,10 +93,10 @@ public SizeFileFilter(final long size) { * Constructs a new size file filter for files based on a certain size * threshold. * - * @param size the threshold size of the files + * @param size the threshold size of the files. * @param acceptLarger if true, files equal to or larger are accepted, - * otherwise smaller ones (but not equal to) - * @throws IllegalArgumentException if the size is negative + * otherwise smaller ones (but not equal to). + * @throws IllegalArgumentException if the size is negative. */ public SizeFileFilter(final long size, final boolean acceptLarger) { if (size < 0) { @@ -115,8 +115,8 @@ public SizeFileFilter(final long size, final boolean acceptLarger) { * file IS selected. *

    * - * @param file the File to check - * @return true if the file name matches + * @param file the File to check. + * @return true if the file name matches. */ @Override public boolean accept(final File file) { @@ -134,9 +134,9 @@ private boolean accept(final long length) { * file IS selected. *

    * - * @param file the File to check + * @param file the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name matches + * @return true if the file name matches. */ @Override public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) { @@ -146,7 +146,7 @@ public FileVisitResult accept(final Path file, final BasicFileAttributes attribu /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java index d375433495a..e4780baf704 100644 --- a/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/SuffixFileFilter.java @@ -84,9 +84,9 @@ public class SuffixFileFilter extends AbstractFileFilter implements Serializable /** * Constructs a new Suffix file filter for a list of suffixes. * - * @param suffixes the suffixes to allow, must not be null - * @throws IllegalArgumentException if the suffix list is null - * @throws ClassCastException if the list does not contain Strings + * @param suffixes the suffixes to allow, must not be null. + * @throws IllegalArgumentException if the suffix list is null. + * @throws ClassCastException if the list does not contain Strings. */ public SuffixFileFilter(final List suffixes) { this(suffixes, IOCase.SENSITIVE); @@ -96,10 +96,10 @@ public SuffixFileFilter(final List suffixes) { * Constructs a new Suffix file filter for a list of suffixes * specifying case-sensitivity. * - * @param suffixes the suffixes to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the suffix list is null - * @throws ClassCastException if the list does not contain Strings + * @param suffixes the suffixes to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws IllegalArgumentException if the suffix list is null. + * @throws ClassCastException if the list does not contain Strings. * @since 1.4 */ public SuffixFileFilter(final List suffixes, final IOCase ioCase) { @@ -111,8 +111,8 @@ public SuffixFileFilter(final List suffixes, final IOCase ioCase) { /** * Constructs a new Suffix file filter for a single extension. * - * @param suffix the suffix to allow, must not be null - * @throws IllegalArgumentException if the suffix is null + * @param suffix the suffix to allow, must not be null. + * @throws IllegalArgumentException if the suffix is null. */ public SuffixFileFilter(final String suffix) { this(suffix, IOCase.SENSITIVE); @@ -125,8 +125,8 @@ public SuffixFileFilter(final String suffix) { * instance. This would be inadvisable however. *

    * - * @param suffixes the suffixes to allow, must not be null - * @throws NullPointerException if the suffix array is null + * @param suffixes the suffixes to allow, must not be null. + * @throws NullPointerException if the suffix array is null. */ public SuffixFileFilter(final String... suffixes) { this(suffixes, IOCase.SENSITIVE); @@ -136,9 +136,9 @@ public SuffixFileFilter(final String... suffixes) { * Constructs a new Suffix file filter for a single extension * specifying case-sensitivity. * - * @param suffix the suffix to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the suffix is null + * @param suffix the suffix to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the suffix is null. * @since 1.4 */ public SuffixFileFilter(final String suffix, final IOCase ioCase) { @@ -151,9 +151,9 @@ public SuffixFileFilter(final String suffix, final IOCase ioCase) { * Constructs a new Suffix file filter for an array of suffixes * specifying case-sensitivity. * - * @param suffixes the suffixes to allow, must not be null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the suffix array is null + * @param suffixes the suffixes to allow, must not be null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the suffix array is null. * @since 1.4 */ public SuffixFileFilter(final String[] suffixes, final IOCase ioCase) { @@ -165,8 +165,8 @@ public SuffixFileFilter(final String[] suffixes, final IOCase ioCase) { /** * Tests to see if the file name ends with the suffix. * - * @param file the File to check - * @return true if the file name ends with one of our suffixes + * @param file the File to check. + * @return true if the file name ends with one of our suffixes. */ @Override public boolean accept(final File file) { @@ -176,9 +176,9 @@ public boolean accept(final File file) { /** * Tests to see if the file name ends with the suffix. * - * @param file the File directory - * @param name the file name - * @return true if the file name ends with one of our suffixes + * @param file the File directory. + * @param name the file name. + * @return true if the file name ends with one of our suffixes. */ @Override public boolean accept(final File file, final String name) { @@ -188,9 +188,9 @@ public boolean accept(final File file, final String name) { /** * Tests to see if the file name ends with the suffix. * - * @param path the File to check + * @param path the File to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name ends with one of our suffixes + * @return true if the file name ends with one of our suffixes. * @since 2.9.0 */ @Override @@ -205,7 +205,7 @@ private boolean accept(final String name) { /** * Provides a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java index 5c0d85a79a7..3869b0bcda5 100644 --- a/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilter.java @@ -107,7 +107,7 @@ public SymbolicLinkFileFilter(final FileVisitResult onAccept, final FileVisitRes /** * Tests to see if the file is a symbolic link. * - * @param file the File to check + * @param file the File to check. * @return true if the file exists and is a symbolic link to either another file or a directory, * false otherwise. */ @@ -119,7 +119,7 @@ public boolean accept(final File file) { /** * Tests to see if the file is a symbolic link. * - * @param path the File Path to check + * @param path the File Path to check. * @param attributes the path's basic attributes (may be null). * @return {@code onAccept} from {@link #SymbolicLinkFileFilter(FileVisitResult, FileVisitResult)} if the file exists and is a symbolic link to either * another file or a directory; returns {@code onReject} otherwise. @@ -136,7 +136,7 @@ public FileVisitResult accept(final Path path, final BasicFileAttributes attribu * test for why.) *

    * - * @param filePath The filePath to test + * @param filePath The filePath to test. * @return true if the file exists and is a symbolic link to either a file or directory, false otherwise. */ boolean isSymbolicLink(final Path filePath) { diff --git a/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java index 70e27da55dc..9552e27a545 100644 --- a/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java @@ -60,8 +60,8 @@ protected TrueFileFilter() { /** * Returns true. * - * @param file the file to check (ignored) - * @return true + * @param file the file to check (ignored). + * @return true. */ @Override public boolean accept(final File file) { @@ -71,9 +71,9 @@ public boolean accept(final File file) { /** * Returns true. * - * @param dir the directory to check (ignored) - * @param name the file name (ignored) - * @return true + * @param dir the directory to check (ignored). + * @param name the file name (ignored). + * @return true. */ @Override public boolean accept(final File dir, final String name) { @@ -83,9 +83,9 @@ public boolean accept(final File dir, final String name) { /** * Returns true. * - * @param file the file to check (ignored) + * @param file the file to check (ignored). * @param attributes the path's basic attributes (may be null). - * @return true + * @return true. * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/filefilter/WildcardFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/WildcardFileFilter.java index 72a01c3789e..7e895e254e1 100644 --- a/src/main/java/org/apache/commons/io/filefilter/WildcardFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/WildcardFileFilter.java @@ -174,9 +174,9 @@ private WildcardFileFilter(final Builder builder) { /** * Constructs a new wildcard filter for an array of wildcards specifying case-sensitivity. * - * @param wildcards the array of wildcards to match, not null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the pattern array is null + * @param wildcards the array of wildcards to match, not null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the pattern array is null. */ private WildcardFileFilter(final IOCase ioCase, final String... wildcards) { this.wildcards = requireWildcards(wildcards).clone(); @@ -186,10 +186,10 @@ private WildcardFileFilter(final IOCase ioCase, final String... wildcards) { /** * Constructs a new case-sensitive wildcard filter for a list of wildcards. * - * @param wildcards the list of wildcards to match, not null - * @throws IllegalArgumentException if the pattern list is null - * @throws ClassCastException if the list does not contain Strings - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcards the list of wildcards to match, not null. + * @throws IllegalArgumentException if the pattern list is null. + * @throws ClassCastException if the list does not contain Strings. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final List wildcards) { @@ -199,11 +199,11 @@ public WildcardFileFilter(final List wildcards) { /** * Constructs a new wildcard filter for a list of wildcards specifying case-sensitivity. * - * @param wildcards the list of wildcards to match, not null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws IllegalArgumentException if the pattern list is null - * @throws ClassCastException if the list does not contain Strings - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcards the list of wildcards to match, not null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws IllegalArgumentException if the pattern list is null. + * @throws ClassCastException if the list does not contain Strings. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final List wildcards, final IOCase ioCase) { @@ -213,9 +213,9 @@ public WildcardFileFilter(final List wildcards, final IOCase ioCase) { /** * Constructs a new case-sensitive wildcard filter for a single wildcard. * - * @param wildcard the wildcard to match - * @throws IllegalArgumentException if the pattern is null - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcard the wildcard to match. + * @throws IllegalArgumentException if the pattern is null. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final String wildcard) { @@ -225,9 +225,9 @@ public WildcardFileFilter(final String wildcard) { /** * Constructs a new case-sensitive wildcard filter for an array of wildcards. * - * @param wildcards the array of wildcards to match - * @throws NullPointerException if the pattern array is null - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcards the array of wildcards to match. + * @throws NullPointerException if the pattern array is null. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final String... wildcards) { @@ -237,10 +237,10 @@ public WildcardFileFilter(final String... wildcards) { /** * Constructs a new wildcard filter for a single wildcard specifying case-sensitivity. * - * @param wildcard the wildcard to match, not null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the pattern is null - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcard the wildcard to match, not null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the pattern is null. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final String wildcard, final IOCase ioCase) { @@ -250,10 +250,10 @@ public WildcardFileFilter(final String wildcard, final IOCase ioCase) { /** * Constructs a new wildcard filter for an array of wildcards specifying case-sensitivity. * - * @param wildcards the array of wildcards to match, not null - * @param ioCase how to handle case sensitivity, null means case-sensitive - * @throws NullPointerException if the pattern array is null - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} + * @param wildcards the array of wildcards to match, not null. + * @param ioCase how to handle case sensitivity, null means case-sensitive. + * @throws NullPointerException if the pattern array is null. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated public WildcardFileFilter(final String[] wildcards, final IOCase ioCase) { @@ -263,8 +263,8 @@ public WildcardFileFilter(final String[] wildcards, final IOCase ioCase) { /** * Tests to see if the file name matches one of the wildcards. * - * @param file the file to check - * @return true if the file name matches one of the wildcards + * @param file the file to check. + * @return true if the file name matches one of the wildcards. */ @Override public boolean accept(final File file) { @@ -274,9 +274,9 @@ public boolean accept(final File file) { /** * Tests to see if the file name matches one of the wildcards. * - * @param dir the file directory (ignored) - * @param name the file name - * @return true if the file name matches one of the wildcards + * @param dir the file directory (ignored). + * @param name the file name. + * @return true if the file name matches one of the wildcards. */ @Override public boolean accept(final File dir, final String name) { @@ -286,7 +286,7 @@ public boolean accept(final File dir, final String name) { /** * Tests to see if the file name matches one of the wildcards. * - * @param path the file to check + * @param path the file to check. * @param attributes the path's basic attributes (may be null). * @return true if the file name matches one of the wildcards. * @since 2.9.0 @@ -303,7 +303,7 @@ private boolean accept(final String name) { /** * Provide a String representation of this file filter. * - * @return a String representation + * @return a String representation. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java b/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java index e435101fbd4..a28cd56c634 100644 --- a/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java @@ -93,9 +93,9 @@ public class WildcardFilter extends AbstractFileFilter implements Serializable { /** * Constructs a new case-sensitive wildcard filter for a list of wildcards. * - * @param wildcards the list of wildcards to match - * @throws NullPointerException if the pattern list is null - * @throws ClassCastException if the list does not contain Strings + * @param wildcards the list of wildcards to match. + * @throws NullPointerException if the pattern list is null. + * @throws ClassCastException if the list does not contain Strings. */ public WildcardFilter(final List wildcards) { Objects.requireNonNull(wildcards, "wildcards"); @@ -105,8 +105,8 @@ public WildcardFilter(final List wildcards) { /** * Constructs a new case-sensitive wildcard filter for a single wildcard. * - * @param wildcard the wildcard to match - * @throws NullPointerException if the pattern is null + * @param wildcard the wildcard to match. + * @throws NullPointerException if the pattern is null. */ public WildcardFilter(final String wildcard) { Objects.requireNonNull(wildcard, "wildcard"); @@ -116,8 +116,8 @@ public WildcardFilter(final String wildcard) { /** * Constructs a new case-sensitive wildcard filter for an array of wildcards. * - * @param wildcards the array of wildcards to match - * @throws NullPointerException if the pattern array is null + * @param wildcards the array of wildcards to match. + * @throws NullPointerException if the pattern array is null. */ public WildcardFilter(final String... wildcards) { Objects.requireNonNull(wildcards, "wildcards"); @@ -127,8 +127,8 @@ public WildcardFilter(final String... wildcards) { /** * Tests to see if the file name matches one of the wildcards. * - * @param file the file to check - * @return true if the file name matches one of the wildcards + * @param file the file to check. + * @return true if the file name matches one of the wildcards. */ @Override public boolean accept(final File file) { @@ -141,9 +141,9 @@ public boolean accept(final File file) { /** * Tests to see if the file name matches one of the wildcards. * - * @param dir the file directory - * @param name the file name - * @return true if the file name matches one of the wildcards + * @param dir the file directory. + * @param name the file name. + * @return true if the file name matches one of the wildcards. */ @Override public boolean accept(final File dir, final String name) { @@ -156,9 +156,9 @@ public boolean accept(final File dir, final String name) { /** * Tests to see if the file name matches one of the wildcards. * - * @param path the file to check + * @param path the file to check. * @param attributes the path's basic attributes (may be null). - * @return true if the file name matches one of the wildcards + * @return true if the file name matches one of the wildcards. * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/function/IOBiConsumer.java b/src/main/java/org/apache/commons/io/function/IOBiConsumer.java index a8e1bdf397d..ec217eafa0a 100644 --- a/src/main/java/org/apache/commons/io/function/IOBiConsumer.java +++ b/src/main/java/org/apache/commons/io/function/IOBiConsumer.java @@ -25,8 +25,8 @@ /** * Like {@link BiConsumer} but throws {@link IOException}. * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation + * @param the type of the first argument to the operation. + * @param the type of the second argument to the operation. * @see BiConsumer * @since 2.12.0 */ @@ -36,8 +36,8 @@ public interface IOBiConsumer { /** * Returns the no-op singleton. * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation + * @param the type of the first argument to the operation. + * @param the type of the second argument to the operation. * @return The no-op singleton. */ @SuppressWarnings("unchecked") @@ -48,8 +48,8 @@ static IOBiConsumer noop() { /** * Performs this operation on the given arguments. * - * @param t the first input argument - * @param u the second input argument + * @param t the first input argument. + * @param u the second input argument. * @throws IOException if an I/O error occurs. */ void accept(T t, U u) throws IOException; @@ -59,10 +59,10 @@ static IOBiConsumer noop() { * operation. If performing either operation throws an exception, it is relayed to the caller of the composed operation. * If performing this operation throws an exception, the {@code after} operation will not be performed. * - * @param after the operation to perform after this operation + * @param after the operation to perform after this operation. * @return a composed {@link IOBiConsumer} that performs in sequence this operation followed by the {@code after} - * operation - * @throws NullPointerException if {@code after} is null + * operation. + * @throws NullPointerException if {@code after} is null. */ default IOBiConsumer andThen(final IOBiConsumer after) { Objects.requireNonNull(after); diff --git a/src/main/java/org/apache/commons/io/function/IOBiFunction.java b/src/main/java/org/apache/commons/io/function/IOBiFunction.java index a72b73f3581..fa5bd4c5db1 100644 --- a/src/main/java/org/apache/commons/io/function/IOBiFunction.java +++ b/src/main/java/org/apache/commons/io/function/IOBiFunction.java @@ -30,9 +30,9 @@ * {@link #apply(Object, Object)}. *

    * - * @param the type of the first argument to the function - * @param the type of the second argument to the function - * @param the type of the result of the function + * @param the type of the first argument to the function. + * @param the type of the second argument to the function. + * @param the type of the result of the function. * @see BiFunction * @since 2.12.0 */ @@ -44,10 +44,10 @@ public interface IOBiFunction { * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} function - * @throws NullPointerException if after is null + * @param the type of output of the {@code after} function, and of the composed function. + * @param after the function to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} function. + * @throws NullPointerException if after is null. */ default IOBiFunction andThen(final IOFunction after) { Objects.requireNonNull(after); @@ -57,9 +57,9 @@ default IOBiFunction andThen(final IOFunction extends IOBiFunction { * Creates a {@link IOBinaryOperator} which returns the greater of two elements according to the specified * {@code Comparator}. * - * @param the type of the input arguments of the comparator - * @param comparator a {@code Comparator} for comparing the two values + * @param the type of the input arguments of the comparator. + * @param comparator a {@code Comparator} for comparing the two values. * @return a {@code BinaryOperator} which returns the greater of its operands, according to the supplied * {@code Comparator} - * @throws NullPointerException if the argument is null + * @throws NullPointerException if the argument is null. */ static IOBinaryOperator maxBy(final IOComparator comparator) { Objects.requireNonNull(comparator); @@ -52,11 +52,11 @@ static IOBinaryOperator maxBy(final IOComparator comparator) { * Creates a {@link IOBinaryOperator} which returns the lesser of two elements according to the specified * {@code Comparator}. * - * @param the type of the input arguments of the comparator - * @param comparator a {@code Comparator} for comparing the two values + * @param the type of the input arguments of the comparator. + * @param comparator a {@code Comparator} for comparing the two values. * @return a {@code BinaryOperator} which returns the lesser of its operands, according to the supplied * {@code Comparator} - * @throws NullPointerException if the argument is null + * @throws NullPointerException if the argument is null. */ static IOBinaryOperator minBy(final IOComparator comparator) { Objects.requireNonNull(comparator); diff --git a/src/main/java/org/apache/commons/io/function/IOBooleanSupplier.java b/src/main/java/org/apache/commons/io/function/IOBooleanSupplier.java index 0b8b1dcfd8b..f82f40adb8e 100644 --- a/src/main/java/org/apache/commons/io/function/IOBooleanSupplier.java +++ b/src/main/java/org/apache/commons/io/function/IOBooleanSupplier.java @@ -42,7 +42,7 @@ default BooleanSupplier asBooleanSupplier() { /** * Gets a result. * - * @return a result + * @return a result. * @throws IOException if an I/O error occurs. */ boolean getAsBoolean() throws IOException; diff --git a/src/main/java/org/apache/commons/io/function/IOComparator.java b/src/main/java/org/apache/commons/io/function/IOComparator.java index eb31ef818ef..4d8e891eaa0 100644 --- a/src/main/java/org/apache/commons/io/function/IOComparator.java +++ b/src/main/java/org/apache/commons/io/function/IOComparator.java @@ -24,7 +24,7 @@ /** * Like {@link Comparator} but throws {@link IOException}. * - * @param the type of objects that may be compared by this comparator + * @param the type of objects that may be compared by this comparator. * @see Comparator * @since 2.12.0 */ @@ -48,7 +48,7 @@ default Comparator asComparator() { * @param o2 the second object to be compared. * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than * the second. - * @throws NullPointerException if an argument is null and this comparator does not permit null arguments + * @throws NullPointerException if an argument is null and this comparator does not permit null arguments. * @throws ClassCastException if the arguments' types prevent them from being compared by this comparator. * @throws IOException if an I/O error occurs. */ diff --git a/src/main/java/org/apache/commons/io/function/IOConsumer.java b/src/main/java/org/apache/commons/io/function/IOConsumer.java index 016b643f95f..cb42e0a202d 100644 --- a/src/main/java/org/apache/commons/io/function/IOConsumer.java +++ b/src/main/java/org/apache/commons/io/function/IOConsumer.java @@ -136,7 +136,7 @@ static IOConsumer noop() { /** * Performs this operation on the given argument. * - * @param t the input argument + * @param t the input argument. * @throws IOException if an I/O error occurs. */ void accept(T t) throws IOException; @@ -146,9 +146,9 @@ static IOConsumer noop() { * operation. If performing either operation throws an exception, it is relayed to the caller of the composed operation. * If performing this operation throws an exception, the {@code after} operation will not be performed. * - * @param after the operation to perform after this operation - * @return a composed {@link Consumer} that performs in sequence this operation followed by the {@code after} operation - * @throws NullPointerException if {@code after} is null + * @param after the operation to perform after this operation. + * @return a composed {@link Consumer} that performs in sequence this operation followed by the {@code after} operation. + * @throws NullPointerException if {@code after} is null. */ default IOConsumer andThen(final IOConsumer after) { Objects.requireNonNull(after, "after"); diff --git a/src/main/java/org/apache/commons/io/function/IOFunction.java b/src/main/java/org/apache/commons/io/function/IOFunction.java index 07e9d539a99..92f1335fbb6 100644 --- a/src/main/java/org/apache/commons/io/function/IOFunction.java +++ b/src/main/java/org/apache/commons/io/function/IOFunction.java @@ -37,8 +37,8 @@ public interface IOFunction { /** * Returns a {@link IOFunction} that always returns its input argument. * - * @param the type of the input and output objects to the function - * @return a function that always returns its input argument + * @param the type of the input and output objects to the function. + * @return a function that always returns its input argument. */ @SuppressWarnings("unchecked") static IOFunction identity() { @@ -50,9 +50,9 @@ static IOFunction identity() { * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the * caller of the composed function. * - * @param after the consumer to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} consumer - * @throws NullPointerException if after is null + * @param after the consumer to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} consumer. + * @throws NullPointerException if after is null. * @see #compose(IOFunction) */ default IOConsumer andThen(final Consumer after) { @@ -65,10 +65,10 @@ default IOConsumer andThen(final Consumer after) { * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the * caller of the composed function. * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} function - * @throws NullPointerException if after is null + * @param the type of output of the {@code after} function, and of the composed function. + * @param after the function to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} function. + * @throws NullPointerException if after is null. * @see #compose(IOFunction) */ default IOFunction andThen(final Function after) { @@ -81,9 +81,9 @@ default IOFunction andThen(final Function afte * {@code after} consumer to the result. If evaluation of either function throws an exception, it is relayed to the * caller of the composed function. * - * @param after the consumer to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} consumer - * @throws NullPointerException if after is null + * @param after the consumer to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} consumer. + * @throws NullPointerException if after is null. * @see #compose(IOFunction) */ default IOConsumer andThen(final IOConsumer after) { @@ -96,10 +96,10 @@ default IOConsumer andThen(final IOConsumer after) { * {@code after} function to the result. If evaluation of either function throws an exception, it is relayed to the * caller of the composed function. * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} function - * @throws NullPointerException if after is null + * @param the type of output of the {@code after} function, and of the composed function. + * @param after the function to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} function. + * @throws NullPointerException if after is null. * @see #compose(IOFunction) */ default IOFunction andThen(final IOFunction after) { @@ -110,8 +110,8 @@ default IOFunction andThen(final IOFunction af /** * Applies this function to the given argument. * - * @param t the function argument - * @return the function result + * @param t the function argument. + * @return the function result. * @throws IOException if an I/O error occurs. */ R apply(T t) throws IOException; @@ -131,10 +131,10 @@ default Function asFunction() { * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param the type of input to the {@code before} function, and to the composed function - * @param before the function to apply before this function is applied - * @return a composed function that first applies the {@code before} function and then applies this function - * @throws NullPointerException if before is null + * @param the type of input to the {@code before} function, and to the composed function. + * @param before the function to apply before this function is applied. + * @return a composed function that first applies the {@code before} function and then applies this function. + * @throws NullPointerException if before is null. * @see #andThen(IOFunction) */ default IOFunction compose(final Function before) { @@ -147,10 +147,10 @@ default IOFunction compose(final Function befo * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param the type of input to the {@code before} function, and to the composed function - * @param before the function to apply before this function is applied - * @return a composed function that first applies the {@code before} function and then applies this function - * @throws NullPointerException if before is null + * @param the type of input to the {@code before} function, and to the composed function. + * @param before the function to apply before this function is applied. + * @return a composed function that first applies the {@code before} function and then applies this function. + * @throws NullPointerException if before is null. * @see #andThen(IOFunction) */ default IOFunction compose(final IOFunction before) { @@ -163,9 +163,9 @@ default IOFunction compose(final IOFunction be * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param before the supplier which feeds the application of this function - * @return a composed function that first applies the {@code before} function and then applies this function - * @throws NullPointerException if before is null + * @param before the supplier which feeds the application of this function. + * @return a composed function that first applies the {@code before} function and then applies this function. + * @throws NullPointerException if before is null. * @see #andThen(IOFunction) */ default IOSupplier compose(final IOSupplier before) { @@ -178,9 +178,9 @@ default IOSupplier compose(final IOSupplier before) { * this function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param before the supplier which feeds the application of this function - * @return a composed function that first applies the {@code before} function and then applies this function - * @throws NullPointerException if before is null + * @param before the supplier which feeds the application of this function. + * @return a composed function that first applies the {@code before} function and then applies this function. + * @throws NullPointerException if before is null. * @see #andThen(IOFunction) */ default IOSupplier compose(final Supplier before) { diff --git a/src/main/java/org/apache/commons/io/function/IOIntConsumer.java b/src/main/java/org/apache/commons/io/function/IOIntConsumer.java index 9c45b29a011..8f81eff6342 100644 --- a/src/main/java/org/apache/commons/io/function/IOIntConsumer.java +++ b/src/main/java/org/apache/commons/io/function/IOIntConsumer.java @@ -41,7 +41,7 @@ public interface IOIntConsumer { /** * Performs this operation on the given argument. * - * @param value the input argument + * @param value the input argument. * @throws IOException if an I/O error occurs. */ void accept(int value) throws IOException; @@ -51,9 +51,9 @@ public interface IOIntConsumer { * operation throws an exception, it is relayed to the caller of the composed operation. If performing this operation throws an exception, the {@code after} * operation will not be performed. * - * @param after the operation to perform after this operation - * @return a composed {@code IOIntConsumer} that performs in sequence this operation followed by the {@code after} operation - * @throws NullPointerException if {@code after} is null + * @param after the operation to perform after this operation. + * @return a composed {@code IOIntConsumer} that performs in sequence this operation followed by the {@code after} operation. + * @throws NullPointerException if {@code after} is null. */ default IOIntConsumer andThen(final IOIntConsumer after) { Objects.requireNonNull(after); diff --git a/src/main/java/org/apache/commons/io/function/IOIntSupplier.java b/src/main/java/org/apache/commons/io/function/IOIntSupplier.java index 02e770cc3a3..058763d0a18 100644 --- a/src/main/java/org/apache/commons/io/function/IOIntSupplier.java +++ b/src/main/java/org/apache/commons/io/function/IOIntSupplier.java @@ -42,7 +42,7 @@ default IntSupplier asIntSupplier() { /** * Gets a result. * - * @return a result + * @return a result. * @throws IOException if an I/O error occurs. */ int getAsInt() throws IOException; diff --git a/src/main/java/org/apache/commons/io/function/IOIterator.java b/src/main/java/org/apache/commons/io/function/IOIterator.java index 42cc235fc39..2d99480cf5b 100644 --- a/src/main/java/org/apache/commons/io/function/IOIterator.java +++ b/src/main/java/org/apache/commons/io/function/IOIterator.java @@ -36,8 +36,8 @@ public interface IOIterator { * Adapts the given Iterable as an IOIterator. * * @param the type of the stream elements. - * @param iterable The iterable to adapt - * @return A new IOIterator + * @param iterable The iterable to adapt. + * @return A new IOIterator. * @since 2.17.0 */ static IOIterator adapt(final Iterable iterable) { @@ -48,8 +48,8 @@ static IOIterator adapt(final Iterable iterable) { * Adapts the given Iterator as an IOIterator. * * @param the type of the stream elements. - * @param iterator The iterator to adapt - * @return A new IOIterator + * @param iterator The iterator to adapt. + * @return A new IOIterator. */ static IOIterator adapt(final Iterator iterator) { return IOIteratorAdapter.adapt(iterator); @@ -91,7 +91,7 @@ default void forEachRemaining(final IOConsumer action) throws IOExcep * * @return See delegate. * @throws IOException if an I/O error occurs. - * @throws NoSuchElementException if the iteration has no more elements + * @throws NoSuchElementException if the iteration has no more elements. */ E next() throws IOException; diff --git a/src/main/java/org/apache/commons/io/function/IOLongSupplier.java b/src/main/java/org/apache/commons/io/function/IOLongSupplier.java index 8e90866273c..707d3b548a5 100644 --- a/src/main/java/org/apache/commons/io/function/IOLongSupplier.java +++ b/src/main/java/org/apache/commons/io/function/IOLongSupplier.java @@ -42,7 +42,7 @@ default LongSupplier asSupplier() { /** * Gets a result. * - * @return a result + * @return a result. * @throws IOException if an I/O error occurs. */ long getAsLong() throws IOException; diff --git a/src/main/java/org/apache/commons/io/function/IOPredicate.java b/src/main/java/org/apache/commons/io/function/IOPredicate.java index fda3fddb6be..6186d85b4e5 100644 --- a/src/main/java/org/apache/commons/io/function/IOPredicate.java +++ b/src/main/java/org/apache/commons/io/function/IOPredicate.java @@ -25,7 +25,7 @@ /** * Like {@link Predicate} but throws {@link IOException}. * - * @param the type of the input to the predicate + * @param the type of the input to the predicate. * @since 2.12.0 */ @FunctionalInterface @@ -34,7 +34,7 @@ public interface IOPredicate { /** * Always false. * - * @param the type of the input to the predicate + * @param the type of the input to the predicate. * @return a constant predicate that tests always false. */ @SuppressWarnings("unchecked") @@ -45,7 +45,7 @@ static IOPredicate alwaysFalse() { /** * Always true. * - * @param the type of the input to the predicate + * @param the type of the input to the predicate. * @return a constant predicate that tests always true. */ @SuppressWarnings("unchecked") @@ -56,7 +56,7 @@ static IOPredicate alwaysTrue() { /** * Creates a predicate that tests if two arguments are equal using {@link Objects#equals(Object, Object)}. * - * @param the type of arguments to the predicate + * @param the type of arguments to the predicate. * @param target the object to compare for equality, may be {@code null} * @return a predicate that tests if two arguments are equal using {@link Objects#equals(Object, Object)} */ @@ -74,10 +74,10 @@ static IOPredicate isEqual(final Object target) { * predicate throws an exception, the {@code other} predicate will not be evaluated. *

    * - * @param other a predicate that will be logically-ANDed with this predicate + * @param other a predicate that will be logically-ANDed with this predicate. * @return a composed predicate that represents the short-circuiting logical AND of this predicate and the {@code other} - * predicate - * @throws NullPointerException if other is null + * predicate. + * @throws NullPointerException if other is null. */ default IOPredicate and(final IOPredicate other) { Objects.requireNonNull(other); @@ -97,7 +97,7 @@ default Predicate asPredicate() { /** * Creates a predicate that represents the logical negation of this predicate. * - * @return a predicate that represents the logical negation of this predicate + * @return a predicate that represents the logical negation of this predicate. */ default IOPredicate negate() { return t -> !test(t); @@ -113,10 +113,10 @@ default IOPredicate negate() { * predicate throws an exception, the {@code other} predicate will not be evaluated. *

    * - * @param other a predicate that will be logically-ORed with this predicate + * @param other a predicate that will be logically-ORed with this predicate. * @return a composed predicate that represents the short-circuiting logical OR of this predicate and the {@code other} - * predicate - * @throws NullPointerException if other is null + * predicate. + * @throws NullPointerException if other is null. */ default IOPredicate or(final IOPredicate other) { Objects.requireNonNull(other); @@ -126,7 +126,7 @@ default IOPredicate or(final IOPredicate other) { /** * Evaluates this predicate on the given argument. * - * @param t the input argument + * @param t the input argument. * @return {@code true} if the input argument matches the predicate, otherwise {@code false} * @throws IOException if an I/O error occurs. */ diff --git a/src/main/java/org/apache/commons/io/function/IOQuadFunction.java b/src/main/java/org/apache/commons/io/function/IOQuadFunction.java index 78db4284b67..f5852c09948 100644 --- a/src/main/java/org/apache/commons/io/function/IOQuadFunction.java +++ b/src/main/java/org/apache/commons/io/function/IOQuadFunction.java @@ -29,11 +29,11 @@ * {@link #apply(Object, Object, Object, Object)}. *

    * - * @param the type of the first argument to the function - * @param the type of the second argument to the function - * @param the type of the third argument to the function - * @param the type of the fourth argument to the function - * @param the type of the result of the function + * @param the type of the first argument to the function. + * @param the type of the second argument to the function. + * @param the type of the third argument to the function. + * @param the type of the fourth argument to the function. + * @param the type of the result of the function. * @see Function * @since 2.12.0 */ @@ -45,10 +45,10 @@ public interface IOQuadFunction { * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} function - * @throws NullPointerException if after is null + * @param the type of output of the {@code after} function, and of the composed function. + * @param after the function to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} function. + * @throws NullPointerException if after is null. */ default IOQuadFunction andThen(final IOFunction after) { Objects.requireNonNull(after); @@ -58,11 +58,11 @@ default IOQuadFunction andThen(final IOFunction { * Adapts the given Spliterator as an IOSpliterator. * * @param the type of the stream elements. - * @param iterator The iterator to adapt - * @return A new IOSpliterator + * @param iterator The iterator to adapt. + * @return A new IOSpliterator. */ static IOSpliterator adapt(final Spliterator iterator) { return IOSpliteratorAdapter.adapt(iterator); @@ -55,7 +55,7 @@ default Spliterator asSpliterator() { /** * Like {@link Spliterator#characteristics()}. * - * @return a representation of characteristics + * @return a representation of characteristics. */ default int characteristics() { return unwrap().characteristics(); @@ -74,8 +74,8 @@ default long estimateSize() { /** * Like {@link Spliterator#forEachRemaining(Consumer)}. * - * @param action The action - * @throws NullPointerException if the specified action is null + * @param action The action. + * @throws NullPointerException if the specified action is null. */ default void forEachRemaining(final IOConsumer action) { while (tryAdvance(action)) { // NOPMD @@ -105,7 +105,7 @@ default long getExactSizeIfKnown() { /** * Like {@link Spliterator#hasCharacteristics(int)}. * - * @param characteristics the characteristics to check for + * @param characteristics the characteristics to check for. * @return {@code true} if all the specified characteristics are present, else {@code false} */ default boolean hasCharacteristics(final int characteristics) { @@ -115,9 +115,9 @@ default boolean hasCharacteristics(final int characteristics) { /** * Like {@link Spliterator#tryAdvance(Consumer)}. * - * @param action The action + * @param action The action. * @return {@code false} if no remaining elements existed upon entry to this method, else {@code true}. - * @throws NullPointerException if the specified action is null + * @throws NullPointerException if the specified action is null. */ default boolean tryAdvance(final IOConsumer action) { return unwrap().tryAdvance(Objects.requireNonNull(action, "action").asConsumer()); @@ -127,7 +127,7 @@ default boolean tryAdvance(final IOConsumer action) { * Like {@link Spliterator#trySplit()}. * * @return a {@code Spliterator} covering some portion of the elements, or {@code null} if this spliterator cannot be - * split + * split. */ default IOSpliterator trySplit() { return adapt(unwrap().trySplit()); diff --git a/src/main/java/org/apache/commons/io/function/IOStream.java b/src/main/java/org/apache/commons/io/function/IOStream.java index fb5ee13b58c..87c6c832baf 100644 --- a/src/main/java/org/apache/commons/io/function/IOStream.java +++ b/src/main/java/org/apache/commons/io/function/IOStream.java @@ -66,7 +66,7 @@ static IOStream adapt(final Stream stream) { /** * This class' version of {@link Stream#empty()}. * - * @param the type of the stream elements + * @param the type of the stream elements. * @return an empty sequential {@code IOStreamImpl}. * @see Stream#empty() */ @@ -135,9 +135,9 @@ static IOStream of(final T... values) { /** * Returns a sequential {@code IOStreamImpl} containing a single element. * - * @param t the single element - * @param the type of stream elements - * @return a singleton sequential stream + * @param t the single element. + * @param the type of stream elements. + * @return a singleton sequential stream. */ static IOStream of(final T t) { return adapt(Stream.of(t)); diff --git a/src/main/java/org/apache/commons/io/function/IOTriConsumer.java b/src/main/java/org/apache/commons/io/function/IOTriConsumer.java index f1e78d2de35..304e94440f4 100644 --- a/src/main/java/org/apache/commons/io/function/IOTriConsumer.java +++ b/src/main/java/org/apache/commons/io/function/IOTriConsumer.java @@ -24,9 +24,9 @@ /** * Like {@link BiConsumer} but throws {@link IOException}. * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation - * @param the type of the third argument to the operation + * @param the type of the first argument to the operation. + * @param the type of the second argument to the operation. + * @param the type of the third argument to the operation. * @see BiConsumer * @since 2.12.0 */ @@ -36,9 +36,9 @@ public interface IOTriConsumer { /** * Returns the no-op singleton. * - * @param the type of the first argument to the operation - * @param the type of the second argument to the operation - * @param the type of the third argument to the operation + * @param the type of the first argument to the operation. + * @param the type of the second argument to the operation. + * @param the type of the third argument to the operation. * @return The no-op singleton. */ @SuppressWarnings("unchecked") @@ -49,9 +49,9 @@ static IOTriConsumer noop() { /** * Performs this operation on the given arguments. * - * @param t the first input argument - * @param u the second input argument - * @param v the second third argument + * @param t the first input argument. + * @param u the second input argument. + * @param v the second third argument. * @throws IOException if an I/O error occurs. */ void accept(T t, U u, V v) throws IOException; @@ -61,10 +61,10 @@ static IOTriConsumer noop() { * operation. If performing either operation throws an exception, it is relayed to the caller of the composed operation. * If performing this operation throws an exception, the {@code after} operation will not be performed. * - * @param after the operation to perform after this operation + * @param after the operation to perform after this operation. * @return a composed {@link IOTriConsumer} that performs in sequence this operation followed by the {@code after} - * operation - * @throws NullPointerException if {@code after} is null + * operation. + * @throws NullPointerException if {@code after} is null. */ default IOTriConsumer andThen(final IOTriConsumer after) { Objects.requireNonNull(after); diff --git a/src/main/java/org/apache/commons/io/function/IOTriFunction.java b/src/main/java/org/apache/commons/io/function/IOTriFunction.java index 1459c3962e8..d84069df1df 100644 --- a/src/main/java/org/apache/commons/io/function/IOTriFunction.java +++ b/src/main/java/org/apache/commons/io/function/IOTriFunction.java @@ -29,10 +29,10 @@ * {@link #apply(Object, Object, Object)}. *

    * - * @param the type of the first argument to the function - * @param the type of the second argument to the function - * @param the type of the third argument to the function - * @param the type of the result of the function + * @param the type of the first argument to the function. + * @param the type of the second argument to the function. + * @param the type of the third argument to the function. + * @param the type of the result of the function. * @see Function * @since 2.12.0 */ @@ -44,10 +44,10 @@ public interface IOTriFunction { * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the * composed function. * - * @param the type of output of the {@code after} function, and of the composed function - * @param after the function to apply after this function is applied - * @return a composed function that first applies this function and then applies the {@code after} function - * @throws NullPointerException if after is null + * @param the type of output of the {@code after} function, and of the composed function. + * @param after the function to apply after this function is applied. + * @return a composed function that first applies this function and then applies the {@code after} function. + * @throws NullPointerException if after is null. */ default IOTriFunction andThen(final IOFunction after) { Objects.requireNonNull(after); @@ -57,10 +57,10 @@ default IOTriFunction andThen(final IOFunction implements Iterable { /** * Constructs a new instance. * - * @param delegate The delegate + * @param delegate The delegate. */ UncheckedIOIterable(final IOIterable delegate) { this.delegate = Objects.requireNonNull(delegate, "delegate"); diff --git a/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java b/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java index ec0bfb9867e..0fbbafb31dc 100644 --- a/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java +++ b/src/main/java/org/apache/commons/io/function/UncheckedIOIterator.java @@ -37,7 +37,7 @@ final class UncheckedIOIterator implements Iterator { /** * Constructs a new instance. * - * @param delegate The delegate + * @param delegate The delegate. */ UncheckedIOIterator(final IOIterator delegate) { this.delegate = Objects.requireNonNull(delegate, "delegate"); diff --git a/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java b/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java index 53974b060e5..b9851d93b1d 100644 --- a/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java +++ b/src/main/java/org/apache/commons/io/input/AbstractCharacterFilterReader.java @@ -40,7 +40,7 @@ public abstract class AbstractCharacterFilterReader extends FilterReader { /** * Constructs a new reader. * - * @param reader the reader to filter + * @param reader the reader to filter. */ protected AbstractCharacterFilterReader(final Reader reader) { this(reader, SKIP_NONE); diff --git a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java index 81f6c6e771d..4659f3f7038 100644 --- a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java +++ b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java @@ -112,7 +112,7 @@ private AutoCloseInputStream(final Builder builder) throws IOException { /** * Constructs an automatically closing proxy for the given input stream. * - * @param in underlying input stream + * @param in underlying input stream. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @SuppressWarnings("resource") // ClosedInputStream.nonNull() doesn't allocate @@ -124,8 +124,8 @@ public AutoCloseInputStream(final InputStream in) { /** * Automatically closes the stream if the end of stream was reached. * - * @param n number of bytes read, or -1 if no more bytes are available - * @throws IOException if the stream could not be closed + * @param n number of bytes read, or -1 if no more bytes are available. + * @throws IOException if the stream could not be closed. * @since 2.0 */ @Override @@ -146,7 +146,7 @@ protected void afterRead(final int n) throws IOException { * first called. *

    * - * @throws IOException if the underlying input stream cannot be closed + * @throws IOException if the underlying input stream cannot be closed. */ @Override public void close() throws IOException { @@ -158,7 +158,7 @@ public void close() throws IOException { * Ensures that the stream is closed before it gets garbage-collected. As mentioned in {@link #close()}, this is a no-op if the stream has already been * closed. * - * @throws Throwable if an error occurs + * @throws Throwable if an error occurs. */ @Override protected void finalize() throws Throwable { diff --git a/src/main/java/org/apache/commons/io/input/BOMInputStream.java b/src/main/java/org/apache/commons/io/input/BOMInputStream.java index acfe8d9ddbb..265da04e671 100644 --- a/src/main/java/org/apache/commons/io/input/BOMInputStream.java +++ b/src/main/java/org/apache/commons/io/input/BOMInputStream.java @@ -134,7 +134,7 @@ public static class Builder extends AbstractBuilder { /** * For test access. * - * @return the default byte order mark + * @return the default byte order mark. */ static ByteOrderMark getDefaultByteOrderMark() { return DEFAULT[0]; @@ -200,7 +200,7 @@ public Builder setByteOrderMarks(final ByteOrderMark... byteOrderMarks) { * The default is false. *

    * - * @param include true to include the UTF-8 BOM or false to exclude it. return this; + * @param include true to include the UTF-8 BOM or false to exclude it. return this;. * @return {@code this} instance. */ public Builder setInclude(final boolean include) { @@ -253,7 +253,7 @@ private BOMInputStream(final Builder builder) throws IOException { * Constructs a new BOM InputStream that excludes a {@link ByteOrderMark#UTF_8} BOM. * * @param delegate - * the InputStream to delegate to + * the InputStream to delegate to. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -265,9 +265,9 @@ public BOMInputStream(final InputStream delegate) { * Constructs a new BOM InputStream that detects a {@link ByteOrderMark#UTF_8} and optionally includes it. * * @param delegate - * the InputStream to delegate to + * the InputStream to delegate to. * @param include - * true to include the UTF-8 BOM or false to exclude it + * true to include the UTF-8 BOM or false to exclude it. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -279,11 +279,11 @@ public BOMInputStream(final InputStream delegate, final boolean include) { * Constructs a new BOM InputStream that detects the specified BOMs and optionally includes them. * * @param delegate - * the InputStream to delegate to + * the InputStream to delegate to. * @param include - * true to include the specified BOMs or false to exclude them + * true to include the specified BOMs or false to exclude them. * @param boms - * The BOMs to detect and optionally exclude + * The BOMs to detect and optionally exclude. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -303,9 +303,9 @@ public BOMInputStream(final InputStream delegate, final boolean include, final B * Constructs a new BOM InputStream that excludes the specified BOMs. * * @param delegate - * the InputStream to delegate to + * the InputStream to delegate to. * @param boms - * The BOMs to detect and exclude + * The BOMs to detect and exclude. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -339,9 +339,9 @@ public ByteOrderMark getBOM() throws IOException { /** * Gets the BOM charset Name - {@link ByteOrderMark#getCharsetName()}. * - * @return The BOM charset Name or null if no BOM found + * @return The BOM charset Name or null if no BOM found. * @throws IOException - * if an error reading the first bytes of the stream occurs + * if an error reading the first bytes of the stream occurs. */ public String getBOMCharsetName() throws IOException { getBOM(); @@ -351,9 +351,9 @@ public String getBOMCharsetName() throws IOException { /** * Tests whether the stream contains one of the specified BOMs. * - * @return true if the stream has one of the specified BOMs, otherwise false if it does not + * @return true if the stream has one of the specified BOMs, otherwise false if it does not. * @throws IOException - * if an error reading the first bytes of the stream occurs + * if an error reading the first bytes of the stream occurs. */ public boolean hasBOM() throws IOException { return getBOM() != null; @@ -363,12 +363,12 @@ public boolean hasBOM() throws IOException { * Tests whether the stream contains the specified BOM. * * @param bom - * The BOM to check for - * @return true if the stream has the specified BOM, otherwise false if it does not + * The BOM to check for. + * @return true if the stream has the specified BOM, otherwise false if it does not. * @throws IllegalArgumentException - * if the BOM is not one the stream is configured to detect + * if the BOM is not one the stream is configured to detect. * @throws IOException - * if an error reading the first bytes of the stream occurs + * if an error reading the first bytes of the stream occurs. */ public boolean hasBOM(final ByteOrderMark bom) throws IOException { if (!bomList.contains(bom)) { @@ -381,7 +381,7 @@ public boolean hasBOM(final ByteOrderMark bom) throws IOException { * Invokes the delegate's {@code mark(int)} method. * * @param readLimit - * read ahead limit + * read ahead limit. */ @Override public synchronized void mark(final int readLimit) { @@ -394,8 +394,8 @@ public synchronized void mark(final int readLimit) { * Checks if the bytes match a BOM. * * @param bom - * The BOM - * @return true if the bytes match the bom, otherwise false + * The BOM. + * @return true if the bytes match the bom, otherwise false. */ private boolean matches(final ByteOrderMark bom) { return bom.matches(firstBytes); @@ -404,9 +404,9 @@ private boolean matches(final ByteOrderMark bom) { /** * Invokes the delegate's {@code read()} method, detecting and optionally skipping BOM. * - * @return the byte read (excluding BOM) or -1 if the end of stream + * @return the byte read (excluding BOM) or -1 if the end of stream. * @throws IOException - * if an I/O error occurs + * if an I/O error occurs. */ @Override public int read() throws IOException { @@ -420,11 +420,11 @@ public int read() throws IOException { * * @param buf * the buffer to read the bytes into, never {@code null} - * @return the number of bytes read (excluding BOM) or -1 if the end of stream + * @return the number of bytes read (excluding BOM) or -1 if the end of stream. * @throws NullPointerException * if the buffer is {@code null} * @throws IOException - * if an I/O error occurs + * if an I/O error occurs. */ @Override public int read(final byte[] buf) throws IOException { @@ -435,18 +435,18 @@ public int read(final byte[] buf) throws IOException { * Invokes the delegate's {@code read(byte[], int, int)} method, detecting and optionally skipping BOM. * * @param buf - * the buffer to read the bytes into + * the buffer to read the bytes into. * @param off - * The start offset + * The start offset. * @param len - * The number of bytes to read (excluding BOM) - * @return the number of bytes read or -1 if the end of stream + * The number of bytes to read (excluding BOM). + * @return the number of bytes read or -1 if the end of stream. * @throws NullPointerException * if the buffer is {@code null} * @throws IndexOutOfBoundsException * if {@code off} or {@code len} are negative, or if {@code off + len} is greater than {@code buf.length} * @throws IOException - * if an I/O error occurs + * if an I/O error occurs. */ @Override public int read(final byte[] buf, int off, int len) throws IOException { @@ -501,7 +501,7 @@ private ByteOrderMark readBom() throws IOException { * valid byte or -1 to indicate that the initial bytes have been processed already. * * @return the byte read (excluding BOM) or -1 if at the end of first bytes. - * @throws IOException if an I/O error occurs + * @throws IOException if an I/O error occurs. */ private int readFirstBytes() throws IOException { getBOM(); @@ -512,7 +512,7 @@ private int readFirstBytes() throws IOException { * Invokes the delegate's {@code reset()} method. * * @throws IOException - * if an I/O error occurs + * if an I/O error occurs. */ @Override public synchronized void reset() throws IOException { @@ -527,10 +527,10 @@ public synchronized void reset() throws IOException { * Invokes the delegate's {@code skip(long)} method, detecting and optionally skipping BOM. * * @param n - * the number of bytes to skip - * @return the number of bytes to skipped or -1 if the end of stream + * the number of bytes to skip. + * @return the number of bytes to skipped or -1 if the end of stream. * @throws IOException - * if an I/O error occurs + * if an I/O error occurs. */ @Override public long skip(final long n) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/BoundedReader.java b/src/main/java/org/apache/commons/io/input/BoundedReader.java index 5c1c255c0fe..f7ce2975308 100644 --- a/src/main/java/org/apache/commons/io/input/BoundedReader.java +++ b/src/main/java/org/apache/commons/io/input/BoundedReader.java @@ -53,8 +53,8 @@ public class BoundedReader extends Reader { /** * Constructs a bounded reader * - * @param target The target stream that will be used - * @param maxCharsFromTargetReader The maximum number of characters that can be read from target + * @param target The target stream that will be used. + * @param maxCharsFromTargetReader The maximum number of characters that can be read from target. */ public BoundedReader(final Reader target, final int maxCharsFromTargetReader) { this.target = target; @@ -64,7 +64,7 @@ public BoundedReader(final Reader target, final int maxCharsFromTargetReader) { /** * Closes the target * - * @throws IOException If an I/O error occurs while calling the underlying reader's close method + * @throws IOException If an I/O error occurs while calling the underlying reader's close method. */ @Override public void close() throws IOException { @@ -78,7 +78,7 @@ public void close() throws IOException { * Note that this parameter is not validated with respect to maxCharsFromTargetReader. There * is no way to pass past maxCharsFromTargetReader, even if this value is greater. * - * @throws IOException If an I/O error occurs while calling the underlying reader's mark method + * @throws IOException If an I/O error occurs while calling the underlying reader's mark method. * @see Reader#mark(int) */ @Override @@ -93,8 +93,8 @@ public void mark(final int readAheadLimit) throws IOException { /** * Reads a single character * - * @return -1 on EOF or the character read - * @throws IOException If an I/O error occurs while calling the underlying reader's read method + * @return -1 on EOF or the character read. + * @throws IOException If an I/O error occurs while calling the underlying reader's read method. * @see Reader#read() */ @Override @@ -114,13 +114,13 @@ public int read() throws IOException { /** * Reads into an array * - * @param cbuf The buffer to fill - * @param off The offset - * @param len The number of chars to read - * @return the number of chars read + * @param cbuf The buffer to fill. + * @param off The offset. + * @param len The number of chars to read. + * @return the number of chars read. * @throws NullPointerException if the buffer is {@code null}. * @throws IndexOutOfBoundsException if {@code off} or {@code len} are negative, or if {@code off + len} is greater than {@code cbuf.length}. - * @throws IOException If an I/O error occurs while calling the underlying reader's read method + * @throws IOException If an I/O error occurs while calling the underlying reader's read method. * @see Reader#read(char[], int, int) */ @Override @@ -140,7 +140,7 @@ public int read(final char[] cbuf, final int off, final int len) throws IOExcept /** * Resets the target to the latest mark, * - * @throws IOException If an I/O error occurs while calling the underlying reader's reset method + * @throws IOException If an I/O error occurs while calling the underlying reader's reset method. * @see Reader#reset() */ @Override 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 8e81b34508a..bd579b618cf 100644 --- a/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java +++ b/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java @@ -150,7 +150,7 @@ private BufferedFileChannelInputStream(final Builder builder) throws IOException * Constructs a new instance for the given File. * * @param file The file to stream. - * @throws IOException If an I/O error occurs + * @throws IOException If an I/O error occurs. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -163,7 +163,7 @@ public BufferedFileChannelInputStream(final File file) throws IOException { * * @param file The file to stream. * @param bufferSize buffer size. - * @throws IOException If an I/O error occurs + * @throws IOException If an I/O error occurs. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -175,7 +175,7 @@ public BufferedFileChannelInputStream(final File file, final int bufferSize) thr * Constructs a new instance for the given Path. * * @param path The path to stream. - * @throws IOException If an I/O error occurs + * @throws IOException If an I/O error occurs. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -188,7 +188,7 @@ public BufferedFileChannelInputStream(final Path path) throws IOException { * * @param path The path to stream. * @param bufferSize buffer size. - * @throws IOException If an I/O error occurs + * @throws IOException If an I/O error occurs. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -269,7 +269,7 @@ public synchronized int read(final byte[] b, final int offset, int len) throws I /** * Checks whether data is left to be read from the input stream. * - * @return true if data is left, false otherwise + * @return true if data is left, false otherwise. * @throws IOException if an I/O error occurs. */ private boolean refill() throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/CharSequenceReader.java b/src/main/java/org/apache/commons/io/input/CharSequenceReader.java index bb2be3692c9..60026b84429 100644 --- a/src/main/java/org/apache/commons/io/input/CharSequenceReader.java +++ b/src/main/java/org/apache/commons/io/input/CharSequenceReader.java @@ -99,8 +99,8 @@ public CharSequenceReader(final CharSequence charSequence) { *

    * * @param charSequence The character sequence, may be {@code null} - * @param start The start index in the character sequence, inclusive - * @throws IllegalArgumentException if the start index is negative + * @param start The start index in the character sequence, inclusive. + * @throws IllegalArgumentException if the start index is negative. * @since 2.7 */ public CharSequenceReader(final CharSequence charSequence, final int start) { @@ -120,9 +120,9 @@ public CharSequenceReader(final CharSequence charSequence, final int start) { *

    * * @param charSequence The character sequence, may be {@code null} - * @param start The start index in the character sequence, inclusive - * @param end The end index in the character sequence, exclusive - * @throws IllegalArgumentException if the start index is negative, or if the end index is smaller than the start index + * @param start The start index in the character sequence, inclusive. + * @param end The end index in the character sequence, exclusive. + * @throws IllegalArgumentException if the start index is negative, or if the end index is smaller than the start index. * @since 2.7 */ public CharSequenceReader(final CharSequence charSequence, final int start, final int end) { @@ -168,7 +168,7 @@ private int end() { /** * Mark the current position. * - * @param readAheadLimit ignored + * @param readAheadLimit ignored. */ @Override public void mark(final int readAheadLimit) { @@ -202,10 +202,10 @@ public int read() { /** * Reads the specified number of characters into the array. * - * @param array The array to store the characters in - * @param offset The starting position in the array to store - * @param length The maximum number of characters to read - * @return The number of characters read or -1 if there are no more + * @param array The array to store the characters in. + * @param offset The starting position in the array to store. + * @param length The maximum number of characters to read. + * @return The number of characters read or -1 if there are no more. * @throws NullPointerException if the array is {@code null}. * @throws IndexOutOfBoundsException if {@code offset} or {@code length} are negative, or if {@code offset + length} is greater than {@code array.length}. */ @@ -272,8 +272,8 @@ public void reset() { /** * Skip the specified number of characters. * - * @param n The number of characters to skip - * @return The actual number of characters skipped + * @param n The number of characters to skip. + * @return The actual number of characters skipped. */ @Override public long skip(final long n) { @@ -302,7 +302,7 @@ private int start() { * Gets a String representation of the underlying * character sequence. * - * @return The contents of the character sequence + * @return The contents of the character sequence. */ @Override public String toString() { diff --git a/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java b/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java index fef0d6cf17b..4b2828390e8 100644 --- a/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ClassLoaderObjectInputStream.java @@ -40,10 +40,10 @@ public class ClassLoaderObjectInputStream extends ObjectInputStream { /** * Constructs a new ClassLoaderObjectInputStream. * - * @param classLoader the ClassLoader from which classes should be loaded - * @param inputStream the InputStream to work on - * @throws IOException in case of an I/O error - * @throws StreamCorruptedException if the stream is corrupted + * @param classLoader the ClassLoader from which classes should be loaded. + * @param inputStream the InputStream to work on. + * @throws IOException in case of an I/O error. + * @throws StreamCorruptedException if the stream is corrupted. */ public ClassLoaderObjectInputStream( final ClassLoader classLoader, final InputStream inputStream) @@ -56,10 +56,10 @@ public ClassLoaderObjectInputStream( * Resolve a class specified by the descriptor using the * specified ClassLoader or the super ClassLoader. * - * @param objectStreamClass descriptor of the class - * @return the Class object described by the ObjectStreamClass - * @throws IOException in case of an I/O error - * @throws ClassNotFoundException if the Class cannot be found + * @param objectStreamClass descriptor of the class. + * @return the Class object described by the ObjectStreamClass. + * @throws IOException in case of an I/O error. + * @throws ClassNotFoundException if the Class cannot be found. */ @Override protected Class resolveClass(final ObjectStreamClass objectStreamClass) @@ -76,10 +76,10 @@ protected Class resolveClass(final ObjectStreamClass objectStreamClass) * Create a proxy class that implements the specified interfaces using * the specified ClassLoader or the super ClassLoader. * - * @param interfaces the interfaces to implement - * @return a proxy class implementing the interfaces - * @throws IOException in case of an I/O error - * @throws ClassNotFoundException if the Class cannot be found + * @param interfaces the interfaces to implement. + * @return a proxy class implementing the interfaces. + * @throws IOException in case of an I/O error. + * @throws ClassNotFoundException if the Class cannot be found. * @see ObjectInputStream#resolveProxyClass(String[]) * @since 2.1 */ diff --git a/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java b/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java index 001bfca6f55..64592afc611 100644 --- a/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java @@ -44,8 +44,8 @@ public static InputStream systemIn(final InputStream inputStream) { /** * Constructs a proxy that shields the given input stream from being closed. * - * @param inputStream the input stream to wrap - * @return the created proxy + * @param inputStream the input stream to wrap. + * @return the created proxy. * @since 2.9.0 */ public static CloseShieldInputStream wrap(final InputStream inputStream) { @@ -55,7 +55,7 @@ public static CloseShieldInputStream wrap(final InputStream inputStream) { /** * Constructs a proxy that shields the given input stream from being closed. * - * @param inputStream underlying input stream + * @param inputStream underlying input stream. * @deprecated Using this constructor prevents IDEs from warning if the * underlying input stream is never closed. Use * {@link #wrap(InputStream)} instead. diff --git a/src/main/java/org/apache/commons/io/input/CloseShieldReader.java b/src/main/java/org/apache/commons/io/input/CloseShieldReader.java index c6f116db765..e271627ceea 100644 --- a/src/main/java/org/apache/commons/io/input/CloseShieldReader.java +++ b/src/main/java/org/apache/commons/io/input/CloseShieldReader.java @@ -33,8 +33,8 @@ public class CloseShieldReader extends ProxyReader { /** * Constructs a proxy that shields the given reader from being closed. * - * @param reader the reader to wrap - * @return the created proxy + * @param reader the reader to wrap. + * @return the created proxy. * @since 2.9.0 */ public static CloseShieldReader wrap(final Reader reader) { @@ -44,7 +44,7 @@ public static CloseShieldReader wrap(final Reader reader) { /** * Constructs a proxy that shields the given reader from being closed. * - * @param reader underlying reader + * @param reader underlying reader. * @deprecated Using this constructor prevents IDEs from warning if the * underlying reader is never closed. Use {@link #wrap(Reader)} * instead. diff --git a/src/main/java/org/apache/commons/io/input/CountingInputStream.java b/src/main/java/org/apache/commons/io/input/CountingInputStream.java index f14e7130507..1182309f07f 100644 --- a/src/main/java/org/apache/commons/io/input/CountingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CountingInputStream.java @@ -40,7 +40,7 @@ public class CountingInputStream extends ProxyInputStream { /** * Constructs a new CountingInputStream. * - * @param in the InputStream to delegate to + * @param in the InputStream to delegate to. */ public CountingInputStream(final InputStream in) { super(in); @@ -57,7 +57,7 @@ public CountingInputStream(final InputStream in) { /** * Adds the number of read bytes to the count. * - * @param n number of bytes read, or -1 if no more bytes are available + * @param n number of bytes read, or -1 if no more bytes are available. * @throws IOException Not thrown here but subclasses may throw. * @since 2.0 */ @@ -77,7 +77,7 @@ protected synchronized void afterRead(final int n) throws IOException { * result in incorrect count for files over 2GB. *

    * - * @return the number of bytes accumulated + * @return the number of bytes accumulated. * @since 1.3 */ public synchronized long getByteCount() { @@ -92,8 +92,8 @@ public synchronized long getByteCount() { * See {@link #getByteCount()} for a method using a {@code long}. *

    * - * @return the number of bytes accumulated - * @throws ArithmeticException if the byte count is too large + * @return the number of bytes accumulated. + * @throws ArithmeticException if the byte count is too large. * @deprecated Use {@link #getByteCount()}. */ @Deprecated @@ -113,7 +113,7 @@ public int getCount() { * result in incorrect count for files over 2GB. *

    * - * @return the count previous to resetting + * @return the count previous to resetting. * @since 1.3 */ public synchronized long resetByteCount() { @@ -130,8 +130,8 @@ public synchronized long resetByteCount() { * See {@link #resetByteCount()} for a method using a {@code long}. *

    * - * @return the count previous to resetting - * @throws ArithmeticException if the byte count is too large + * @return the count previous to resetting. + * @throws ArithmeticException if the byte count is too large. * @deprecated Use {@link #resetByteCount()}. */ @Deprecated @@ -147,8 +147,8 @@ public int resetCount() { * Skips the stream over the specified number of bytes, adding the skipped * amount to the count. * - * @param length the number of bytes to skip - * @return the actual number of bytes skipped + * @param length the number of bytes to skip. + * @return the actual number of bytes skipped. * @throws IOException if an I/O error occurs. * @see InputStream#skip(long) */ diff --git a/src/main/java/org/apache/commons/io/input/DemuxInputStream.java b/src/main/java/org/apache/commons/io/input/DemuxInputStream.java index ad49dca2793..3a0132dc8e6 100644 --- a/src/main/java/org/apache/commons/io/input/DemuxInputStream.java +++ b/src/main/java/org/apache/commons/io/input/DemuxInputStream.java @@ -40,8 +40,8 @@ public DemuxInputStream() { /** * Binds the specified stream to the current thread. * - * @param input the stream to bind - * @return the InputStream that was previously active + * @param input the stream to bind. + * @return the InputStream that was previously active. */ public InputStream bindStream(final InputStream input) { final InputStream oldValue = inputStreamLocal.get(); @@ -52,7 +52,7 @@ public InputStream bindStream(final InputStream input) { /** * Closes stream associated with current thread. * - * @throws IOException if an error occurs + * @throws IOException if an error occurs. */ @SuppressWarnings("resource") // we actually close the stream here @Override @@ -63,8 +63,8 @@ public void close() throws IOException { /** * Reads byte from stream associated with current thread. * - * @return the byte read from stream - * @throws IOException if an error occurs + * @return the byte read from stream. + * @throws IOException if an error occurs. */ @Override public int read() throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java b/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java index 44fb12ff56e..0ed0b0bfda6 100644 --- a/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java @@ -40,7 +40,7 @@ public class MarkShieldInputStream extends ProxyInputStream { * Constructs a proxy that shields the given input stream from being * marked or rest. * - * @param in underlying input stream + * @param in underlying input stream. */ public MarkShieldInputStream(final InputStream in) { super(in); diff --git a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java index 5f2fb452ef0..7188c564502 100644 --- a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java @@ -148,7 +148,7 @@ public static class MessageDigestMaintainingObserver extends Observer { /** * Constructs an MessageDigestMaintainingObserver for the given MessageDigest. * - * @param messageDigest the message digest to use + * @param messageDigest the message digest to use. * @throws NullPointerException if messageDigest is null. */ public MessageDigestMaintainingObserver(final MessageDigest messageDigest) { @@ -211,7 +211,7 @@ private MessageDigestCalculatingInputStream(final Builder builder) throws IOExce * The MD5 algorithm is weak and should not be used. *

    * - * @param inputStream the stream to calculate the message digest for + * @param inputStream the stream to calculate the message digest for. * @throws NoSuchAlgorithmException if no Provider supports a MessageDigestSpi implementation for the specified algorithm. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @@ -226,8 +226,8 @@ public MessageDigestCalculatingInputStream(final InputStream inputStream) throws * The MD5 cryptographic algorithm is weak and should not be used. *

    * - * @param inputStream the stream to calculate the message digest for - * @param messageDigest the message digest to use + * @param inputStream the stream to calculate the message digest for. + * @param messageDigest the message digest to use. * @throws NullPointerException if messageDigest is null. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @@ -243,7 +243,7 @@ public MessageDigestCalculatingInputStream(final InputStream inputStream, final * The MD5 cryptographic algorithm is weak and should not be used. *

    * - * @param inputStream the stream to calculate the message digest for + * @param inputStream the stream to calculate the message digest for. * @param algorithm the name of the algorithm requested. See the MessageDigest section in the *
    Java Cryptography * Architecture Standard Algorithm Name Documentation for information about standard algorithm names. @@ -262,7 +262,7 @@ public MessageDigestCalculatingInputStream(final InputStream inputStream, final * data has been read, if that is what you want. The easiest way to do so is by invoking {@link #consume()}. *

    * - * @return the message digest used + * @return the message digest used. */ public MessageDigest getMessageDigest() { return messageDigest; diff --git a/src/main/java/org/apache/commons/io/input/MessageDigestInputStream.java b/src/main/java/org/apache/commons/io/input/MessageDigestInputStream.java index dac3f2afb5e..c8c3af88347 100644 --- a/src/main/java/org/apache/commons/io/input/MessageDigestInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MessageDigestInputStream.java @@ -152,7 +152,7 @@ public static class MessageDigestMaintainingObserver extends Observer { /** * Constructs an MessageDigestMaintainingObserver for the given MessageDigest. * - * @param messageDigest the message digest to use + * @param messageDigest the message digest to use. * @throws NullPointerException if messageDigest is null. */ public MessageDigestMaintainingObserver(final MessageDigest messageDigest) { @@ -190,7 +190,7 @@ public static Builder builder() { * The MD5 cryptographic algorithm is weak and should not be used. *

    * - * @param builder A builder use to get the stream to calculate the message digest and the message digest to use + * @param builder A builder use to get the stream to calculate the message digest and the message digest to use. * @throws NullPointerException if messageDigest is null. */ private MessageDigestInputStream(final Builder builder) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/NullInputStream.java b/src/main/java/org/apache/commons/io/input/NullInputStream.java index 5fa9b817b5c..1f05410f636 100644 --- a/src/main/java/org/apache/commons/io/input/NullInputStream.java +++ b/src/main/java/org/apache/commons/io/input/NullInputStream.java @@ -272,7 +272,7 @@ public int read() throws IOException { /** * Reads some bytes into the specified array. * - * @param bytes The byte array to read into + * @param bytes The byte array to read into. * @return The number of bytes read or {@code -1} if the end of file has been reached and {@code throwEofException} is set to {@code false}. * @throws NullPointerException if the byte array is {@code null}. * @throws EOFException if the end of file is reached and {@code throwEofException} is set to {@code true}. diff --git a/src/main/java/org/apache/commons/io/input/NullReader.java b/src/main/java/org/apache/commons/io/input/NullReader.java index 28f3d37eb21..0405f3943d0 100644 --- a/src/main/java/org/apache/commons/io/input/NullReader.java +++ b/src/main/java/org/apache/commons/io/input/NullReader.java @@ -217,7 +217,7 @@ protected int processChar() { * This implementation leaves the character array unchanged. *

    * - * @param chars The character array + * @param chars The character array. * @param offset The offset to start at. * @param length The number of characters. */ @@ -250,7 +250,7 @@ public int read() throws IOException { /** * Reads some characters into the specified array. * - * @param chars The character array to read into + * @param chars The character array to read into. * @return The number of characters read or {@code -1} * if the end of file has been reached and * {@code throwEofException} is set to {@code false}. diff --git a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java index a1287b857f7..1909f859a65 100644 --- a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java @@ -144,7 +144,7 @@ public void data(final int value) throws IOException { /** * Called to indicate that an error occurred on the underlying stream. * - * @param exception the exception to throw + * @param exception the exception to throw. * @throws IOException if an I/O error occurs. */ public void error(final IOException exception) throws IOException { @@ -361,7 +361,7 @@ public int read(final byte[] buffer, final int offset, final int length) throws /** * Removes an Observer. * - * @param observer the observer to remove + * @param observer the observer to remove. */ public void remove(final Observer observer) { observers.remove(observer); diff --git a/src/main/java/org/apache/commons/io/input/ProxyReader.java b/src/main/java/org/apache/commons/io/input/ProxyReader.java index 7bfed636497..47cff05b1f1 100644 --- a/src/main/java/org/apache/commons/io/input/ProxyReader.java +++ b/src/main/java/org/apache/commons/io/input/ProxyReader.java @@ -40,7 +40,7 @@ public abstract class ProxyReader extends FilterReader { /** * Constructs a new ProxyReader. * - * @param delegate the Reader to delegate to + * @param delegate the Reader to delegate to. */ public ProxyReader(final Reader delegate) { // the delegate is stored in a protected superclass variable named 'in' @@ -60,8 +60,8 @@ public ProxyReader(final Reader delegate) { * {@link #reset()}. You need to explicitly override those methods if * you want to add post-processing steps also to them. * - * @param n number of chars read, or -1 if the end of stream was reached - * @throws IOException if the post-processing fails + * @param n number of chars read, or -1 if the end of stream was reached. + * @throws IOException if the post-processing fails. * @since 2.0 */ @SuppressWarnings("unused") // Possibly thrown from subclasses. @@ -83,8 +83,8 @@ protected void afterRead(final int n) throws IOException { * {@link #reset()}. You need to explicitly override those methods if * you want to add pre-processing steps also to them. * - * @param n number of chars that the caller asked to be read - * @throws IOException if the pre-processing fails + * @param n number of chars that the caller asked to be read. + * @throws IOException if the pre-processing fails. * @since 2.0 */ @SuppressWarnings("unused") // Possibly thrown from subclasses. @@ -110,7 +110,9 @@ public void close() throws IOException { *

    * This method provides a point to implement custom exception * handling. The default behavior is to re-throw the exception. - * @param e The IOException thrown + *

    + * + * @param e The IOException thrown. * @throws IOException if an I/O error occurs. * @since 2.0 */ @@ -120,7 +122,7 @@ protected void handleIOException(final IOException e) throws IOException { /** * Invokes the delegate's {@code mark(int)} method. - * @param readAheadLimit read ahead limit + * @param readAheadLimit read ahead limit. * @throws IOException if an I/O error occurs. */ @Override @@ -134,7 +136,7 @@ public synchronized void mark(final int readAheadLimit) throws IOException { /** * Invokes the delegate's {@code markSupported()} method. - * @return true if mark is supported, otherwise false + * @return true if mark is supported, otherwise false. */ @Override public boolean markSupported() { @@ -143,7 +145,7 @@ public boolean markSupported() { /** * Invokes the delegate's {@code read()} method. - * @return the character read or -1 if the end of stream + * @return the character read or -1 if the end of stream. * @throws IOException if an I/O error occurs. */ @Override @@ -161,8 +163,8 @@ public int read() throws IOException { /** * Invokes the delegate's {@code read(char[])} method. - * @param chr the buffer to read the characters into - * @return the number of characters read or -1 if the end of stream + * @param chr the buffer to read the characters into. + * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. */ @Override @@ -180,10 +182,10 @@ public int read(final char[] chr) throws IOException { /** * Invokes the delegate's {@code read(char[], int, int)} method. - * @param chr the buffer to read the characters into - * @param st The start offset - * @param len The number of bytes to read - * @return the number of characters read or -1 if the end of stream + * @param chr the buffer to read the characters into. + * @param st The start offset. + * @param len The number of bytes to read. + * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. */ @Override @@ -201,8 +203,8 @@ public int read(final char[] chr, final int st, final int len) throws IOExceptio /** * Invokes the delegate's {@code read(CharBuffer)} method. - * @param target the char buffer to read the characters into - * @return the number of characters read or -1 if the end of stream + * @param target the char buffer to read the characters into. + * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. * @since 2.0 */ @@ -221,7 +223,7 @@ public int read(final CharBuffer target) throws IOException { /** * Invokes the delegate's {@code ready()} method. - * @return true if the stream is ready to be read + * @return true if the stream is ready to be read. * @throws IOException if an I/O error occurs. */ @Override @@ -249,8 +251,8 @@ public synchronized void reset() throws IOException { /** * Invokes the delegate's {@code skip(long)} method. - * @param ln the number of bytes to skip - * @return the number of bytes to skipped or EOF if the end of stream + * @param ln the number of bytes to skip. + * @return the number of bytes to skipped or EOF if the end of stream. * @throws IOException if an I/O error occurs. */ @Override 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 09d7bbaa1a8..45f19cc94c5 100644 --- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java @@ -229,7 +229,7 @@ private ReaderInputStream(final Builder builder) throws IOException { * buffer size of {@value IOUtils#DEFAULT_BUFFER_SIZE} characters. * * @param reader the target {@link Reader} - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader) { @@ -244,7 +244,7 @@ public ReaderInputStream(final Reader reader) { *

    * * @param reader the target {@link Reader} - * @param charset the charset encoding + * @param charset the charset encoding. * @deprecated Use {@link ReaderInputStream#builder()} instead, will be protected for subclasses. */ @Deprecated @@ -262,7 +262,7 @@ public ReaderInputStream(final Reader reader, final Charset charset) { * @param reader the target {@link Reader}. * @param charset the charset encoding. * @param bufferSize the size of the input buffer in number of characters. - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader, final Charset charset, final int bufferSize) { @@ -284,9 +284,9 @@ public ReaderInputStream(final Reader reader, final Charset charset, final int b *

    * * @param reader the target {@link Reader} - * @param charsetEncoder the charset encoder + * @param charsetEncoder the charset encoder. * @since 2.1 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader, final CharsetEncoder charsetEncoder) { @@ -303,9 +303,9 @@ public ReaderInputStream(final Reader reader, final CharsetEncoder charsetEncode * * @param reader the target {@link Reader} * @param charsetEncoder the charset encoder, null defaults to the default Charset encoder. - * @param bufferSize the size of the input buffer in number of characters + * @param bufferSize the size of the input buffer in number of characters. * @since 2.1 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader, final CharsetEncoder charsetEncoder, final int bufferSize) { @@ -325,8 +325,8 @@ public ReaderInputStream(final Reader reader, final CharsetEncoder charsetEncode *

    * * @param reader the target {@link Reader} - * @param charsetName the name of the charset encoding - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @param charsetName the name of the charset encoding. + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader, final String charsetName) { @@ -342,8 +342,8 @@ public ReaderInputStream(final Reader reader, final String charsetName) { * * @param reader the target {@link Reader} * @param charsetName the name of the charset encoding, null maps to the default Charset. - * @param bufferSize the size of the input buffer in number of characters - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @param bufferSize the size of the input buffer in number of characters. + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader, final String charsetName, final int bufferSize) { @@ -372,7 +372,7 @@ public void close() throws IOException { /** * Fills the internal char buffer from the reader. * - * @throws IOException If an I/O error occurs + * @throws IOException If an I/O error occurs. */ private void fillBuffer() throws IOException { if (endOfInput) { @@ -415,7 +415,7 @@ CharsetEncoder getCharsetEncoder() { /** * Reads a single byte. * - * @return either the byte read or {@code -1} if the end of the stream has been reached + * @return either the byte read or {@code -1} if the end of the stream has been reached. * @throws IOException if an I/O error occurs. */ @Override @@ -436,7 +436,7 @@ public int read() throws IOException { * Reads the specified number of bytes into an array. * * @param b the byte array to read into, must not be {@code null} - * @return the number of bytes read or {@code -1} if the end of the stream has been reached + * @return the number of bytes read or {@code -1} if the end of the stream has been reached. * @throws NullPointerException if the byte array is {@code null}. * @throws IOException if an I/O error occurs. */ @@ -448,10 +448,10 @@ public int read(final byte[] b) throws IOException { /** * Reads the specified number of bytes into an array. * - * @param array the byte array to read into - * @param off the offset to start reading bytes into - * @param len the number of bytes to read - * @return the number of bytes read or {@code -1} if the end of the stream has been reached + * @param array the byte array to read into. + * @param off the offset to start reading bytes into. + * @param len the number of bytes to read. + * @return the number of bytes read or {@code -1} if the end of the stream has been reached. * @throws NullPointerException if the byte array is {@code null}. * @throws IndexOutOfBoundsException if {@code off} or {@code len} are negative, or if {@code off + len} is greater than {@code array.length}. * @throws IOException if an I/O error occurs. 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 e88606d9e76..da5688b5155 100644 --- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java @@ -137,10 +137,10 @@ private final class FilePart { /** * Constructs a new instance. * - * @param partNumber the part number - * @param length its length - * @param leftOverOfLastFilePart remainder - * @throws IOException if there is a problem reading the file + * @param partNumber the part number. + * @param length its length. + * @param leftOverOfLastFilePart remainder. + * @throws IOException if there is a problem reading the file. */ private FilePart(final long partNumber, final int length, final byte[] leftOverOfLastFilePart) throws IOException { this.partNumber = partNumber; @@ -181,9 +181,9 @@ private void createLeftOver() { /** * Finds the new-line sequence and return its length. * - * @param data buffer to scan - * @param i start offset in buffer - * @return length of newline sequence or 0 if none found + * @param data buffer to scan. + * @param i start offset in buffer. + * @return length of newline sequence or 0 if none found. */ private int getNewLineMatchByteCount(final byte[] data, final int i) { for (final byte[] newLineSequence : newLineSequences) { @@ -202,7 +202,7 @@ private int getNewLineMatchByteCount(final byte[] data, final int i) { /** * Reads a line. * - * @return the line or null + * @return the line or null. */ private String readLine() { //NOPMD Bug in PMD @@ -260,8 +260,8 @@ private String readLine() { //NOPMD Bug in PMD /** * Handles block rollover * - * @return the new FilePart or null - * @throws IOException if there was a problem reading the file + * @return the new FilePart or null. + * @throws IOException if there was a problem reading the file. */ private FilePart rollOver() throws IOException { @@ -356,7 +356,7 @@ private ReversedLinesFileReader(final Builder builder) throws IOException { /** * Constructs a ReversedLinesFileReader with default block size of 4KB and the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * - * @param file the file to be read + * @param file the file to be read. * @throws IOException if an I/O error occurs. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @@ -369,7 +369,7 @@ public ReversedLinesFileReader(final File file) throws IOException { * Constructs a ReversedLinesFileReader with default block size of 4KB and the * specified encoding. * - * @param file the file to be read + * @param file the file to be read. * @param charset the charset to use, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.5 @@ -383,7 +383,7 @@ public ReversedLinesFileReader(final File file, final Charset charset) throws IO /** * Constructs a ReversedLinesFileReader with the given block size and encoding. * - * @param file the file to be read + * @param file the file to be read. * @param blockSize size of the internal buffer (for ideal performance this * should match with the block size of the underlying file * system). @@ -400,13 +400,13 @@ public ReversedLinesFileReader(final File file, final int blockSize, final Chars /** * Constructs a ReversedLinesFileReader with the given block size and encoding. * - * @param file the file to be read + * @param file the file to be read. * @param blockSize size of the internal buffer (for ideal performance this * should match with the block size of the underlying file * system). * @param charsetName the encoding of the file, null uses the default Charset. - * @throws IOException if an I/O error occurs - * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported + * @throws IOException if an I/O error occurs. + * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated @@ -418,7 +418,7 @@ public ReversedLinesFileReader(final File file, final int blockSize, final Strin * Constructs a ReversedLinesFileReader with default block size of 4KB and the * specified encoding. * - * @param file the file to be read + * @param file the file to be read. * @param charset the charset to use, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.7 @@ -432,7 +432,7 @@ public ReversedLinesFileReader(final Path file, final Charset charset) throws IO /** * Constructs a ReversedLinesFileReader with the given block size and encoding. * - * @param file the file to be read + * @param file the file to be read. * @param blockSize size of the internal buffer (for ideal performance this * should match with the block size of the underlying file * system). @@ -449,13 +449,13 @@ public ReversedLinesFileReader(final Path file, final int blockSize, final Chars /** * Constructs a ReversedLinesFileReader with the given block size and encoding. * - * @param file the file to be read + * @param file the file to be read. * @param blockSize size of the internal buffer (for ideal performance this * should match with the block size of the underlying file * system). * @param charsetName the encoding of the file, null uses the default Charset. - * @throws IOException if an I/O error occurs - * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported + * @throws IOException if an I/O error occurs. + * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @since 2.7 * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @@ -509,7 +509,7 @@ public Iterator unwrap() { /** * Returns the lines of the file from bottom to top. * - * @return the next line or null if the start of the file is reached + * @return the next line or null if the start of the file is reached. * @throws IOException if an I/O error occurs. */ public String readLine() throws IOException { @@ -541,7 +541,7 @@ public String readLine() throws IOException { *

    * * @param lineCount How many lines to read. - * @return A new list + * @return A new list. * @throws IOException if an I/O error occurs. * @since 2.8.0 */ diff --git a/src/main/java/org/apache/commons/io/input/SequenceReader.java b/src/main/java/org/apache/commons/io/input/SequenceReader.java index daeb71faa92..269ce1cb8be 100644 --- a/src/main/java/org/apache/commons/io/input/SequenceReader.java +++ b/src/main/java/org/apache/commons/io/input/SequenceReader.java @@ -44,7 +44,7 @@ public class SequenceReader extends Reader { /** * Constructs a new instance with readers * - * @param readers the readers to read + * @param readers the readers to read. */ public SequenceReader(final Iterable readers) { this.readers = Objects.requireNonNull(readers, "readers").iterator(); @@ -54,7 +54,7 @@ public SequenceReader(final Iterable readers) { /** * Constructs a new instance with readers * - * @param readers the readers to read + * @param readers the readers to read. */ public SequenceReader(final Reader... readers) { this(Arrays.asList(readers)); diff --git a/src/main/java/org/apache/commons/io/input/SwappedDataInputStream.java b/src/main/java/org/apache/commons/io/input/SwappedDataInputStream.java index a901ec6bc74..72e46367490 100644 --- a/src/main/java/org/apache/commons/io/input/SwappedDataInputStream.java +++ b/src/main/java/org/apache/commons/io/input/SwappedDataInputStream.java @@ -37,7 +37,7 @@ public class SwappedDataInputStream extends ProxyInputStream implements DataInpu /** * Constructs a SwappedDataInputStream. * - * @param input InputStream to read from + * @param input InputStream to read from. */ public SwappedDataInputStream(final InputStream input) { super(input); @@ -46,9 +46,9 @@ public SwappedDataInputStream(final InputStream input) { /** * Return {@code {@link #readByte()} != 0} * - * @return false if the byte read is zero, otherwise true + * @return false if the byte read is zero, otherwise true. * @throws IOException if an I/O error occurs. - * @throws EOFException if an end of file is reached unexpectedly + * @throws EOFException if an end of file is reached unexpectedly. */ @Override public boolean readBoolean() throws IOException, EOFException { @@ -58,9 +58,9 @@ public boolean readBoolean() throws IOException, EOFException { /** * Invokes the delegate's {@code read()} method. * - * @return the byte read or -1 if the end of stream + * @return the byte read or -1 if the end of stream. * @throws IOException if an I/O error occurs. - * @throws EOFException if an end of file is reached unexpectedly + * @throws EOFException if an end of file is reached unexpectedly. */ @Override public byte readByte() throws IOException, EOFException { @@ -70,9 +70,9 @@ public byte readByte() throws IOException, EOFException { /** * Reads a 2 byte, unsigned, little-endian UTF-16 code point. * - * @return the UTF-16 code point read or -1 if the end of stream + * @return the UTF-16 code point read or -1 if the end of stream. * @throws IOException if an I/O error occurs. - * @throws EOFException if an end of file is reached unexpectedly + * @throws EOFException if an end of file is reached unexpectedly. */ @Override public char readChar() throws IOException, EOFException { @@ -82,9 +82,9 @@ public char readChar() throws IOException, EOFException { /** * Reads an 8 byte, two's complement, little-endian long. * - * @return the read long + * @return the read long. * @throws IOException if an I/O error occurs. - * @throws EOFException if an end of file is reached unexpectedly + * @throws EOFException if an end of file is reached unexpectedly. */ @Override public double readDouble() throws IOException, EOFException { @@ -94,9 +94,9 @@ public double readDouble() throws IOException, EOFException { /** * Reads a 4 byte, IEEE 754, little-endian float. * - * @return the read float + * @return the read float. * @throws IOException if an I/O error occurs. - * @throws EOFException if an end of file is reached unexpectedly + * @throws EOFException if an end of file is reached unexpectedly. */ @Override public float readFloat() throws IOException, EOFException { @@ -106,8 +106,8 @@ public float readFloat() throws IOException, EOFException { /** * Invokes the delegate's {@code read(byte[] data, int, int)} method. * - * @param data the buffer to read the bytes into - * @throws EOFException if an end of file is reached unexpectedly + * @param data the buffer to read the bytes into. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -118,10 +118,10 @@ public void readFully(final byte[] data) throws IOException, EOFException { /** * Invokes the delegate's {@code read(byte[] data, int, int)} method. * - * @param data the buffer to read the bytes into - * @param offset The start offset - * @param length The number of bytes to read - * @throws EOFException if an end of file is reached unexpectedly + * @param data the buffer to read the bytes into. + * @param offset The start offset. + * @param length The number of bytes to read. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -143,8 +143,8 @@ public void readFully(final byte[] data, final int offset, final int length) thr /** * Reads a 4 byte, two's complement little-endian integer. * - * @return the read int - * @throws EOFException if an end of file is reached unexpectedly + * @return the read int. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -155,10 +155,10 @@ public int readInt() throws IOException, EOFException { /** * Not currently supported - throws {@link UnsupportedOperationException}. * - * @return the line read - * @throws EOFException if an end of file is reached unexpectedly - * @throws IOException if an I/O error occurs - * @throws UnsupportedOperationException always + * @return the line read. + * @throws EOFException if an end of file is reached unexpectedly. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException always. */ @Override public String readLine() throws IOException, EOFException { @@ -168,8 +168,8 @@ public String readLine() throws IOException, EOFException { /** * Reads an 8 byte, two's complement little-endian integer. * - * @return the read long - * @throws EOFException if an end of file is reached unexpectedly + * @return the read long. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -180,8 +180,8 @@ public long readLong() throws IOException, EOFException { /** * Reads a 2 byte, two's complement, little-endian integer. * - * @return the read short - * @throws EOFException if an end of file is reached unexpectedly + * @return the read short. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -192,8 +192,8 @@ public short readShort() throws IOException, EOFException { /** * Invokes the delegate's {@code read()} method. * - * @return the byte read or -1 if the end of stream - * @throws EOFException if an end of file is reached unexpectedly + * @return the byte read or -1 if the end of stream. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -204,8 +204,8 @@ public int readUnsignedByte() throws IOException, EOFException { /** * Reads a 2 byte, unsigned, little-endian integer. * - * @return the read short - * @throws EOFException if an end of file is reached unexpectedly + * @return the read short. + * @throws EOFException if an end of file is reached unexpectedly. * @throws IOException if an I/O error occurs. */ @Override @@ -216,10 +216,10 @@ public int readUnsignedShort() throws IOException, EOFException { /** * Not currently supported - throws {@link UnsupportedOperationException}. * - * @return never - * @throws EOFException if an end of file is reached unexpectedly - * @throws IOException if an I/O error occurs - * @throws UnsupportedOperationException always + * @return never. + * @throws EOFException if an end of file is reached unexpectedly. + * @throws IOException if an I/O error occurs. + * @throws UnsupportedOperationException always. */ @Override public String readUTF() throws IOException, EOFException { @@ -229,9 +229,9 @@ public String readUTF() throws IOException, EOFException { /** * Invokes the delegate's {@code skip(int)} method. * - * @param count the number of bytes to skip - * @return the number of bytes skipped or -1 if the end of stream - * @throws IOException if an I/O error occurs + * @param count the number of bytes to skip. + * @return the number of bytes skipped or -1 if the end of stream. + * @throws IOException if an I/O error occurs. */ @Override public int skipBytes(final int count) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java index 141f9c54602..88ad492246d 100644 --- a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java +++ b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java @@ -76,7 +76,7 @@ public class TaggedInputStream extends ProxyInputStream { /** * Constructs a tagging decorator for the given input stream. * - * @param proxy input stream to be decorated + * @param proxy input stream to be decorated. */ public TaggedInputStream(final InputStream proxy) { super(proxy); @@ -85,7 +85,7 @@ public TaggedInputStream(final InputStream proxy) { /** * Tags any IOExceptions thrown, wrapping and re-throwing. * - * @param e The IOException thrown + * @param e The IOException thrown. * @throws IOException if an I/O error occurs. */ @Override @@ -96,9 +96,9 @@ protected void handleIOException(final IOException e) throws IOException { /** * Tests if the given exception was caused by this stream. * - * @param exception an exception + * @param exception an exception. * @return {@code true} if the exception was thrown by this stream, - * {@code false} otherwise + * {@code false} otherwise. */ public boolean isCauseOf(final Throwable exception) { return TaggedIOException.isTaggedWith(exception, tag); @@ -111,8 +111,8 @@ public boolean isCauseOf(final Throwable exception) { * original wrapped exception. Returns normally if the exception was * not thrown by this stream. * - * @param throwable an exception - * @throws IOException original exception, if any, thrown by this stream + * @param throwable an exception. + * @throws IOException original exception, if any, thrown by this stream. */ public void throwIfCauseOf(final Throwable throwable) throws IOException { TaggedIOException.throwCauseIfTaggedWith(throwable, tag); diff --git a/src/main/java/org/apache/commons/io/input/TaggedReader.java b/src/main/java/org/apache/commons/io/input/TaggedReader.java index 97297a9fd28..2573873d271 100644 --- a/src/main/java/org/apache/commons/io/input/TaggedReader.java +++ b/src/main/java/org/apache/commons/io/input/TaggedReader.java @@ -75,7 +75,7 @@ public class TaggedReader extends ProxyReader { /** * Constructs a tagging decorator for the given reader. * - * @param proxy reader to be decorated + * @param proxy reader to be decorated. */ public TaggedReader(final Reader proxy) { super(proxy); @@ -84,7 +84,7 @@ public TaggedReader(final Reader proxy) { /** * Tags any IOExceptions thrown, wrapping and re-throwing. * - * @param e The IOException thrown + * @param e The IOException thrown. * @throws IOException if an I/O error occurs. */ @Override @@ -95,8 +95,8 @@ protected void handleIOException(final IOException e) throws IOException { /** * Tests if the given exception was caused by this reader. * - * @param exception an exception - * @return {@code true} if the exception was thrown by this reader, {@code false} otherwise + * @param exception an exception. + * @return {@code true} if the exception was thrown by this reader, {@code false} otherwise. */ public boolean isCauseOf(final Throwable exception) { return TaggedIOException.isTaggedWith(exception, tag); @@ -107,8 +107,8 @@ public boolean isCauseOf(final Throwable exception) { * {@link TaggedIOException} wrapper created by this decorator, and then unwraps and throws the original wrapped * exception. Returns normally if the exception was not thrown by this reader. * - * @param throwable an exception - * @throws IOException original exception, if any, thrown by this reader + * @param throwable an exception. + * @throws IOException original exception, if any, thrown by this reader. */ public void throwIfCauseOf(final Throwable throwable) throws IOException { TaggedIOException.throwCauseIfTaggedWith(throwable, tag); diff --git a/src/main/java/org/apache/commons/io/input/Tailer.java b/src/main/java/org/apache/commons/io/input/Tailer.java index 620ba6febcd..2a631d89351 100644 --- a/src/main/java/org/apache/commons/io/input/Tailer.java +++ b/src/main/java/org/apache/commons/io/input/Tailer.java @@ -275,7 +275,7 @@ protected Builder setOrigin(final AbstractOrigin origin) { /** * Sets the re-open behavior. * - * @param reOpen whether to close/reopen the file between chunks + * @param reOpen whether to close/reopen the file between chunks. * @return {@code this} instance. */ public Builder setReOpen(final boolean reOpen) { @@ -740,12 +740,12 @@ private Tailer(final Builder builder) { * Creates a Tailer for the given file, with a specified buffer size. * * @param file the file to follow. - * @param charset the Charset to be used for reading the file + * @param charset the Charset to be used for reading the file. * @param tailerListener the TailerListener to use. * @param delayMillis the delay between checks of the file for new content in milliseconds. * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. - * @param reOpen if true, close and reopen the file between reading chunks - * @param bufSize Buffer size + * @param reOpen if true, close and reopen the file between reading chunks. + * @param bufSize Buffer size. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -800,7 +800,7 @@ public Tailer(final File file, final TailerListener tailerListener, final long d * @param tailerListener the TailerListener to use. * @param delayMillis the delay between checks of the file for new content in milliseconds. * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. - * @param reOpen if true, close and reopen the file between reading chunks + * @param reOpen if true, close and reopen the file between reading chunks. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -815,8 +815,8 @@ public Tailer(final File file, final TailerListener tailerListener, final long d * @param tailerListener the TailerListener to use. * @param delayMillis the delay between checks of the file for new content in milliseconds. * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. - * @param reOpen if true, close and reopen the file between reading chunks - * @param bufferSize Buffer size + * @param reOpen if true, close and reopen the file between reading chunks. + * @param bufferSize Buffer size. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -831,7 +831,7 @@ public Tailer(final File file, final TailerListener tailerListener, final long d * @param tailerListener the TailerListener to use. * @param delayMillis the delay between checks of the file for new content in milliseconds. * @param end Set to true to tail from the end of the file, false to tail from the beginning of the file. - * @param bufferSize Buffer size + * @param bufferSize Buffer size. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -843,13 +843,13 @@ public Tailer(final File file, final TailerListener tailerListener, final long d * Creates a Tailer for the given file, with a specified buffer size. * * @param tailable the file to follow. - * @param charset the Charset to be used for reading the file + * @param charset the Charset to be used for reading the file. * @param tailerListener the TailerListener to use. * @param delayDuration the delay between checks of the file for new content in milliseconds. * @param tailAtEnd Set to true to tail from the end of the file, false to tail from the beginning of the file. - * @param reOpen if true, close and reopen the file between reading chunks - * @param ignoreTouch if true, file timestamp changes without content change get ignored - * @param bufferSize Buffer size + * @param reOpen if true, close and reopen the file between reading chunks. + * @param ignoreTouch if true, file timestamp changes without content change get ignored. + * @param bufferSize Buffer size. */ private Tailer(final Tailable tailable, final Charset charset, final TailerListener tailerListener, final Duration delayDuration, final boolean tailAtEnd, final boolean reOpen, final int bufferSize, final boolean ignoreTouch) { @@ -897,8 +897,8 @@ public Duration getDelayDuration() { /** * Gets the file. * - * @return the file - * @throws IllegalStateException if constructed using a user provided {@link Tailable} implementation + * @return the file. + * @throws IllegalStateException if constructed using a user provided {@link Tailable} implementation. */ public File getFile() { if (tailable instanceof TailablePath) { @@ -920,7 +920,7 @@ protected boolean getRun() { /** * Gets the Tailable. * - * @return the Tailable + * @return the Tailable. * @since 2.12.0 */ public Tailable getTailable() { @@ -930,8 +930,8 @@ public Tailable getTailable() { /** * Reads new lines. * - * @param reader The file to read - * @return The new position after the lines have been read + * @param reader The file to read. + * @return The new position after the lines have been read. * @throws IOException if an I/O error occurs. */ private long readLines(final RandomAccessResourceBridge reader) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/TeeInputStream.java b/src/main/java/org/apache/commons/io/input/TeeInputStream.java index 1949f977e09..0c852cd5f88 100644 --- a/src/main/java/org/apache/commons/io/input/TeeInputStream.java +++ b/src/main/java/org/apache/commons/io/input/TeeInputStream.java @@ -55,8 +55,8 @@ public class TeeInputStream extends ProxyInputStream { * and copies all read bytes to the given {@link OutputStream}. The given * output stream will not be closed when this stream gets closed. * - * @param input input stream to be proxied - * @param branch output stream that will receive a copy of all bytes read + * @param input input stream to be proxied. + * @param branch output stream that will receive a copy of all bytes read. */ public TeeInputStream(final InputStream input, final OutputStream branch) { this(input, branch, false); @@ -68,10 +68,10 @@ public TeeInputStream(final InputStream input, final OutputStream branch) { * output stream will be closed when this stream gets closed if the * closeBranch parameter is {@code true}. * - * @param input input stream to be proxied - * @param branch output stream that will receive a copy of all bytes read + * @param input input stream to be proxied. + * @param branch output stream that will receive a copy of all bytes read. * @param closeBranch flag for closing also the output stream when this - * stream is closed + * stream is closed. */ public TeeInputStream( final InputStream input, final OutputStream branch, final boolean closeBranch) { @@ -85,7 +85,7 @@ public TeeInputStream( * output stream. An exception thrown from one stream will not prevent * closing of the other stream. * - * @throws IOException if either of the streams could not be closed + * @throws IOException if either of the streams could not be closed. */ @Override public void close() throws IOException { @@ -102,8 +102,8 @@ public void close() throws IOException { * Reads a single byte from the proxied input stream and writes it to * the associated output stream. * - * @return next byte from the stream, or -1 if the stream has ended - * @throws IOException if the stream could not be read (or written) + * @return next byte from the stream, or -1 if the stream has ended. + * @throws IOException if the stream could not be read (or written). */ @Override public int read() throws IOException { @@ -118,9 +118,9 @@ public int read() throws IOException { * Reads bytes from the proxied input stream and writes the read bytes * to the associated output stream. * - * @param bts byte buffer - * @return number of bytes read, or -1 if the stream has ended - * @throws IOException if the stream could not be read (or written) + * @param bts byte buffer. + * @return number of bytes read, or -1 if the stream has ended. + * @throws IOException if the stream could not be read (or written). */ @Override public int read(final byte[] bts) throws IOException { @@ -135,11 +135,11 @@ public int read(final byte[] bts) throws IOException { * Reads bytes from the proxied input stream and writes the read bytes * to the associated output stream. * - * @param bts byte buffer - * @param st start offset within the buffer - * @param end maximum number of bytes to read - * @return number of bytes read, or -1 if the stream has ended - * @throws IOException if the stream could not be read (or written) + * @param bts byte buffer. + * @param st start offset within the buffer. + * @param end maximum number of bytes to read. + * @return number of bytes read, or -1 if the stream has ended. + * @throws IOException if the stream could not be read (or written). */ @Override public int read(final byte[] bts, final int st, final int end) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/TeeReader.java b/src/main/java/org/apache/commons/io/input/TeeReader.java index 72fa4ecb2f5..892f1d575bf 100644 --- a/src/main/java/org/apache/commons/io/input/TeeReader.java +++ b/src/main/java/org/apache/commons/io/input/TeeReader.java @@ -50,8 +50,8 @@ public class TeeReader extends ProxyReader { * Constructs a TeeReader that proxies the given {@link Reader} and copies all read characters to the given * {@link Writer}. The given writer will not be closed when this reader gets closed. * - * @param input reader to be proxied - * @param branch writer that will receive a copy of all characters read + * @param input reader to be proxied. + * @param branch writer that will receive a copy of all characters read. */ public TeeReader(final Reader input, final Writer branch) { this(input, branch, false); @@ -62,9 +62,9 @@ public TeeReader(final Reader input, final Writer branch) { * {@link Writer}. The given writer will be closed when this reader gets closed if the closeBranch parameter is * {@code true}. * - * @param input reader to be proxied - * @param branch writer that will receive a copy of all characters read - * @param closeBranch flag for closing also the writer when this reader is closed + * @param input reader to be proxied. + * @param branch writer that will receive a copy of all characters read. + * @param closeBranch flag for closing also the writer when this reader is closed. */ public TeeReader(final Reader input, final Writer branch, final boolean closeBranch) { super(input); @@ -76,7 +76,7 @@ public TeeReader(final Reader input, final Writer branch, final boolean closeBra * Closes the proxied reader and, if so configured, the associated writer. An exception thrown from the reader will * not prevent closing of the writer. * - * @throws IOException if either the reader or writer could not be closed + * @throws IOException if either the reader or writer could not be closed. */ @Override public void close() throws IOException { @@ -92,8 +92,8 @@ public void close() throws IOException { /** * Reads a single character from the proxied reader and writes it to the associated writer. * - * @return next character from the reader, or -1 if the reader has ended - * @throws IOException if the reader could not be read (or written) + * @return next character from the reader, or -1 if the reader has ended. + * @throws IOException if the reader could not be read (or written). */ @Override public int read() throws IOException { @@ -107,9 +107,9 @@ public int read() throws IOException { /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * - * @param chr character buffer - * @return number of characters read, or -1 if the reader has ended - * @throws IOException if the reader could not be read (or written) + * @param chr character buffer. + * @return number of characters read, or -1 if the reader has ended. + * @throws IOException if the reader could not be read (or written). */ @Override public int read(final char[] chr) throws IOException { @@ -123,11 +123,11 @@ public int read(final char[] chr) throws IOException { /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * - * @param chr character buffer - * @param st start offset within the buffer - * @param end maximum number of characters to read - * @return number of characters read, or -1 if the reader has ended - * @throws IOException if the reader could not be read (or written) + * @param chr character buffer. + * @param st start offset within the buffer. + * @param end maximum number of characters to read. + * @return number of characters read, or -1 if the reader has ended. + * @throws IOException if the reader could not be read (or written). */ @Override public int read(final char[] chr, final int st, final int end) throws IOException { @@ -141,9 +141,9 @@ public int read(final char[] chr, final int st, final int end) throws IOExceptio /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * - * @param target character buffer - * @return number of characters read, or -1 if the reader has ended - * @throws IOException if the reader could not be read (or written) + * @param target character buffer. + * @return number of characters read, or -1 if the reader has ended. + * @throws IOException if the reader could not be read (or written). */ @Override public int read(final CharBuffer target) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java index b081db3c6e5..9b670bdae10 100644 --- a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java @@ -128,7 +128,7 @@ public ThrottledInputStream get() throws IOException { * To test idle timeouts for example, use 1 byte per minute, 1 byte per 30 seconds, and so on. *

    * - * @param value the maximum bytes + * @param value the maximum bytes. * @param chronoUnit a duration scale goal. * @return {@code this} instance. * @throws IllegalArgumentException Thrown if maxBytesPerSecond <= 0. @@ -151,7 +151,7 @@ public Builder setMaxBytes(final long value, final ChronoUnit chronoUnit) { * To test idle timeouts for example, use 1 byte per minute, 1 byte per 30 seconds, and so on. *

    * - * @param value the maximum bytes + * @param value the maximum bytes. * @param duration a duration goal. * @return {@code this} instance. * @throws IllegalArgumentException Thrown if maxBytesPerSecond <= 0. diff --git a/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java b/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java index ac6e003ab1f..eb6cf216251 100644 --- a/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java @@ -110,7 +110,7 @@ public static Builder builder() { * Constructs a {@link UncheckedFilterInputStream}. * * @param builder A builder providing the underlying input stream. - * @throws IOException + * @throws IOException if an I/O error occurs. */ @SuppressWarnings("resource") // caller closes private UncheckedFilterInputStream(final Builder builder) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java index 3d0400fca71..bfd0a0f632c 100644 --- a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java @@ -43,8 +43,8 @@ public class UnixLineEndingInputStream extends InputStream { /** * Constructs an input stream that filters another stream * - * @param inputStream The input stream to wrap - * @param ensureLineFeedAtEndOfFile true to ensure that the file ends with LF + * @param inputStream The input stream to wrap. + * @param ensureLineFeedAtEndOfFile true to ensure that the file ends with LF. */ public UnixLineEndingInputStream(final InputStream inputStream, final boolean ensureLineFeedAtEndOfFile) { this.in = inputStream; @@ -112,7 +112,7 @@ public synchronized int read() throws IOException { /** * Reads the next item from the target, updating internal flags in the process - * @return the next int read from the target stream + * @return the next int read from the target stream. * @throws IOException If an I/O error occurs. */ private int readWithUpdate() throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java b/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java index 63874faabb7..fea13e7c4cc 100644 --- a/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java +++ b/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java @@ -31,7 +31,7 @@ final class UnsupportedOperationExceptions { /** * Constructs a new instance of UnsupportedOperationException for a {@code mark} method. * - * @return a new instance of UnsupportedOperationException + * @return a new instance of UnsupportedOperationException. */ static UnsupportedOperationException mark() { // Use the same message as in java.io.InputStream.reset() in OpenJDK 8.0.275-1. @@ -41,8 +41,8 @@ static UnsupportedOperationException mark() { /** * Constructs a new instance of UnsupportedOperationException for the given unsupported a {@code method} name. * - * @param method A method name - * @return a new instance of UnsupportedOperationException + * @param method A method name. + * @return a new instance of UnsupportedOperationException. */ static UnsupportedOperationException method(final String method) { return new UnsupportedOperationException(method + " not supported"); @@ -51,7 +51,7 @@ static UnsupportedOperationException method(final String method) { /** * Constructs a new instance of UnsupportedOperationException for a {@code reset} method. * - * @return a new instance of UnsupportedOperationException + * @return a new instance of UnsupportedOperationException. */ static UnsupportedOperationException reset() { // Use the same message as in java.io.InputStream.reset() in OpenJDK 8.0.275-1. diff --git a/src/main/java/org/apache/commons/io/input/UnsynchronizedBufferedReader.java b/src/main/java/org/apache/commons/io/input/UnsynchronizedBufferedReader.java index bde55873f24..b5484116c32 100644 --- a/src/main/java/org/apache/commons/io/input/UnsynchronizedBufferedReader.java +++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedBufferedReader.java @@ -212,8 +212,8 @@ public boolean markSupported() { /** * Returns the next character in the current reader without consuming it. So the next call to {@link #read()} will still return this value. * - * @return the next character - * @throws IOException If an I/O error occurs + * @return the next character. + * @throws IOException If an I/O error occurs. */ public int peek() throws IOException { mark(1); @@ -227,8 +227,8 @@ public int peek() throws IOException { * still return the next value. * * @param buf the buffer to fill for the look ahead. - * @return the buffer itself - * @throws IOException If an I/O error occurs + * @return the buffer itself. + * @throws IOException If an I/O error occurs. */ public int peek(final char[] buf) throws IOException { final int n = buf.length; 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 a56dec7206c..95f0805e21b 100644 --- a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java @@ -213,7 +213,7 @@ private UnsynchronizedByteArrayInputStream(final Builder builder) throws IOExcep /** * Constructs a new byte array input stream. * - * @param data the buffer + * @param data the buffer. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -224,9 +224,9 @@ public UnsynchronizedByteArrayInputStream(final byte[] data) { /** * Constructs a new byte array input stream. * - * @param data the buffer - * @param offset the offset into the buffer - * @throws IllegalArgumentException if the offset is less than zero + * @param data the buffer. + * @param offset the offset into the buffer. + * @throws IllegalArgumentException if the offset is less than zero. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated @@ -237,10 +237,10 @@ public UnsynchronizedByteArrayInputStream(final byte[] data, final int offset) { /** * Constructs a new byte array input stream. * - * @param data the buffer - * @param offset the offset into the buffer - * @param length the length of the buffer - * @throws IllegalArgumentException if the offset or length less than zero + * @param data the buffer. + * @param offset the offset into the buffer. + * @param length the length of the buffer. + * @throws IllegalArgumentException if the offset or length less than zero. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java index e438c940487..94b2de54c79 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java @@ -277,8 +277,8 @@ public static Builder builder() { /** * Gets the charset parameter value, {@code null} if not present, {@code null} if httpContentType is {@code null}. * - * @param httpContentType the HTTP content type - * @return The content type encoding (upcased) + * @param httpContentType the HTTP content type. + * @return The content type encoding (upcased). */ static String getContentTypeEncoding(final String httpContentType) { String encoding = null; @@ -297,8 +297,8 @@ static String getContentTypeEncoding(final String httpContentType) { /** * Gets the MIME type or {@code null} if httpContentType is {@code null}. * - * @param httpContentType the HTTP content type - * @return The mime content type + * @param httpContentType the HTTP content type. + * @return The mime content type. */ static String getContentTypeMime(final String httpContentType) { String mime = null; @@ -314,8 +314,8 @@ static String getContentTypeMime(final String httpContentType) { * Gets the encoding declared in the , {@code null} if none. * * @param inputStream InputStream to create the reader from. - * @param guessedEnc guessed encoding - * @return the encoding declared in the + * @param guessedEnc guessed encoding. + * @return the encoding declared in the . * @throws IOException thrown if there is a problem reading the stream. */ private static String getXmlProlog(final InputStream inputStream, final String guessedEnc) throws IOException { @@ -360,8 +360,8 @@ private static String getXmlProlog(final InputStream inputStream, final String g /** * Tests if the MIME type belongs to the APPLICATION XML family. * - * @param mime The mime type - * @return true if the mime type belongs to the APPLICATION XML family, otherwise false + * @param mime The mime type. + * @return true if the mime type belongs to the APPLICATION XML family, otherwise false. */ static boolean isAppXml(final String mime) { return mime != null && (mime.equals("application/xml") || mime.equals("application/xml-dtd") || mime.equals("application/xml-external-parsed-entity") @@ -371,8 +371,8 @@ static boolean isAppXml(final String mime) { /** * Tests if the MIME type belongs to the TEXT XML family. * - * @param mime The mime type - * @return true if the mime type belongs to the TEXT XML family, otherwise false + * @param mime The mime type. + * @return true if the mime type belongs to the TEXT XML family, otherwise false. */ static boolean isTextXml(final String mime) { return mime != null && (mime.equals("text/xml") || mime.equals("text/xml-external-parsed-entity") || mime.startsWith("text/") && mime.endsWith("+xml")); @@ -484,7 +484,7 @@ public XmlStreamReader(final InputStream inputStream, final boolean lenient) thr * * @param inputStream InputStream to create a Reader from. * @param lenient indicates if the charset encoding detection should be relaxed. - * @param defaultEncoding The default encoding + * @param defaultEncoding The default encoding. * @throws NullPointerException if the input stream is {@code null}. * @throws IOException thrown if there is a problem reading the stream. * @throws XmlStreamReaderException thrown if the charset encoding could not be determined according to the specification. @@ -588,7 +588,7 @@ public XmlStreamReader(final InputStream inputStream, final String httpContentTy * @param inputStream InputStream to create the reader from. * @param httpContentType content-type header to use for the resolution of the charset encoding. * @param lenient indicates if the charset encoding detection should be relaxed. - * @param defaultEncoding The default encoding + * @param defaultEncoding The default encoding. * @throws NullPointerException if the input stream is {@code null}. * @throws IOException thrown if there is a problem reading the file. * @throws XmlStreamReaderException thrown if the charset encoding could not be determined according to the specification. @@ -661,7 +661,7 @@ public XmlStreamReader(final URL url) throws IOException { *

    * * @param urlConnection URLConnection to create a Reader from. - * @param defaultEncoding The default encoding + * @param defaultEncoding The default encoding. * @throws NullPointerException if the input is {@code null}. * @throws IOException thrown if there is a problem reading the stream of the URLConnection. */ @@ -695,12 +695,12 @@ public XmlStreamReader(final URLConnection urlConnection, final String defaultEn /** * Calculates the HTTP encoding. - * @param bomEnc BOM encoding - * @param xmlGuessEnc XML Guess encoding - * @param xmlEnc XML encoding + * @param bomEnc BOM encoding. + * @param xmlGuessEnc XML Guess encoding. + * @param xmlEnc XML encoding. * @param lenient indicates if the charset encoding detection should be relaxed. - * @param httpContentType The HTTP content type - * @return the HTTP encoding + * @param httpContentType The HTTP content type. + * @return the HTTP encoding. * @throws IOException thrown if there is a problem reading the stream. */ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final boolean lenient, final String httpContentType) @@ -773,10 +773,10 @@ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, fina /** * Calculate the raw encoding. * - * @param bomEnc BOM encoding - * @param xmlGuessEnc XML Guess encoding - * @param xmlEnc XML encoding - * @return the raw encoding + * @param bomEnc BOM encoding. + * @param xmlGuessEnc XML Guess encoding. + * @param xmlEnc XML encoding. + * @return the raw encoding. * @throws IOException thrown if there is a problem reading the stream. */ String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc) throws IOException { @@ -850,8 +850,8 @@ public void close() throws IOException { * Does lenient detection. * * @param httpContentType content-type header to use for the resolution of the charset encoding. - * @param ex The thrown exception - * @return the encoding + * @param ex The thrown exception. + * @return the encoding. * @throws IOException thrown if there is a problem reading the stream. */ private String doLenientDetection(String httpContentType, XmlStreamReaderException ex) throws IOException { @@ -898,10 +898,10 @@ public String getEncoding() { /** * Process the raw stream. * - * @param bomInput BOMInputStream to detect byte order marks - * @param piInput BOMInputStream to guess XML encoding + * @param bomInput BOMInputStream to detect byte order marks. + * @param piInput BOMInputStream to guess XML encoding. * @param lenient indicates if the charset encoding detection should be relaxed. - * @return the encoding to be used + * @return the encoding to be used. * @throws IOException thrown if there is a problem reading the stream. */ private String processHttpStream(final BOMInputStream bomInput, final BOMInputStream piInput, final boolean lenient) throws IOException { @@ -921,11 +921,11 @@ private String processHttpStream(final BOMInputStream bomInput, final BOMInputSt /** * Processes an HTTP stream. * - * @param bomInput BOMInputStream to detect byte order marks - * @param piInput BOMInputStream to guess XML encoding + * @param bomInput BOMInputStream to detect byte order marks. + * @param piInput BOMInputStream to guess XML encoding. * @param lenient indicates if the charset encoding detection should be relaxed. - * @param httpContentType The HTTP content type - * @return the encoding to be used + * @param httpContentType The HTTP content type. + * @return the encoding to be used. * @throws IOException thrown if there is a problem reading the stream. */ private String processHttpStream(final BOMInputStream bomInput, final BOMInputStream piInput, final boolean lenient, final String httpContentType) @@ -946,10 +946,10 @@ private String processHttpStream(final BOMInputStream bomInput, final BOMInputSt /** * Reads the underlying reader's {@code read(char[], int, int)} method. * - * @param buf the buffer to read the characters into - * @param offset The start offset - * @param len The number of bytes to read - * @return the number of characters read or -1 if the end of stream + * @param buf the buffer to read the characters into. + * @param offset The start offset. + * @param len The number of bytes to read. + * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. */ @Override diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java index b92163478d0..cea865ae066 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java @@ -104,8 +104,8 @@ protected void fillBuffer() throws IOException { /** * Fills the buffer from the input stream until the given number of bytes have been added to the buffer. * - * @param count number of byte to fill into the buffer - * @return true if the buffer has bytes + * @param count number of byte to fill into the buffer. + * @return true if the buffer has bytes. * @throws IOException in case of an error while reading from the input stream. */ protected boolean haveBytes(final int count) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java index 43c8e71bd4a..64780b7c709 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java @@ -46,7 +46,7 @@ public CircularByteBuffer() { /** * Constructs a new instance with the given buffer size. * - * @param size the size of buffer to create + * @param size the size of buffer to create. */ public CircularByteBuffer(final int size) { buffer = IOUtils.byteArray(size); @@ -79,9 +79,9 @@ public void add(final byte value) { * for the bytes at offsets {@code offset+0}, {@code offset+1}, ..., * {@code offset+length-1} of byte array {@code targetBuffer}. * - * @param targetBuffer the buffer to copy - * @param offset start offset - * @param length length to copy + * @param targetBuffer the buffer to copy. + * @param offset start offset. + * @param length length to copy. * @throws IllegalStateException The buffer doesn't have sufficient space. Use * {@link #getSpace()} to prevent this exception. * @throws IllegalArgumentException Either of {@code offset}, or {@code length} is negative. @@ -119,7 +119,7 @@ public void clear() { /** * Gets the number of bytes, that are currently present in the buffer. * - * @return the number of bytes + * @return the number of bytes. */ public int getCurrentNumberOfBytes() { return currentNumberOfBytes; @@ -128,7 +128,7 @@ public int getCurrentNumberOfBytes() { /** * Gets the number of bytes, that can currently be added to the buffer. * - * @return the number of bytes that can be added + * @return the number of bytes that can be added. */ public int getSpace() { return buffer.length - currentNumberOfBytes; @@ -158,7 +158,7 @@ public boolean hasSpace() { /** * Tests whether there is currently room for the given number of bytes in the buffer. * - * @param count the byte count + * @param count the byte count. * @return true whether there is currently room for the given number of bytes in the buffer. * @see #hasSpace() * @see #getSpace() @@ -173,9 +173,9 @@ public boolean hasSpace(final int count) { * removed from the buffer. If the result is true, then the following invocations * of {@link #read()} are guaranteed to return exactly those bytes. * - * @param sourceBuffer the buffer to compare against - * @param offset start offset - * @param length length to compare + * @param sourceBuffer the buffer to compare against. + * @param offset start offset. + * @param length length to compare. * @return True, if the next invocations of {@link #read()} will return the * bytes at offsets {@code sourceBuffer}+0, {@code offset}+1, ..., * {@code offset}+{@code length}-1 of byte array {@code sourceBuffer}. diff --git a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java index ec96054fc43..8bb0f7c7158 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java @@ -53,8 +53,8 @@ public PeekableInputStream(final InputStream inputStream, final int bufferSize) * Returns whether the next bytes in the buffer are as given by {@code sourceBuffer}. This is equivalent to * {@link #peek(byte[], int, int)} with {@code offset} == 0, and {@code length} == {@code sourceBuffer.length} * - * @param sourceBuffer the buffer to compare against - * @return true if the next bytes are as given + * @param sourceBuffer the buffer to compare against. + * @return true if the next bytes are as given. * @throws IOException Refilling the buffer failed. */ public boolean peek(final byte[] sourceBuffer) throws IOException { @@ -66,11 +66,11 @@ public boolean peek(final byte[] sourceBuffer) throws IOException { * Returns whether the next bytes in the buffer are as given by {@code sourceBuffer}, {code offset}, and * {@code length}. * - * @param sourceBuffer the buffer to compare against - * @param offset the start offset - * @param length the length to compare - * @return true if the next bytes in the buffer are as given - * @throws IOException if there is a problem calling fillBuffer() + * @param sourceBuffer the buffer to compare against. + * @param offset the start offset. + * @param length the length to compare. + * @return true if the next bytes in the buffer are as given. + * @throws IOException if there is a problem calling fillBuffer(). */ public boolean peek(final byte[] sourceBuffer, final int offset, final int length) throws IOException { Objects.requireNonNull(sourceBuffer, "sourceBuffer"); diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java index ce64c8d4ed4..b7bf2a0cdb4 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java @@ -31,56 +31,56 @@ public interface FileAlterationListener { /** * Directory changed Event. * - * @param directory The directory changed + * @param directory The directory changed. */ void onDirectoryChange(File directory); /** * Directory created Event. * - * @param directory The directory created + * @param directory The directory created. */ void onDirectoryCreate(File directory); /** * Directory deleted Event. * - * @param directory The directory deleted + * @param directory The directory deleted. */ void onDirectoryDelete(File directory); /** * File changed Event. * - * @param file The file changed + * @param file The file changed. */ void onFileChange(File file); /** * File created Event. * - * @param file The file created + * @param file The file created. */ void onFileCreate(File file); /** * File deleted Event. * - * @param file The file deleted + * @param file The file deleted. */ void onFileDelete(File file); /** * File system observer started checking event. * - * @param observer The file system observer + * @param observer The file system observer. */ void onStart(FileAlterationObserver observer); /** * File system observer finished checking event. * - * @param observer The file system observer + * @param observer The file system observer. */ void onStop(FileAlterationObserver observer); } diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java index 0b54bbd6723..c676470fa31 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java @@ -36,7 +36,7 @@ public FileAlterationListenerAdaptor() { /** * Directory changed Event. * - * @param directory The directory changed (ignored) + * @param directory The directory changed (ignored). */ @Override public void onDirectoryChange(final File directory) { @@ -46,7 +46,7 @@ public void onDirectoryChange(final File directory) { /** * Directory created Event. * - * @param directory The directory created (ignored) + * @param directory The directory created (ignored). */ @Override public void onDirectoryCreate(final File directory) { @@ -56,7 +56,7 @@ public void onDirectoryCreate(final File directory) { /** * Directory deleted Event. * - * @param directory The directory deleted (ignored) + * @param directory The directory deleted (ignored). */ @Override public void onDirectoryDelete(final File directory) { @@ -66,7 +66,7 @@ public void onDirectoryDelete(final File directory) { /** * File changed Event. * - * @param file The file changed (ignored) + * @param file The file changed (ignored). */ @Override public void onFileChange(final File file) { @@ -76,7 +76,7 @@ public void onFileChange(final File file) { /** * File created Event. * - * @param file The file created (ignored) + * @param file The file created (ignored). */ @Override public void onFileCreate(final File file) { @@ -86,7 +86,7 @@ public void onFileCreate(final File file) { /** * File deleted Event. * - * @param file The file deleted (ignored) + * @param file The file deleted (ignored). */ @Override public void onFileDelete(final File file) { @@ -96,7 +96,7 @@ public void onFileDelete(final File file) { /** * File system observer started checking event. * - * @param observer The file system observer (ignored) + * @param observer The file system observer (ignored). */ @Override public void onStart(final FileAlterationObserver observer) { @@ -106,7 +106,7 @@ public void onStart(final FileAlterationObserver observer) { /** * File system observer finished checking event. * - * @param observer The file system observer (ignored) + * @param observer The file system observer (ignored). */ @Override public void onStop(final FileAlterationObserver observer) { diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java index 394e7aca661..77f7fa56b02 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java @@ -98,7 +98,7 @@ public FileAlterationMonitor(final long interval, final FileAlterationObserver.. /** * Adds a file system observer to this monitor. * - * @param observer The file system observer to add + * @param observer The file system observer to add. */ public void addObserver(final FileAlterationObserver observer) { if (observer != null) { @@ -109,7 +109,7 @@ public void addObserver(final FileAlterationObserver observer) { /** * Returns the interval. * - * @return the interval + * @return the interval. */ public long getInterval() { return intervalMillis; @@ -128,7 +128,7 @@ public Iterable getObservers() { /** * Removes a file system observer from this monitor. * - * @param observer The file system observer to remove + * @param observer The file system observer to remove. */ public void removeObserver(final FileAlterationObserver observer) { if (observer != null) { @@ -157,7 +157,7 @@ public void run() { /** * Sets the thread factory. * - * @param threadFactory the thread factory + * @param threadFactory the thread factory. */ public synchronized void setThreadFactory(final ThreadFactory threadFactory) { this.threadFactory = threadFactory; @@ -166,7 +166,7 @@ public synchronized void setThreadFactory(final ThreadFactory threadFactory) { /** * Starts monitoring. * - * @throws Exception if an error occurs initializing the observer + * @throws Exception if an error occurs initializing the observer. */ public synchronized void start() throws Exception { if (running) { @@ -187,7 +187,7 @@ public synchronized void start() throws Exception { /** * Stops monitoring. * - * @throws Exception if an error occurs initializing the observer + * @throws Exception if an error occurs initializing the observer. */ public synchronized void stop() throws Exception { stop(intervalMillis); @@ -198,7 +198,7 @@ public synchronized void stop() throws Exception { * * @param stopInterval the amount of time in milliseconds to wait for the thread to finish. * A value of zero will wait until the thread is finished (see {@link Thread#join(long)}). - * @throws Exception if an error occurs initializing the observer + * @throws Exception if an error occurs initializing the observer. * @since 2.1 */ public synchronized void stop(final long stopInterval) throws Exception { diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java index 277d80cb71e..282f1652d95 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java @@ -501,7 +501,7 @@ public FileFilter getFileFilter() { /** * Returns the set of registered file system listeners. * - * @return The file system listeners + * @return The file system listeners. */ public Iterable getListeners() { return new ArrayList<>(listeners); @@ -533,7 +533,7 @@ private FileEntry[] listFileEntries(final File file, final FileEntry entry) { * Lists the contents of a directory. * * @param directory The directory to list. - * @return the directory contents or a zero length array if the empty or the file is not a directory + * @return the directory contents or a zero length array if the empty or the file is not a directory. */ private File[] listFiles(final File directory) { return directory.isDirectory() ? sort(directory.listFiles(fileFilter)) : FileUtils.EMPTY_FILE_ARRAY; diff --git a/src/main/java/org/apache/commons/io/monitor/FileEntry.java b/src/main/java/org/apache/commons/io/monitor/FileEntry.java index d1e07fb885c..e4487173798 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileEntry.java +++ b/src/main/java/org/apache/commons/io/monitor/FileEntry.java @@ -84,7 +84,7 @@ public class FileEntry implements Serializable { /** * Constructs a new monitor for a specified {@link File}. * - * @param file The file being monitored + * @param file The file being monitored. */ public FileEntry(final File file) { this(null, file); @@ -107,7 +107,7 @@ public FileEntry(final FileEntry parent, final File file) { * * @return This directory's files or an empty * array if the file is not a directory or the - * directory is empty + * directory is empty. */ public FileEntry[] getChildren() { return children != null ? children : EMPTY_FILE_ENTRY_ARRAY; @@ -116,7 +116,7 @@ public FileEntry[] getChildren() { /** * Gets the file being monitored. * - * @return the file being monitored + * @return the file being monitored. */ public File getFile() { return file; @@ -145,7 +145,7 @@ public FileTime getLastModifiedFileTime() { /** * Gets the length. * - * @return the length + * @return the length. */ public long getLength() { return length; @@ -154,7 +154,7 @@ public long getLength() { /** * Gets the level * - * @return the level + * @return the level. */ public int getLevel() { return parent == null ? 0 : parent.getLevel() + 1; @@ -163,7 +163,7 @@ public int getLevel() { /** * Gets the file name. * - * @return the file name + * @return the file name. */ public String getName() { return name; @@ -172,7 +172,7 @@ public String getName() { /** * Gets the parent entry. * - * @return the parent entry + * @return the parent entry. */ public FileEntry getParent() { return parent; @@ -181,7 +181,7 @@ public FileEntry getParent() { /** * Tests whether the file is a directory or not. * - * @return whether the file is a directory or not + * @return whether the file is a directory or not. */ public boolean isDirectory() { return directory; @@ -191,7 +191,7 @@ public boolean isDirectory() { * Tests whether the file existed the last time it * was checked. * - * @return whether the file existed + * @return whether the file existed. */ public boolean isExists() { return exists; @@ -204,8 +204,8 @@ public boolean isExists() { * a new instance of the appropriate type. *

    * - * @param file The child file - * @return a new child instance + * @param file The child file. + * @return a new child instance. */ public FileEntry newChildInstance(final File file) { return new FileEntry(this, file); @@ -224,8 +224,8 @@ public FileEntry newChildInstance(final File file) { * and {@code length} properties are compared for changes *

    * - * @param file the file instance to compare to - * @return {@code true} if the file has changed, otherwise {@code false} + * @param file the file instance to compare to. + * @return {@code true} if the file has changed, otherwise {@code false}. */ public boolean refresh(final File file) { // cache original values @@ -253,7 +253,7 @@ public boolean refresh(final File file) { /** * Sets the directory's files. * - * @param children This directory's files, may be null + * @param children This directory's files, may be null. */ public void setChildren(final FileEntry... children) { this.children = children; @@ -262,7 +262,7 @@ public void setChildren(final FileEntry... children) { /** * Sets whether the file is a directory or not. * - * @param directory whether the file is a directory or not + * @param directory whether the file is a directory or not. */ public void setDirectory(final boolean directory) { this.directory = directory; @@ -272,7 +272,7 @@ public void setDirectory(final boolean directory) { * Sets whether the file existed the last time it * was checked. * - * @param exists whether the file exists or not + * @param exists whether the file exists or not. */ public void setExists(final boolean exists) { this.exists = exists; @@ -305,7 +305,7 @@ void setLastModified(final SerializableFileTime lastModified) { /** * Sets the length. * - * @param length the length + * @param length the length. */ public void setLength(final long length) { this.length = length; @@ -314,7 +314,7 @@ public void setLength(final long length) { /** * Sets the file name. * - * @param name the file name + * @param name the file name. */ public void setName(final String name) { this.name = name; diff --git a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java index fe54f5a7960..78c20d15100 100644 --- a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java @@ -56,7 +56,7 @@ * ignored. *

    * - * @param The AbstractByteArrayOutputStream subclass + * @param The AbstractByteArrayOutputStream subclass. * @since 2.7 */ public abstract class AbstractByteArrayOutputStream> extends OutputStream { @@ -110,7 +110,7 @@ public AbstractByteArrayOutputStream() { /** * Returns this instance typed to {@code T}. * - * @return {@code this} instance + * @return {@code this} instance. */ @SuppressWarnings("unchecked") protected T asThis() { @@ -349,7 +349,7 @@ public T write(final CharSequence data, final Charset charset) { * this stream. * * @param in the input stream to read from. - * @return total number of bytes read from the input stream (and written to this stream) + * @return total number of bytes read from the input stream (and written to this stream). * @throws IOException if an I/O error occurs while reading the input stream. * @since 1.4 */ diff --git a/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java b/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java index e8320d99d64..ed7727969b9 100644 --- a/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java @@ -39,7 +39,7 @@ public class AppendableOutputStream extends OutputStream /** * Constructs a new instance with the specified appendable. * - * @param appendable the appendable to write to + * @param appendable the appendable to write to. */ public AppendableOutputStream(final T appendable) { this.appendable = appendable; @@ -48,7 +48,7 @@ public AppendableOutputStream(final T appendable) { /** * Gets the target appendable. * - * @return the target appendable + * @return the target appendable. */ public T getAppendable() { return appendable; @@ -57,7 +57,7 @@ public T getAppendable() { /** * Writes a character to the underlying appendable. * - * @param b the character to write + * @param b the character to write. * @throws IOException If an I/O error occurs. */ @Override diff --git a/src/main/java/org/apache/commons/io/output/AppendableWriter.java b/src/main/java/org/apache/commons/io/output/AppendableWriter.java index b1ace0b908c..4ac262ccea0 100644 --- a/src/main/java/org/apache/commons/io/output/AppendableWriter.java +++ b/src/main/java/org/apache/commons/io/output/AppendableWriter.java @@ -75,10 +75,10 @@ public Writer append(final CharSequence csq) throws IOException { /** * Appends a subsequence of the specified character sequence to the underlying appendable. * - * @param csq the character sequence from which a subsequence will be appended - * @param start the index of the first character in the subsequence - * @param end the index of the character following the last character in the subsequence - * @return this writer + * @param csq the character sequence from which a subsequence will be appended. + * @param start the index of the first character in the subsequence. + * @param end the index of the character following the last character in the subsequence. + * @return this writer. * @throws IndexOutOfBoundsException If {@code start} or {@code end} are negative, {@code start} is greater than * {@code end}, or {@code end} is greater than {@code csq.length()}. * @throws IOException If an I/O error occurs. diff --git a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java index 48fb793669b..fa643b66fc0 100644 --- a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java @@ -95,8 +95,8 @@ public ByteArrayOutputStream() { * Constructs a new byte array output stream, with a buffer capacity of * the specified size, in bytes. * - * @param size the initial size - * @throws IllegalArgumentException if size is negative + * @param size the initial size. + * @throws IllegalArgumentException if size is negative. */ public ByteArrayOutputStream(final int size) { if (size < 0) { 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 2588264e172..4cef36c3b4d 100644 --- a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java @@ -143,7 +143,7 @@ public ChunkedOutputStream(final OutputStream stream) { /** * Constructs 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 <= 0. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. diff --git a/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java b/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java index cefa71ad41f..876f3e5b7dc 100644 --- a/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java @@ -34,7 +34,7 @@ public class CloseShieldOutputStream extends ProxyOutputStream { * Constructs a proxy that shields the given output stream from being closed. * * @param outputStream the output stream to wrap. - * @return the created proxy + * @return the created proxy. * @since 2.9.0 */ public static CloseShieldOutputStream wrap(final OutputStream outputStream) { diff --git a/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java b/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java index c7216ce6f90..664df91028d 100644 --- a/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java @@ -58,7 +58,7 @@ public ClosedOutputStream() { /** * Throws an {@link IOException} to indicate that the stream is closed. * - * @throws IOException always thrown + * @throws IOException always thrown. */ @Override public void flush() throws IOException { diff --git a/src/main/java/org/apache/commons/io/output/ClosedWriter.java b/src/main/java/org/apache/commons/io/output/ClosedWriter.java index c4e1d93b93c..550b9daf523 100644 --- a/src/main/java/org/apache/commons/io/output/ClosedWriter.java +++ b/src/main/java/org/apache/commons/io/output/ClosedWriter.java @@ -61,7 +61,7 @@ public void close() throws IOException { /** * Throws an {@link IOException} to indicate that the stream is closed. * - * @throws IOException always thrown + * @throws IOException always thrown. */ @Override public void flush() throws IOException { diff --git a/src/main/java/org/apache/commons/io/output/NullWriter.java b/src/main/java/org/apache/commons/io/output/NullWriter.java index 635ffb044a6..e43b6427c75 100644 --- a/src/main/java/org/apache/commons/io/output/NullWriter.java +++ b/src/main/java/org/apache/commons/io/output/NullWriter.java @@ -69,7 +69,7 @@ public Writer append(final char c) { * Does nothing, like writing to {@code /dev/null}. * * @param csq The character sequence to write. - * @return this writer + * @return this writer. * @since 2.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/output/ProxyWriter.java b/src/main/java/org/apache/commons/io/output/ProxyWriter.java index ac88f4c6943..cf82a1b2e61 100644 --- a/src/main/java/org/apache/commons/io/output/ProxyWriter.java +++ b/src/main/java/org/apache/commons/io/output/ProxyWriter.java @@ -51,8 +51,8 @@ public ProxyWriter(final Writer delegate) { * The default implementation does nothing. *

    * - * @param n number of chars written - * @throws IOException if the post-processing fails + * @param n number of chars written. + * @throws IOException if the post-processing fails. * @since 2.0 */ @SuppressWarnings("unused") // Possibly thrown from subclasses. diff --git a/src/main/java/org/apache/commons/io/output/TeeOutputStream.java b/src/main/java/org/apache/commons/io/output/TeeOutputStream.java index 72a1eb9e4c6..59f70ffaafd 100644 --- a/src/main/java/org/apache/commons/io/output/TeeOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/TeeOutputStream.java @@ -35,8 +35,8 @@ public class TeeOutputStream extends ProxyOutputStream { /** * Constructs a TeeOutputStream. * - * @param out the main OutputStream - * @param branch the second OutputStream + * @param out the main OutputStream. + * @param branch the second OutputStream. */ public TeeOutputStream(final OutputStream out, final OutputStream branch) { super(out); diff --git a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java index 9292aaf70e8..8c517d1ac0d 100644 --- a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java @@ -198,7 +198,7 @@ public static Builder builder() { /** * Checks if the JDK in use properly supports the given charset. * - * @param charset the charset to check the support for + * @param charset the charset to check the support for. */ private static void checkIbmJdkWithBrokenUTF16(final Charset charset) { if (!StandardCharsets.UTF_16.name().equals(charset.name())) { diff --git a/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java b/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java index 47103a4293d..0682c66b802 100644 --- a/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java +++ b/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java @@ -27,8 +27,8 @@ public interface ClassNameMatcher { /** * Returns {@code true} if the supplied class name matches this object's condition. * - * @param className fully qualified class name - * @return {@code true} if the class name matches this object's condition + * @param className fully qualified class name. + * @return {@code true} if the class name matches this object's condition. */ boolean matches(String className); } \ No newline at end of file diff --git a/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java b/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java index 14f725f5975..402d1adf573 100644 --- a/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java +++ b/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java @@ -36,7 +36,7 @@ final class FullClassNameMatcher implements ClassNameMatcher { /** * Constructs an object based on the specified class names. * - * @param classes a list of class names + * @param classes a list of class names. */ FullClassNameMatcher(final String... classes) { classesSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(classes))); diff --git a/src/main/java/org/apache/commons/io/serialization/ObjectStreamClassPredicate.java b/src/main/java/org/apache/commons/io/serialization/ObjectStreamClassPredicate.java index 5a3375cd72e..ffdf1a73df9 100644 --- a/src/main/java/org/apache/commons/io/serialization/ObjectStreamClassPredicate.java +++ b/src/main/java/org/apache/commons/io/serialization/ObjectStreamClassPredicate.java @@ -55,8 +55,8 @@ public ObjectStreamClassPredicate() { * The reject list takes precedence over the accept list. *

    * - * @param classes Classes to accept - * @return this object + * @param classes Classes to accept. + * @return this object. */ public ObjectStreamClassPredicate accept(final Class... classes) { Stream.of(classes).map(c -> new FullClassNameMatcher(c.getName())).forEach(acceptMatchers::add); @@ -112,7 +112,7 @@ public ObjectStreamClassPredicate accept(final String... patterns) { * The reject list takes precedence over the accept list. *

    * - * @param classes Classes to reject + * @param classes Classes to reject. * @return {@code this} instance. */ public ObjectStreamClassPredicate reject(final Class... classes) { @@ -126,7 +126,7 @@ public ObjectStreamClassPredicate reject(final Class... classes) { * The reject list takes precedence over the accept list. *

    * - * @param m the matcher to use + * @param m the matcher to use. * @return {@code this} instance. */ public ObjectStreamClassPredicate reject(final ClassNameMatcher m) { @@ -140,7 +140,7 @@ public ObjectStreamClassPredicate reject(final ClassNameMatcher m) { * The reject list takes precedence over the accept list. *

    * - * @param pattern standard Java regexp + * @param pattern standard Java regexp. * @return {@code this} instance. */ public ObjectStreamClassPredicate reject(final Pattern pattern) { diff --git a/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java b/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java index 7d204dfa4f7..adb76fdc511 100644 --- a/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java +++ b/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java @@ -34,8 +34,8 @@ final class RegexpClassNameMatcher implements ClassNameMatcher { /** * Constructs an object based on the specified pattern. * - * @param pattern a pattern for evaluating acceptable class names - * @throws NullPointerException if {@code pattern} is null + * @param pattern a pattern for evaluating acceptable class names. + * @throws NullPointerException if {@code pattern} is null. */ RegexpClassNameMatcher(final Pattern pattern) { this.pattern = Objects.requireNonNull(pattern, "pattern"); @@ -44,7 +44,7 @@ final class RegexpClassNameMatcher implements ClassNameMatcher { /** * Constructs an object based on the specified regular expression. * - * @param regex a regular expression for evaluating acceptable class names + * @param regex a regular expression for evaluating acceptable class names. */ RegexpClassNameMatcher(final String regex) { this(Pattern.compile(regex)); diff --git a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java index d2e51425b24..8e945578efc 100644 --- a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java +++ b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java @@ -119,8 +119,8 @@ public Builder() { /** * Accepts the specified classes for deserialization, unless they are otherwise rejected. * - * @param classes Classes to accept - * @return this object + * @param classes Classes to accept. + * @return this object. * @since 2.18.0 */ public Builder accept(final Class... classes) { @@ -204,7 +204,7 @@ public ObjectStreamClassPredicate getPredicate() { /** * Rejects the specified classes for deserialization, even if they are otherwise accepted. * - * @param classes Classes to reject + * @param classes Classes to reject. * @return {@code this} instance. * @since 2.18.0 */ @@ -216,7 +216,7 @@ public Builder reject(final Class... classes) { /** * Rejects class names where the supplied ClassNameMatcher matches for deserialization, even if they are otherwise accepted. * - * @param matcher the matcher to use + * @param matcher the matcher to use. * @return {@code this} instance. * @since 2.18.0 */ @@ -228,7 +228,7 @@ public Builder reject(final ClassNameMatcher matcher) { /** * Rejects class names that match the supplied pattern for deserialization, even if they are otherwise accepted. * - * @param pattern standard Java regexp + * @param pattern standard Java regexp. * @return {@code this} instance. * @since 2.18.0 */ @@ -285,8 +285,8 @@ private ValidatingObjectInputStream(final Builder builder) throws IOException { * Constructs an instance to deserialize the specified input stream. At least one accept method needs to be called to specify which classes can be * deserialized, as by default no classes are accepted. * - * @param input an input stream - * @throws IOException if an I/O error occurs while reading stream header + * @param input an input stream. + * @throws IOException if an I/O error occurs while reading stream header. * @deprecated Use {@link #builder()}. */ @Deprecated @@ -313,7 +313,7 @@ private ValidatingObjectInputStream(final InputStream input, final ObjectStreamC * The reject list takes precedence over the accept list. *

    * - * @param classes Classes to accept + * @param classes Classes to accept. * @return {@code this} instance. */ public ValidatingObjectInputStream accept(final Class... classes) { diff --git a/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java b/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java index f5d0773fd2f..70f97aa23cc 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java @@ -70,7 +70,7 @@ public void setUp() throws Exception { /** * Tests that {@code copyInputStreamToFile(InputStream, File)} closes the input stream. * - * @throws IOException + * @throws IOException Thrown on a test failure. * @see FileUtils#copyInputStreamToFile(InputStream, File) * @see FileUtils#copyToFile(InputStream, File) */ @@ -85,7 +85,7 @@ void testCopyInputStreamToFile() throws IOException { /** * Tests that {@code copyToFile(InputStream, File)} does not close the input stream. * - * @throws IOException + * @throws IOException Thrown on a test failure. * @see FileUtils#copyToFile(InputStream, File) * @see FileUtils#copyInputStreamToFile(InputStream, File) */ diff --git a/src/test/java/org/apache/commons/io/FileUtilsDirectoryContainsTest.java b/src/test/java/org/apache/commons/io/FileUtilsDirectoryContainsTest.java index b2574587719..4da1d567783 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsDirectoryContainsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsDirectoryContainsTest.java @@ -127,8 +127,9 @@ void testFileDoesNotExist() throws IOException { } /** - * Test to demonstrate a file which does not exist returns false - * @throws IOException If an I/O error occurs + * Test to demonstrate a file which does not exist returns false. + * + * @throws IOException If an I/O error occurs. */ @Test void testFileDoesNotExistBug() throws IOException { diff --git a/src/test/java/org/apache/commons/io/FileUtilsFileNewerTest.java b/src/test/java/org/apache/commons/io/FileUtilsFileNewerTest.java index 67ee8e2fd2c..6905cecdc33 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsFileNewerTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsFileNewerTest.java @@ -68,7 +68,7 @@ public void setUp() throws Exception { /** * Tests the {@code isFileNewer(File, *)} methods which a "normal" file. * - * @throws IOException + * @throws IOException Thrown on a test failure. * @see FileUtils#isFileNewer(File, long) * @see FileUtils#isFileNewer(File, Date) * @see FileUtils#isFileNewer(File, File) @@ -100,10 +100,10 @@ void testIsFileNewer() throws IOException { *

    * The test is successful if the three comparisons return the specified wanted result. * - * @param description describes the tested situation - * @param file the file of which the last modification date is compared - * @param fileTime the time reference measured in milliseconds since the epoch - * @param wantedResult the expected result + * @param description describes the tested situation. + * @param file the file of which the last modification date is compared. + * @param fileTime the time reference measured in milliseconds since the epoch. + * @param wantedResult the expected result. * @throws IOException if an I/O error occurs. */ protected void testIsFileNewer(final String description, final File file, final FileTime fileTime, final boolean wantedResult) throws IOException { diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index df90ab66e11..5684bf09470 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -1916,7 +1916,7 @@ void testToCharArray_Reader() throws Exception { * Note, this test utilizes on {@link IOUtils#toByteArray(InputStream)} and so relies on * {@link #testToByteArray_InputStream()} to ensure this method functions correctly. * - * @throws Exception on error + * @throws Exception on error. */ @Test void testToInputStream_CharSequence() throws Exception { @@ -1937,7 +1937,7 @@ void testToInputStream_CharSequence() throws Exception { * utilizes on {@link IOUtils#toByteArray(InputStream)} and so relies on * {@link #testToByteArray_InputStream()} to ensure this method functions correctly. * - * @throws Exception on error + * @throws Exception on error. */ @Test void testToInputStream_String() throws Exception { diff --git a/src/test/java/org/apache/commons/io/LineIteratorTest.java b/src/test/java/org/apache/commons/io/LineIteratorTest.java index 1ab177e8e1c..e4f5f88a970 100644 --- a/src/test/java/org/apache/commons/io/LineIteratorTest.java +++ b/src/test/java/org/apache/commons/io/LineIteratorTest.java @@ -63,9 +63,9 @@ private void assertLines(final List lines, final LineIterator iterator) /** * Creates a test file with a specified number of lines. * - * @param file target file - * @param lineCount number of lines to create - * @throws IOException If an I/O error occurs + * @param file target file. + * @param lineCount number of lines to create. + * @throws IOException If an I/O error occurs. */ private List createLinesFile(final File file, final int lineCount) throws IOException { final List lines = createStringLines(lineCount); @@ -76,10 +76,10 @@ private List createLinesFile(final File file, final int lineCount) throw /** * Creates a test file with a specified number of lines. * - * @param file target file - * @param encoding the encoding to use while writing the lines - * @param lineCount number of lines to create - * @throws IOException If an I/O error occurs + * @param file target file. + * @param encoding the encoding to use while writing the lines. + * @param lineCount number of lines to create. + * @throws IOException If an I/O error occurs. */ private List createLinesFile(final File file, final String encoding, final int lineCount) throws IOException { final List lines = createStringLines(lineCount); @@ -90,7 +90,7 @@ private List createLinesFile(final File file, final String encoding, fin /** * Creates String data lines. * - * @param lineCount number of lines to create + * @param lineCount number of lines to create. * @return a new lines list. */ private List createStringLines(final int lineCount) { @@ -104,8 +104,8 @@ private List createStringLines(final int lineCount) { /** * Utility method to create and test a file with a specified number of lines. * - * @param lineCount the lines to create in the test file - * @throws IOException If an I/O error occurs while creating the file + * @param lineCount the lines to create in the test file. + * @throws IOException If an I/O error occurs while creating the file. */ private void doTestFileWithSpecifiedLines(final int lineCount) throws IOException { final String encoding = UTF_8; diff --git a/src/test/java/org/apache/commons/io/file/TempDirectory.java b/src/test/java/org/apache/commons/io/file/TempDirectory.java index bf858514bec..991a73f6793 100644 --- a/src/test/java/org/apache/commons/io/file/TempDirectory.java +++ b/src/test/java/org/apache/commons/io/file/TempDirectory.java @@ -36,7 +36,7 @@ public class TempDirectory extends DeletablePath { * @param dir See {@link Files#createTempDirectory(String, FileAttribute...)}. * @param prefix See {@link Files#createTempDirectory(String, FileAttribute...)}. * @param attrs See {@link Files#createTempDirectory(String, FileAttribute...)}. - * @return a new instance for a new temporary directory + * @return a new instance for a new temporary directory. * @throws IOException See {@link Files#createTempDirectory(String, FileAttribute...)}. */ public static TempDirectory create(final Path dir, final String prefix, final FileAttribute... attrs) throws IOException { @@ -49,7 +49,7 @@ public static TempDirectory create(final Path dir, final String prefix, final Fi * * @param prefix See {@link Files#createTempDirectory(String, FileAttribute...)}. * @param attrs See {@link Files#createTempDirectory(String, FileAttribute...)}. - * @return a new instance for a new temporary directory + * @return a new instance for a new temporary directory. * @throws IOException See {@link Files#createTempDirectory(String, FileAttribute...)}. */ public static TempDirectory create(final String prefix, final FileAttribute... attrs) throws IOException { diff --git a/src/test/java/org/apache/commons/io/file/TempFile.java b/src/test/java/org/apache/commons/io/file/TempFile.java index 56e7b395a4f..7a177607da3 100644 --- a/src/test/java/org/apache/commons/io/file/TempFile.java +++ b/src/test/java/org/apache/commons/io/file/TempFile.java @@ -37,7 +37,7 @@ public class TempFile extends DeletablePath { * @param prefix See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. * @param suffix See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. * @param attrs See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. - * @return a new instance for a new temporary directory + * @return a new instance for a new temporary directory. * @throws IOException See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. */ public static TempFile create(final Path dir, final String prefix, final String suffix, final FileAttribute... attrs) throws IOException { @@ -51,7 +51,7 @@ public static TempFile create(final Path dir, final String prefix, final String * @param prefix See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. * @param suffix See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. * @param attrs See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. - * @return a new instance for a new temporary directory + * @return a new instance for a new temporary directory. * @throws IOException See {@link Files#createTempFile(Path, String, String, FileAttribute...)}. */ public static TempFile create(final String prefix, final String suffix, final FileAttribute... attrs) throws IOException { diff --git a/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java index 1734969bd6e..f112b5dad03 100644 --- a/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java @@ -152,7 +152,7 @@ void testRegexEdgeCases() { /** * Tests https://issues.apache.org/jira/browse/IO-733. * - * @throws IOException + * @throws IOException Thrown on a test failure. */ @SuppressWarnings("unchecked") @Test diff --git a/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java index 4c536df45db..cdd5ea9b252 100644 --- a/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java @@ -100,7 +100,7 @@ static void tearDown() { * Unit test teardown deletes all four of these files. *

    * - * @throws IOException If it fails to create the temporary files + * @throws IOException If it fails to create the temporary files. */ @BeforeAll static void testSetup() throws IOException { diff --git a/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java index f199be777b3..e32540afddf 100644 --- a/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java +++ b/src/test/java/org/apache/commons/io/function/IOBiFunctionTest.java @@ -45,7 +45,7 @@ private boolean not(final boolean value) throws IOException { /** * Tests {@link IOBiFunction#andThen(IOFunction)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAndThenIOFunction() throws IOException { @@ -59,7 +59,7 @@ void testAndThenIOFunction() throws IOException { /** * Tests {@link IOBiFunction#apply(Object, Object)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testApply() throws IOException { diff --git a/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java index 66520402df8..bb3524389c3 100644 --- a/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java +++ b/src/test/java/org/apache/commons/io/function/IOQuadFunctionTest.java @@ -33,7 +33,7 @@ class IOQuadFunctionTest { /** * Tests {@link IOQuadFunction#apply(Object, Object, Object, Object)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAccept() throws IOException { @@ -58,7 +58,7 @@ void testAccept() throws IOException { /** * Tests {@link IOTriFunction#andThen(IOFunction)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAndThenIOFunction() throws IOException { diff --git a/src/test/java/org/apache/commons/io/function/IORunnableTest.java b/src/test/java/org/apache/commons/io/function/IORunnableTest.java index 4fe035d92e8..134ad6027fc 100644 --- a/src/test/java/org/apache/commons/io/function/IORunnableTest.java +++ b/src/test/java/org/apache/commons/io/function/IORunnableTest.java @@ -39,7 +39,7 @@ class IORunnableTest { /** * Tests {@link IORunnable#run()}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAccept() throws IOException { diff --git a/src/test/java/org/apache/commons/io/function/IOTriFunctionTest.java b/src/test/java/org/apache/commons/io/function/IOTriFunctionTest.java index 0ed956a8556..4575d47e577 100644 --- a/src/test/java/org/apache/commons/io/function/IOTriFunctionTest.java +++ b/src/test/java/org/apache/commons/io/function/IOTriFunctionTest.java @@ -33,7 +33,7 @@ class IOTriFunctionTest { /** * Tests {@link IOTriFunction#apply(Object, Object, Object)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAccept() throws IOException { @@ -55,7 +55,7 @@ void testAccept() throws IOException { /** * Tests {@link IOTriFunction#andThen(IOFunction)}. * - * @throws IOException thrown on test failure + * @throws IOException thrown on test failure. */ @Test void testAndThenIOFunction() throws IOException { diff --git a/src/test/java/org/apache/commons/io/function/UncheckTest.java b/src/test/java/org/apache/commons/io/function/UncheckTest.java index 2622c6176da..01065739388 100644 --- a/src/test/java/org/apache/commons/io/function/UncheckTest.java +++ b/src/test/java/org/apache/commons/io/function/UncheckTest.java @@ -336,7 +336,7 @@ void testRun() { /** * Tests {@link Uncheck#run(IORunnable, Supplier))}. * - * @throws IOException + * @throws IOException Thrown on a test failure. */ @Test void testRunMessage() throws IOException { diff --git a/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java b/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java index d8e8a48e833..b70ad1ec12f 100644 --- a/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java @@ -150,12 +150,12 @@ private String getXML(final String bomType, final String xmlType, } /** - * @param bomType no-bom, UTF-16BE-bom, UTF-16LE-bom, UTF-8-bom - * @param xmlType xml, xml-prolog, xml-prolog-charset - * @param streamEnc encoding of the stream - * @param prologEnc encoding of the prolog - * @return XML stream - * @throws IOException If an I/O error occurs + * @param bomType no-bom, UTF-16BE-bom, UTF-16LE-bom, UTF-8-bom. + * @param xmlType xml, xml-prolog, xml-prolog-charset. + * @param streamEnc encoding of the stream. + * @param prologEnc encoding of the prolog. + * @return XML stream. + * @throws IOException If an I/O error occurs. */ protected InputStream getXmlInputStream(final String bomType, final String xmlType, final String streamEnc, final String prologEnc) throws IOException { diff --git a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java index 93737d3bcb4..b73c9991dc3 100644 --- a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java +++ b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java @@ -455,7 +455,7 @@ public XmlStreamReader(final InputStream inputStream, final String httpContentTy * the charset encoding. * @param lenient indicates if the charset encoding detection should be * relaxed. - * @param defaultEncoding the default encoding to use + * @param defaultEncoding the default encoding to use. * @throws IOException thrown if there is a problem reading the file. * @throws XmlStreamReaderException thrown if the charset encoding could not * be determined according to the specification. diff --git a/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java b/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java index 31d2bd7479f..d00feb3fdbb 100644 --- a/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java +++ b/src/test/java/org/apache/commons/io/monitor/AbstractMonitorTest.java @@ -53,7 +53,7 @@ public abstract class AbstractMonitorTest { /** * Check all the Collections are empty * - * @param label the label to use for this check + * @param label the label to use for this check. */ protected void checkCollectionsEmpty(final String label) { checkCollectionSizes("EMPTY-" + label, 0, 0, 0, 0, 0, 0); @@ -62,13 +62,13 @@ protected void checkCollectionsEmpty(final String label) { /** * Check all the Collections have the expected sizes. * - * @param label the label to use for this check - * @param dirCreate expected number of dirs created - * @param dirChange expected number of dirs changed - * @param dirDelete expected number of dirs deleted - * @param fileCreate expected number of files created - * @param fileChange expected number of files changed - * @param fileDelete expected number of files deleted + * @param label the label to use for this check. + * @param dirCreate expected number of dirs created. + * @param dirChange expected number of dirs changed. + * @param dirDelete expected number of dirs deleted. + * @param fileCreate expected number of files created. + * @param fileChange expected number of files changed. + * @param fileDelete expected number of files deleted. */ protected void checkCollectionSizes(String label, final int dirCreate, @@ -94,8 +94,8 @@ protected void checkCollectionSizes(String label, /** * Create a {@link FileAlterationObserver}. * - * @param file The directory to observe - * @param fileFilter The file filter to apply + * @param file The directory to observe. + * @param fileFilter The file filter to apply. */ protected void createObserver(final File file, final FileFilter fileFilter) { observer = FileAlterationObserver.builder().setFile(file).setFileFilter(fileFilter).getUnchecked(); @@ -127,8 +127,8 @@ public void setUp() { * Either creates a file if it doesn't exist or updates the last modified date/time * if it does. * - * @param file The file to touch - * @return The file + * @param file The file to touch. + * @return The file. * @throws IOException if an I/O error occurs. */ protected File touch(File file) throws IOException { diff --git a/src/test/java/org/apache/commons/io/monitor/CollectionFileListener.java b/src/test/java/org/apache/commons/io/monitor/CollectionFileListener.java index 309eb63b526..4e597d8e2f1 100644 --- a/src/test/java/org/apache/commons/io/monitor/CollectionFileListener.java +++ b/src/test/java/org/apache/commons/io/monitor/CollectionFileListener.java @@ -60,7 +60,7 @@ public void clear() { /** * Gets the set of changed directories. * - * @return Directories which have changed + * @return Directories which have changed. */ public Collection getChangedDirectories() { return changedDirectories; @@ -69,7 +69,7 @@ public Collection getChangedDirectories() { /** * Gets the set of changed files. * - * @return Files which have changed + * @return Files which have changed. */ public Collection getChangedFiles() { return changedFiles; @@ -78,7 +78,7 @@ public Collection getChangedFiles() { /** * Gets the set of created directories. * - * @return Directories which have been created + * @return Directories which have been created. */ public Collection getCreatedDirectories() { return createdDirectories; @@ -87,7 +87,7 @@ public Collection getCreatedDirectories() { /** * Gets the set of created files. * - * @return Files which have been created + * @return Files which have been created. */ public Collection getCreatedFiles() { return createdFiles; @@ -96,7 +96,7 @@ public Collection getCreatedFiles() { /** * Gets the set of deleted directories. * - * @return Directories which been deleted + * @return Directories which been deleted. */ public Collection getDeletedDirectories() { return deletedDirectories; @@ -105,7 +105,7 @@ public Collection getDeletedDirectories() { /** * Gets the set of deleted files. * - * @return Files which been deleted + * @return Files which been deleted. */ public Collection getDeletedFiles() { return deletedFiles; @@ -114,7 +114,7 @@ public Collection getDeletedFiles() { /** * Directory changed Event. * - * @param directory The directory changed + * @param directory The directory changed. */ @Override public void onDirectoryChange(final File directory) { @@ -124,7 +124,7 @@ public void onDirectoryChange(final File directory) { /** * Directory created Event. * - * @param directory The directory created + * @param directory The directory created. */ @Override public void onDirectoryCreate(final File directory) { @@ -134,7 +134,7 @@ public void onDirectoryCreate(final File directory) { /** * Directory deleted Event. * - * @param directory The directory deleted + * @param directory The directory deleted. */ @Override public void onDirectoryDelete(final File directory) { @@ -144,7 +144,7 @@ public void onDirectoryDelete(final File directory) { /** * File changed Event. * - * @param file The file changed + * @param file The file changed. */ @Override public void onFileChange(final File file) { @@ -154,7 +154,7 @@ public void onFileChange(final File file) { /** * File created Event. * - * @param file The file created + * @param file The file created. */ @Override public void onFileCreate(final File file) { @@ -164,7 +164,7 @@ public void onFileCreate(final File file) { /** * File deleted Event. * - * @param file The file deleted + * @param file The file deleted. */ @Override public void onFileDelete(final File file) { @@ -174,7 +174,7 @@ public void onFileDelete(final File file) { /** * File system observer started checking event. * - * @param observer The file system observer + * @param observer The file system observer. */ @Override public void onStart(final FileAlterationObserver observer) { @@ -186,7 +186,7 @@ public void onStart(final FileAlterationObserver observer) { /** * File system observer finished checking event. * - * @param observer The file system observer + * @param observer The file system observer. */ @Override public void onStop(final FileAlterationObserver observer) { diff --git a/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTest.java b/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTest.java index ce236dbb5b6..7882d6dbaf3 100644 --- a/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTest.java +++ b/src/test/java/org/apache/commons/io/monitor/FileAlterationMonitorTest.java @@ -128,8 +128,9 @@ void testDefaultConstructor() { } /** - * Test checkAndNotify() method - * @throws Exception + * Test checkAndNotify() method. + * + * @throws Exception Thrown on a test failure. */ @Test void testMonitor() throws Exception { @@ -201,7 +202,7 @@ public Thread newThread(final Runnable r) { /** * Test using a thread factory. - * @throws Exception + * @throws Exception. */ @Test void testThreadFactory() throws Exception { 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 f56cc4e9ebc..211438a5586 100644 --- a/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/ChunkedOutputStreamTest.java @@ -48,7 +48,7 @@ public void write(final byte[] b, final int off, final int len) { /** * Tests the default chunk size with a ByteArrayOutputStream. * - * @throws IOException + * @throws IOException. */ @Test void testBuildSetByteArrayOutputStream() throws IOException { @@ -64,7 +64,7 @@ void testBuildSetByteArrayOutputStream() throws IOException { /** * Tests the default chunk size with a Path. * - * @throws IOException + * @throws IOException Thrown on test failure. */ @Test void testBuildSetPath() throws IOException { diff --git a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java index ae3fe77d50d..e0b29fb599b 100644 --- a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java @@ -148,7 +148,8 @@ void testAtThreshold(final int initialBufferSize) throws IOException { /** * Tests the case where the amount of data falls below the threshold, and is therefore confined to memory. - * @throws IOException + * + * @throws IOException Thrown on a test failure. */ @ParameterizedTest(name = "initialBufferSize = {0}") @MethodSource("data") @@ -237,7 +238,8 @@ void testTempFileAboveThreshold(final int initialBufferSize) throws IOException /** * Tests specifying a temporary file and the threshold is reached. - * @throws IOException + * + * @throws IOException Thrown on a test failure. */ @ParameterizedTest(name = "initialBufferSize = {0}") @MethodSource("data") @@ -278,7 +280,8 @@ void testTempFileAboveThresholdPrefixOnly(final int initialBufferSize) throws IO /** * Tests specifying a temporary file and the threshold not reached. - * @throws IOException + * + * @throws IOException Thrown on a test failure. */ @ParameterizedTest(name = "initialBufferSize = {0}") @MethodSource("data") @@ -302,7 +305,7 @@ void testTempFileBelowThreshold(final int initialBufferSize) throws IOException /** * Tests specifying a temporary file and the threshold is reached. * - * @throws Exception + * @throws IOException Thrown on a test failure. */ @Test void testTempFileError() throws Exception { @@ -338,7 +341,8 @@ void testThresholdNegative(final int initialBufferSize) throws IOException { /** * Tests the case where there are multiple writes beyond the threshold, to ensure that the * {@code thresholdReached()} method is only called once, as the threshold is crossed for the first time. - * @throws IOException + * + * @throws IOException Thrown on a test failure. */ @ParameterizedTest(name = "initialBufferSize = {0}") @MethodSource("data") @@ -418,7 +422,8 @@ void testWriteToLargeCtor(final int initialBufferSize) throws IOException { /** * Tests whether writeTo() properly writes small content. - * @throws IOException + * + * @throws IOException Thrown on a test failure. */ @ParameterizedTest(name = "initialBufferSize = {0}") @MethodSource("data") diff --git a/src/test/java/org/apache/commons/io/serialization/AbstractCloseableListTest.java b/src/test/java/org/apache/commons/io/serialization/AbstractCloseableListTest.java index 43ec7d55d8e..6258a3cc0e2 100644 --- a/src/test/java/org/apache/commons/io/serialization/AbstractCloseableListTest.java +++ b/src/test/java/org/apache/commons/io/serialization/AbstractCloseableListTest.java @@ -37,7 +37,7 @@ public abstract class AbstractCloseableListTest { /** * Adds a {@link Closeable} to close after each test. * - * @param The Closeable type + * @param The Closeable type. * @param t The Closeable. * @return The Closeable. * @see Closeable diff --git a/src/test/java/org/apache/commons/io/test/TestUtils.java b/src/test/java/org/apache/commons/io/test/TestUtils.java index a4278c14974..619c1e3eb30 100644 --- a/src/test/java/org/apache/commons/io/test/TestUtils.java +++ b/src/test/java/org/apache/commons/io/test/TestUtils.java @@ -48,9 +48,9 @@ public abstract class TestUtils { /** * Assert that the content of a file is equal to that in a byte[]. * - * @param b0 the expected contents - * @param file the file to check - * @throws IOException If an I/O error occurs while reading the file contents + * @param b0 the expected contents. + * @param file the file to check. + * @throws IOException If an I/O error occurs while reading the file contents. */ public static void assertEqualContent(final byte[] b0, final File file) throws IOException { assertEqualContent(b0, file.toPath()); @@ -59,9 +59,9 @@ public static void assertEqualContent(final byte[] b0, final File file) throws I /** * Assert that the content of a file is equal to that in a byte[]. * - * @param b0 the expected contents - * @param file the file to check - * @throws IOException If an I/O error occurs while reading the file contents + * @param b0 the expected contents. + * @param file the file to check. + * @throws IOException If an I/O error occurs while reading the file contents. */ public static void assertEqualContent(final byte[] b0, final Path file) throws IOException { int count = 0; @@ -82,9 +82,9 @@ public static void assertEqualContent(final byte[] b0, final Path file) throws I /** * Assert that the content of a file is equal to that in a char[]. * - * @param c0 the expected contents - * @param file the file to check - * @throws IOException If an I/O error occurs while reading the file contents + * @param c0 the expected contents. + * @param file the file to check. + * @throws IOException If an I/O error occurs while reading the file contents. */ public static void assertEqualContent(final char[] c0, final File file) throws IOException { assertEqualContent(c0, file.toPath()); @@ -93,9 +93,9 @@ public static void assertEqualContent(final char[] c0, final File file) throws I /** * Assert that the content of a file is equal to that in a char[]. * - * @param c0 the expected contents - * @param file the file to check - * @throws IOException If an I/O error occurs while reading the file contents + * @param c0 the expected contents. + * @param file the file to check. + * @throws IOException If an I/O error occurs while reading the file contents. */ public static void assertEqualContent(final char[] c0, final Path file) throws IOException { int count = 0; diff --git a/src/test/java/org/apache/commons/io/test/ThrowOnFlushAndCloseOutputStream.java b/src/test/java/org/apache/commons/io/test/ThrowOnFlushAndCloseOutputStream.java index f5096673a78..8d9d8b01a39 100644 --- a/src/test/java/org/apache/commons/io/test/ThrowOnFlushAndCloseOutputStream.java +++ b/src/test/java/org/apache/commons/io/test/ThrowOnFlushAndCloseOutputStream.java @@ -33,8 +33,8 @@ public class ThrowOnFlushAndCloseOutputStream extends ProxyOutputStream { /** * @param proxy OutputStream to delegate to. - * @param throwOnFlush True if flush() is forbidden - * @param throwOnClose True if close() is forbidden + * @param throwOnFlush True if flush() is forbidden. + * @param throwOnClose True if close() is forbidden. */ public ThrowOnFlushAndCloseOutputStream(final OutputStream proxy, final boolean throwOnFlush, final boolean throwOnClose) { From 37d17bc8a483e47b8fb5c3fe3aca0aaf7c0418c7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 26 Dec 2025 16:04:19 -0500 Subject: [PATCH 110/174] Javadoc: Normalize spelling --- .../apache/commons/io/DirectoryWalker.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java index 1bc9d44b030..13a4c3f51f0 100644 --- a/src/main/java/org/apache/commons/io/DirectoryWalker.java +++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java @@ -196,14 +196,14 @@ *
      * public class FooDirectoryWalker extends DirectoryWalker {
      *
    - *     private volatile boolean cancelled = false;
    + *     private volatile boolean canceled = false;
      *
      *     public void cancel() {
    - *         cancelled = true;
    + *         canceled = true;
      *     }
      *
      *     protected boolean handleIsCancelled(File file, int depth, Collection results) {
    - *         return cancelled;
    + *         return canceled;
      *     }
      *
      *     protected void handleCancelled(File startDirectory, Collection results, CancelException cancel) {
    @@ -272,8 +272,8 @@ public static class CancelException extends IOException {
              * Constructs a {@link CancelException} with
              * the file and depth when cancellation occurred.
              *
    -         * @param file  the file when the operation was cancelled, may be null.
    -         * @param depth  the depth when the operation was cancelled, may be null.
    +         * @param file  the file when the operation was canceled, may be null.
    +         * @param depth  the depth when the operation was canceled, may be null.
              */
             public CancelException(final File file, final int depth) {
                 this("Operation Cancelled", file, depth);
    @@ -285,8 +285,8 @@ public CancelException(final File file, final int depth) {
              * cancellation occurred.
              *
              * @param message  the detail message.
    -         * @param file  the file when the operation was cancelled.
    -         * @param depth  the depth when the operation was cancelled.
    +         * @param file  the file when the operation was canceled.
    +         * @param depth  the depth when the operation was canceled.
              */
             public CancelException(final String message, final File file, final int depth) {
                 super(message);
    @@ -295,18 +295,18 @@ public CancelException(final String message, final File file, final int depth) {
             }
     
             /**
    -         * Returns the depth when the operation was cancelled.
    +         * Returns the depth when the operation was canceled.
              *
    -         * @return the depth when the operation was cancelled.
    +         * @return the depth when the operation was canceled.
              */
             public int getDepth() {
                 return depth;
             }
     
             /**
    -         * Returns the file when the operation was cancelled.
    +         * Returns the file when the operation was canceled.
              *
    -         * @return the file when the operation was cancelled.
    +         * @return the file when the operation was canceled.
              */
             public File getFile() {
                 return file;
    @@ -376,7 +376,7 @@ protected DirectoryWalker(IOFileFilter directoryFilter, IOFileFilter fileFilter,
         }
     
         /**
    -     * Checks whether the walk has been cancelled by calling {@link #handleIsCancelled},
    +     * Checks whether the walk has been canceled by calling {@link #handleIsCancelled},
          * throwing a {@link CancelException} if it has.
          * 

    * Writers of subclasses should not normally call this method as it is called @@ -417,7 +417,7 @@ protected File[] filterDirectoryContents(final File directory, final int depth, } /** - * Overridable callback method invoked when the operation is cancelled. + * Overridable callback method invoked when the operation is canceled. * The file being processed when the cancellation occurred can be * obtained from the exception. *

    @@ -526,7 +526,7 @@ protected void handleFile(final File file, final int depth, final Collection /** * Overridable callback method invoked to determine if the entire walk - * operation should be immediately cancelled. + * operation should be immediately canceled. *

    * This method should be implemented by those subclasses that want to * provide a public {@code cancel()} method available from another @@ -534,13 +534,13 @@ protected void handleFile(final File file, final int depth, final Collection *

    *
          *  public class FooDirectoryWalker extends DirectoryWalker {
    -     *    private volatile boolean cancelled = false;
    +     *    private volatile boolean canceled = false;
          *
          *    public void cancel() {
    -     *        cancelled = true;
    +     *        canceled = true;
          *    }
          *    private void handleIsCancelled(File file, int depth, Collection results) {
    -     *        return cancelled;
    +     *        return canceled;
          *    }
          *    protected void handleCancelled(File startDirectory,
          *              Collection results, CancelException cancel) {
    @@ -550,7 +550,7 @@ protected void handleFile(final File file, final int depth, final Collection
          * 
    *

    * If this method returns true, then the directory walk is immediately - * cancelled. The next callback method will be {@link #handleCancelled}. + * canceled. The next callback method will be {@link #handleCancelled}. *

    *

    * This implementation returns false. @@ -559,14 +559,14 @@ protected void handleFile(final File file, final int depth, final Collection * @param file the file or directory being processed. * @param depth the current directory level (starting directory = 0). * @param results the collection of result objects, may be updated. - * @return true if the walk has been cancelled. + * @return true if the walk has been canceled. * @throws IOException if an I/O Error occurs. */ @SuppressWarnings("unused") // Possibly thrown from subclasses. protected boolean handleIsCancelled( final File file, final int depth, final Collection results) throws IOException { // do nothing - overridable by subclass - return false; // not cancelled + return false; // not canceled } /** From 09e6e3687bb734f34d1a0bc479b50591aa3feed3 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 26 Dec 2025 16:04:46 -0500 Subject: [PATCH 111/174] Variable: Normalize spelling --- .../org/apache/commons/io/DirectoryWalkerTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java index 57316a32677..101d61066d9 100644 --- a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java +++ b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java @@ -172,7 +172,7 @@ protected void handleFile(final File file, final int depth, final Collection { private final String cancelFileName; private final boolean suppressCancel; - private boolean cancelled; + private boolean canceled; public List results; TestMultiThreadCancelWalker(final String cancelFileName, final boolean suppressCancel) { @@ -199,9 +199,9 @@ protected void handleCancelled(final File startDirectory, final Collection @Override protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws IOException { results.add(directory); - assertFalse(cancelled); + assertFalse(canceled); if (cancelFileName.equals(directory.getName())) { - cancelled = true; + canceled = true; } } @@ -209,16 +209,16 @@ protected void handleDirectoryEnd(final File directory, final int depth, final C @Override protected void handleFile(final File file, final int depth, final Collection results) throws IOException { results.add(file); - assertFalse(cancelled); + assertFalse(canceled); if (cancelFileName.equals(file.getName())) { - cancelled = true; + canceled = true; } } /** Handles Cancelled. */ @Override protected boolean handleIsCancelled(final File file, final int depth, final Collection results) throws IOException { - return cancelled; + return canceled; } } // Directories From e6fe8dc0b32925071361be7d175b6b6f2962750b Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 26 Dec 2025 16:16:01 -0500 Subject: [PATCH 112/174] Javadoc: Fix double the --- src/main/java/org/apache/commons/io/IOUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index df7af6a8803..8d63f052603 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1556,7 +1556,7 @@ public static long copy(final Reader reader, final Appendable output, final Char } /** - * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the the virtual machine's {@linkplain Charset#defaultCharset() default + * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default * charset}, and calling flush. *

    * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. From 930f1fbc6c272eedab8a8c35e344f009c44c15b4 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 26 Dec 2025 16:25:15 -0500 Subject: [PATCH 113/174] Javadoc: Normalize and fix spelling --- src/main/java/org/apache/commons/io/input/Tailer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/input/Tailer.java b/src/main/java/org/apache/commons/io/input/Tailer.java index 2a631d89351..d8ef0db0818 100644 --- a/src/main/java/org/apache/commons/io/input/Tailer.java +++ b/src/main/java/org/apache/commons/io/input/Tailer.java @@ -1043,7 +1043,7 @@ public void run() { * - gets "touched" * - Files.getLastModifiedTime returns a new timestamp but newer data is not yet there ( * was reported to happen on busy systems or samba network shares, see IO-279) - * The default behaviour is to replay the whole file. If this is unsdesired in your usecase, + * The default behavior is to replay the whole file. If this is undesired in your usecase, * use the ignoreTouch builder flag */ if (!ignoreTouch) { From aa9110f23badd011cf2676525b8363b6d9a50987 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 29 Dec 2025 08:51:45 -0500 Subject: [PATCH 114/174] Bump notice file end year from 2025 to 2026 --- NOTICE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE.txt b/NOTICE.txt index 2a4682551b1..b9fb860712d 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,5 +1,5 @@ Apache Commons IO -Copyright 2002-2025 The Apache Software Foundation +Copyright 2002-2026 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (https://www.apache.org/). From 64e2ab4416c3e14ffa4bc947b064768d24a027bc Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Tue, 30 Dec 2025 13:29:24 +0000 Subject: [PATCH 115/174] Javadoc typos --- src/main/java/org/apache/commons/io/IOUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 8d63f052603..c97cae25a44 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -300,12 +300,13 @@ public void close() { /** * A singleton empty byte array. * - * @since 2.9.0 + * @since 2.9.0 */ public static final byte[] EMPTY_BYTE_ARRAY = {}; /** * Represents the end-of-file (or stream) value {@value}. + * * @since 2.5 (made public) */ public static final int EOF = -1; From 66528578e20275834b3c58dc8e90032738b4c969 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 31 Dec 2025 17:50:38 -0500 Subject: [PATCH 116/174] Javadoc: Empty Javadoc line before the 1st tag. --- src/main/java/org/apache/commons/io/CopyUtils.java | 1 + src/main/java/org/apache/commons/io/EndianUtils.java | 1 + src/main/java/org/apache/commons/io/FileCleaner.java | 1 + src/main/java/org/apache/commons/io/FilenameUtils.java | 2 ++ src/main/java/org/apache/commons/io/IOUtils.java | 2 ++ src/main/java/org/apache/commons/io/LineIterator.java | 1 + .../org/apache/commons/io/UncheckedIOExceptions.java | 1 + .../commons/io/comparator/PathFileComparator.java | 1 + .../apache/commons/io/filefilter/AndFileFilter.java | 1 + .../apache/commons/io/filefilter/FileFilterUtils.java | 8 ++++++-- .../commons/io/filefilter/MagicNumberFileFilter.java | 1 + .../org/apache/commons/io/filefilter/OrFileFilter.java | 1 + .../org/apache/commons/io/function/IOIterable.java | 1 + .../org/apache/commons/io/function/IOIterator.java | 1 + .../apache/commons/io/input/BoundedInputStream.java | 1 + .../commons/io/input/CharSequenceInputStream.java | 1 + .../java/org/apache/commons/io/input/ProxyReader.java | 10 ++++++++++ .../commons/io/input/UnixLineEndingInputStream.java | 2 ++ .../org/apache/commons/io/input/XmlStreamReader.java | 1 + .../java/org/apache/commons/io/monitor/FileEntry.java | 1 + .../java/org/apache/commons/io/output/ProxyWriter.java | 2 ++ .../io/output/UnsynchronizedByteArrayOutputStream.java | 1 + 22 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java index 1c88614a213..ed816826305 100644 --- a/src/main/java/org/apache/commons/io/CopyUtils.java +++ b/src/main/java/org/apache/commons/io/CopyUtils.java @@ -117,6 +117,7 @@ public class CopyUtils { /** * Copies bytes from a {@code byte[]} to an {@link OutputStream}. + * * @param input the byte array to read from. * @param output the {@link OutputStream} to write to. * @throws IOException In case of an I/O problem. diff --git a/src/main/java/org/apache/commons/io/EndianUtils.java b/src/main/java/org/apache/commons/io/EndianUtils.java index 0306a661acc..cae06b8345e 100644 --- a/src/main/java/org/apache/commons/io/EndianUtils.java +++ b/src/main/java/org/apache/commons/io/EndianUtils.java @@ -50,6 +50,7 @@ public class EndianUtils { /** * Reads the next byte from the input stream. + * * @param input the stream. * @return the byte. * @throws IOException if the end of file is reached. diff --git a/src/main/java/org/apache/commons/io/FileCleaner.java b/src/main/java/org/apache/commons/io/FileCleaner.java index e874f91f903..fbb0bf51d7e 100644 --- a/src/main/java/org/apache/commons/io/FileCleaner.java +++ b/src/main/java/org/apache/commons/io/FileCleaner.java @@ -63,6 +63,7 @@ public class FileCleaner { * in the resource cleanup code, such as * {@code javax.servlet.ServletContextListener.contextDestroyed(javax.servlet.ServletContextEvent)}. * One called, no new objects can be tracked by the file cleaner. + * * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}. */ @Deprecated diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java index fe49a1a8a6c..19b1c80487a 100644 --- a/src/main/java/org/apache/commons/io/FilenameUtils.java +++ b/src/main/java/org/apache/commons/io/FilenameUtils.java @@ -143,12 +143,14 @@ public class FilenameUtils { /** * The extension separator character. + * * @since 1.4 */ public static final char EXTENSION_SEPARATOR = '.'; /** * The extension separator String. + * * @since 1.4 */ public static final String EXTENSION_SEPARATOR_STR = Character.toString(EXTENSION_SEPARATOR); diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index c97cae25a44..42774b3f78f 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -708,6 +708,7 @@ static void checkFromToIndex(final int fromIndex, final int toIndex, final int l *

  3. Removes the current thread's value for thread-local variables.
  4. *
  5. Sets static scratch arrays to 0s.
  6. * + * * @see IO#clear() */ static void clear() { @@ -902,6 +903,7 @@ public static T closeQuietly(final Closeable closeable, fi *

    * Also consider using a try-with-resources statement where appropriate. *

    + * * @param closeables the objects to close, may be null or already closed. * @see #closeQuietly(Closeable) * @since 2.5 diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index a96af0f224b..d4482c6f3c1 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -142,6 +142,7 @@ public boolean hasNext() { /** * Overridable method to validate each line that is returned. * This implementation always returns true. + * * @param line the line that is to be validated. * @return true if valid, false to remove from the iterator. */ diff --git a/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java b/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java index f31043769b7..6a5075c52ca 100644 --- a/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java +++ b/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java @@ -47,6 +47,7 @@ public static UncheckedIOException create(final Object message) { *

    * This method exists because there is no String constructor in {@link UncheckedIOException}. *

    + * * @param e cause the {@link IOException}. * @param message the detail message. * @return a new {@link UncheckedIOException}. diff --git a/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java b/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java index dc4fb296049..4ae379add58 100644 --- a/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java +++ b/src/main/java/org/apache/commons/io/comparator/PathFileComparator.java @@ -51,6 +51,7 @@ *

    * Serialization is deprecated and will be removed in 3.0. *

    + * * @since 1.4 */ public class PathFileComparator extends AbstractFileComparator implements Serializable { diff --git a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java index 2db3e46f5a8..f7ec25a1f3e 100644 --- a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java @@ -129,6 +129,7 @@ public boolean accept(final File file, final String name) { /** * {@inheritDoc} + * * @since 2.9.0 */ @Override diff --git a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java index 587bb4226ee..74715ef6158 100644 --- a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java +++ b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java @@ -226,13 +226,13 @@ public static IOFileFilter fileFileFilter() { * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles, * FileFilterUtils.suffixFileFilter(".java")); *
    + * * @param filter the filter to apply to the set of files. * @param files the array of files to apply the filter to. * @return a subset of {@code files} that is accepted by the * file filter. * @throws NullPointerException if the filter is {@code null} * or {@code files} contains a {@code null} value. - * * @since 2.0 */ public static File[] filter(final IOFileFilter filter, final File... files) { @@ -259,13 +259,13 @@ public static File[] filter(final IOFileFilter filter, final File... files) { * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles, * FileFilterUtils.suffixFileFilter(".java")); * + * * @param filter the filter to apply to the set of files. * @param files the array of files to apply the filter to. * @return a subset of {@code files} that is accepted by the * file filter. * @throws IllegalArgumentException if the filter is {@code null} * or {@code files} contains a {@code null} value. - * * @since 2.0 */ public static File[] filter(final IOFileFilter filter, final Iterable files) { @@ -311,6 +311,7 @@ private static R filterFiles(final IOFileFilter filter, final Stream + * * @param filter the filter to apply to each files in the list. * @param files the collection of files to apply the filter to. * @return a subset of {@code files} that is accepted by the @@ -339,6 +340,7 @@ public static List filterList(final IOFileFilter filter, final File... fil * List<File> directories = FileFilterUtils.filterList(filesAndDirectories, * FileFilterUtils.directoryFileFilter()); * + * * @param filter the filter to apply to each files in the list. * @param files the collection of files to apply the filter to. * @return a subset of {@code files} that is accepted by the @@ -369,6 +371,7 @@ public static List filterList(final IOFileFilter filter, final Iterable + * * @param filter the filter to apply to the set of files. * @param files the collection of files to apply the filter to. * @return a subset of {@code files} that is accepted by the @@ -398,6 +401,7 @@ public static Set filterSet(final IOFileFilter filter, final File... files * Set<File> javaFiles = FileFilterUtils.filterSet(allFiles, * FileFilterUtils.suffixFileFilter(".java")); * + * * @param filter the filter to apply to the set of files. * @param files the collection of files to apply the filter to. * @return a subset of {@code files} that is accepted by the diff --git a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java index 5868af39a32..3f28a7661cd 100644 --- a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java @@ -270,6 +270,7 @@ public boolean accept(final File file) { * be rejected. * *

    + * * @param file the file to accept or reject. * @param attributes the path's basic attributes (may be null). * @return {@code true} if the file contains the filter's magic number diff --git a/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java index 2bc8fc7074c..4017ce8f070 100644 --- a/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/OrFileFilter.java @@ -76,6 +76,7 @@ private OrFileFilter(final int initialCapacity) { /** * Constructs a new instance for the give filters. + * * @param fileFilters filters to OR. * @since 2.9.0 */ diff --git a/src/main/java/org/apache/commons/io/function/IOIterable.java b/src/main/java/org/apache/commons/io/function/IOIterable.java index bfaccc103b2..dd656dff7dd 100644 --- a/src/main/java/org/apache/commons/io/function/IOIterable.java +++ b/src/main/java/org/apache/commons/io/function/IOIterable.java @@ -75,6 +75,7 @@ default IOSpliterator spliterator() { *

    * Implementations may not have anything to unwrap and that behavior is undefined for now. *

    + * * @return the underlying Iterable. */ Iterable unwrap(); diff --git a/src/main/java/org/apache/commons/io/function/IOIterator.java b/src/main/java/org/apache/commons/io/function/IOIterator.java index 2d99480cf5b..85727a6e431 100644 --- a/src/main/java/org/apache/commons/io/function/IOIterator.java +++ b/src/main/java/org/apache/commons/io/function/IOIterator.java @@ -110,6 +110,7 @@ default void remove() throws IOException { *

    * Implementations may not have anything to unwrap and that behavior is undefined for now. *

    + * * @return the underlying Iterator. */ Iterator unwrap(); diff --git a/src/main/java/org/apache/commons/io/input/BoundedInputStream.java b/src/main/java/org/apache/commons/io/input/BoundedInputStream.java index e3e2d86bf0f..d9fbac8b104 100644 --- a/src/main/java/org/apache/commons/io/input/BoundedInputStream.java +++ b/src/main/java/org/apache/commons/io/input/BoundedInputStream.java @@ -82,6 +82,7 @@ * .get(); * } * + * * @see Builder * @since 2.0 */ diff --git a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java index 874dcf1cb39..689424c062f 100644 --- a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java @@ -281,6 +281,7 @@ CharsetEncoder getCharsetEncoder() { /** * {@inheritDoc} + * * @param readLimit max read limit (ignored). */ @Override diff --git a/src/main/java/org/apache/commons/io/input/ProxyReader.java b/src/main/java/org/apache/commons/io/input/ProxyReader.java index 47cff05b1f1..9d53d007651 100644 --- a/src/main/java/org/apache/commons/io/input/ProxyReader.java +++ b/src/main/java/org/apache/commons/io/input/ProxyReader.java @@ -94,6 +94,7 @@ protected void beforeRead(final int n) throws IOException { /** * Invokes the delegate's {@code close()} method. + * * @throws IOException if an I/O error occurs. */ @Override @@ -122,6 +123,7 @@ protected void handleIOException(final IOException e) throws IOException { /** * Invokes the delegate's {@code mark(int)} method. + * * @param readAheadLimit read ahead limit. * @throws IOException if an I/O error occurs. */ @@ -136,6 +138,7 @@ public synchronized void mark(final int readAheadLimit) throws IOException { /** * Invokes the delegate's {@code markSupported()} method. + * * @return true if mark is supported, otherwise false. */ @Override @@ -145,6 +148,7 @@ public boolean markSupported() { /** * Invokes the delegate's {@code read()} method. + * * @return the character read or -1 if the end of stream. * @throws IOException if an I/O error occurs. */ @@ -163,6 +167,7 @@ public int read() throws IOException { /** * Invokes the delegate's {@code read(char[])} method. + * * @param chr the buffer to read the characters into. * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. @@ -182,6 +187,7 @@ public int read(final char[] chr) throws IOException { /** * Invokes the delegate's {@code read(char[], int, int)} method. + * * @param chr the buffer to read the characters into. * @param st The start offset. * @param len The number of bytes to read. @@ -203,6 +209,7 @@ public int read(final char[] chr, final int st, final int len) throws IOExceptio /** * Invokes the delegate's {@code read(CharBuffer)} method. + * * @param target the char buffer to read the characters into. * @return the number of characters read or -1 if the end of stream. * @throws IOException if an I/O error occurs. @@ -223,6 +230,7 @@ public int read(final CharBuffer target) throws IOException { /** * Invokes the delegate's {@code ready()} method. + * * @return true if the stream is ready to be read. * @throws IOException if an I/O error occurs. */ @@ -238,6 +246,7 @@ public boolean ready() throws IOException { /** * Invokes the delegate's {@code reset()} method. + * * @throws IOException if an I/O error occurs. */ @Override @@ -251,6 +260,7 @@ public synchronized void reset() throws IOException { /** * Invokes the delegate's {@code skip(long)} method. + * * @param ln the number of bytes to skip. * @return the number of bytes to skipped or EOF if the end of stream. * @throws IOException if an I/O error occurs. diff --git a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java index bfd0a0f632c..be80d0d4eb1 100644 --- a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java @@ -53,6 +53,7 @@ public UnixLineEndingInputStream(final InputStream inputStream, final boolean en /** * Closes the stream. Also closes the underlying stream. + * * @throws IOException If an I/O error occurs. */ @Override @@ -112,6 +113,7 @@ public synchronized int read() throws IOException { /** * Reads the next item from the target, updating internal flags in the process + * * @return the next int read from the target stream. * @throws IOException If an I/O error occurs. */ diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java index 94b2de54c79..d8343fd9371 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java @@ -695,6 +695,7 @@ public XmlStreamReader(final URLConnection urlConnection, final String defaultEn /** * Calculates the HTTP encoding. + * * @param bomEnc BOM encoding. * @param xmlGuessEnc XML Guess encoding. * @param xmlEnc XML encoding. diff --git a/src/main/java/org/apache/commons/io/monitor/FileEntry.java b/src/main/java/org/apache/commons/io/monitor/FileEntry.java index e4487173798..fac3317958b 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileEntry.java +++ b/src/main/java/org/apache/commons/io/monitor/FileEntry.java @@ -48,6 +48,7 @@ *

    * Serialization is deprecated and will be removed in 3.0. *

    + * * @see FileAlterationObserver * @since 2.0 */ diff --git a/src/main/java/org/apache/commons/io/output/ProxyWriter.java b/src/main/java/org/apache/commons/io/output/ProxyWriter.java index cf82a1b2e61..ae7f8e8f536 100644 --- a/src/main/java/org/apache/commons/io/output/ProxyWriter.java +++ b/src/main/java/org/apache/commons/io/output/ProxyWriter.java @@ -144,6 +144,7 @@ protected void beforeWrite(final int n) throws IOException { /** * Invokes the delegate's {@code close()} method. + * * @throws IOException if an I/O error occurs. */ @Override @@ -153,6 +154,7 @@ public void close() throws IOException { /** * Invokes the delegate's {@code flush()} method. + * * @throws IOException if an I/O error occurs. */ @Override diff --git a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java index a47a3b2aa2a..58195ffeb6f 100644 --- a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java @@ -157,6 +157,7 @@ public static InputStream toBufferedInputStream(final InputStream input, final i * Constructs a new byte array output stream. The buffer capacity is initially. * * {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary. + * * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. */ @Deprecated From 575c111cd3f9102cad7ab0056ee793ee6a321393 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 31 Dec 2025 18:36:03 -0500 Subject: [PATCH 117/174] Javadoc: The @deprecated tag should be last. --- src/main/java/org/apache/commons/io/LineIterator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index d4482c6f3c1..741eae08ddc 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -56,9 +56,9 @@ public class LineIterator implements Iterator, Closeable { * Closes a {@link LineIterator} quietly. * * @param iterator The iterator to close, or {@code null}. + * @see Throwable#addSuppressed(Throwable) * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle * suppressed exceptions manually. - * @see Throwable#addSuppressed(Throwable) */ @Deprecated public static void closeQuietly(final LineIterator iterator) { From 4a950c11a8d922e2602d53ca18442406b89bb923 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jan 2026 07:19:59 -0500 Subject: [PATCH 118/174] Bump commons.bytebuddy.version from 1.18.2 to 1.18.3 (#820) Bumps `commons.bytebuddy.version` from 1.18.2 to 1.18.3. Updates `net.bytebuddy:byte-buddy` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.2...byte-buddy-1.18.3) Updates `net.bytebuddy:byte-buddy-agent` from 1.18.2 to 1.18.3 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.18.2...byte-buddy-1.18.3) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-version: 1.18.3 dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: net.bytebuddy:byte-buddy-agent dependency-version: 1.18.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0baa433cabc..49a5a84bdb5 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ file comparators, endian transformation classes, and much more. https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ site-content - 1.18.2 + 1.18.3 false true From f156ec05903f143bd6ae9cf2bdad04e8474b4afe Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 1 Jan 2026 07:20:24 -0500 Subject: [PATCH 119/174] Bump commons.bytebuddy.version from 1.18.2 to 1.18.3 #820 --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 12cf9018531..411f98e943e 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,7 +55,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 91 to 93 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. - Bump commons.bytebuddy.version from 1.17.8 to 1.18.2 #814. + Bump commons.bytebuddy.version from 1.17.8 to 1.18.3 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From ddb72e4a52e6e3ddb2635ef8b47c70e95584aea2 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 1 Jan 2026 07:53:28 -0500 Subject: [PATCH 120/174] Fix XML Schema xsi:schemaLocation name (as opposed to URI) --- src/site/xdoc/download_io.xml | 2 +- src/site/xdoc/issue-tracking.xml | 2 +- src/site/xdoc/mail-lists.xml | 2 +- src/site/xdoc/security.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 6ca018e32ca..6a0ba144cd9 100644 --- a/src/site/xdoc/download_io.xml +++ b/src/site/xdoc/download_io.xml @@ -58,7 +58,7 @@ limitations under the License. --> + xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Download Apache Commons IO Apache Commons Team diff --git a/src/site/xdoc/issue-tracking.xml b/src/site/xdoc/issue-tracking.xml index 714f68c3e1b..3cda13d50c6 100644 --- a/src/site/xdoc/issue-tracking.xml +++ b/src/site/xdoc/issue-tracking.xml @@ -43,7 +43,7 @@ limitations under the License. --> + xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons IO Issue tracking Apache Commons Team diff --git a/src/site/xdoc/mail-lists.xml b/src/site/xdoc/mail-lists.xml index 97815e3d51d..bfb01dd0539 100644 --- a/src/site/xdoc/mail-lists.xml +++ b/src/site/xdoc/mail-lists.xml @@ -41,7 +41,7 @@ limitations under the License. --> + xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons IO Mailing Lists Apache Commons Team diff --git a/src/site/xdoc/security.xml b/src/site/xdoc/security.xml index 6999a217027..90e0d19e87b 100644 --- a/src/site/xdoc/security.xml +++ b/src/site/xdoc/security.xml @@ -5,7 +5,7 @@ on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> + xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> Apache Commons Security Reports Apache Commons Team From b53aa6e46f52b7f5bccc6b61f831db899f2eaf38 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 1 Jan 2026 08:13:26 -0500 Subject: [PATCH 121/174] Better description --- src/changes/changes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 411f98e943e..1c1e8e027d5 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -48,7 +48,7 @@ The type attribute can be add,update,fix,remove. Fix Apache RAT plugin console warnings. - ByteArraySeekableByteChannel.position|truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. + ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Fix malformed Javadoc comments. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. From 8279b7fc3b697fc72c2b0f7b8bc80ec14d25a3a7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 2 Jan 2026 17:26:22 -0500 Subject: [PATCH 122/174] Bump org.apache.commons:commons-parent from 93 to 94 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 49a5a84bdb5..55070c9ba35 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 93 + 94 4.0.0 commons-io diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 1c1e8e027d5..bc25f7aeeb8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -53,7 +53,7 @@ The type attribute can be add,update,fix,remove. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. - Bump org.apache.commons:commons-parent from 91 to 93 #816. + Bump org.apache.commons:commons-parent from 91 to 94 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.3 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From b36ebaefc2c356202658b5f67ec2d119fee81434 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 4 Jan 2026 12:48:04 -0500 Subject: [PATCH 123/174] Javadoc Add an empty line before a Javadoc comment --- src/main/java/org/apache/commons/io/DirectoryWalker.java | 2 ++ .../java/org/apache/commons/io/FileCleaningTracker.java | 1 + src/main/java/org/apache/commons/io/FileSystem.java | 1 + .../java/org/apache/commons/io/IOIndexedException.java | 1 + .../java/org/apache/commons/io/build/package-info.java | 2 +- src/main/java/org/apache/commons/io/file/PathUtils.java | 9 +++++++++ .../apache/commons/io/filefilter/DelegateFileFilter.java | 1 + .../org/apache/commons/io/input/ReaderInputStream.java | 1 + .../java/org/apache/commons/io/output/ClosedWriter.java | 1 + src/test/java/org/apache/commons/io/CharsetsTest.java | 1 + .../java/org/apache/commons/io/DirectoryWalkerTest.java | 4 ++++ .../org/apache/commons/io/FileDeleteStrategyTest.java | 1 + .../org/apache/commons/io/IOUtilsConcurrentTest.java | 7 +++++++ .../apache/commons/io/input/QueueInputStreamTest.java | 2 ++ 14 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java index 13a4c3f51f0..1d2a7678fd4 100644 --- a/src/main/java/org/apache/commons/io/DirectoryWalker.java +++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java @@ -265,6 +265,7 @@ public static class CancelException extends IOException { /** The file being processed when the exception was thrown. */ private final File file; + /** The file depth when the exception was thrown. */ private final int depth; @@ -312,6 +313,7 @@ public File getFile() { return file; } } + /** * The file filter to use to filter files and directories. */ diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index 5bde044e333..4fa8e973b6f 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -51,6 +51,7 @@ public class FileCleaningTracker { * The reaper thread. */ private final class Reaper extends Thread { + /** Constructs a new Reaper */ Reaper() { super("File Reaper"); diff --git a/src/main/java/org/apache/commons/io/FileSystem.java b/src/main/java/org/apache/commons/io/FileSystem.java index e4ba867a685..8fd3299d853 100644 --- a/src/main/java/org/apache/commons/io/FileSystem.java +++ b/src/main/java/org/apache/commons/io/FileSystem.java @@ -118,6 +118,7 @@ public enum FileSystem { * Implementations measure length and can truncate to a specified limit. */ enum NameLengthStrategy { + /** Length measured as encoded bytes. */ BYTES { @Override diff --git a/src/main/java/org/apache/commons/io/IOIndexedException.java b/src/main/java/org/apache/commons/io/IOIndexedException.java index fcb84334ff6..958d8307317 100644 --- a/src/main/java/org/apache/commons/io/IOIndexedException.java +++ b/src/main/java/org/apache/commons/io/IOIndexedException.java @@ -27,6 +27,7 @@ public class IOIndexedException extends IOException { private static final long serialVersionUID = 1L; + /** * Converts input to a suitable String for exception message. * diff --git a/src/main/java/org/apache/commons/io/build/package-info.java b/src/main/java/org/apache/commons/io/build/package-info.java index bda177c354c..5eed609d544 100644 --- a/src/main/java/org/apache/commons/io/build/package-info.java +++ b/src/main/java/org/apache/commons/io/build/package-info.java @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** * Provides classes to implement the builder pattern for IO classes. * @@ -49,5 +50,4 @@ * * @since 2.12.0 */ - package org.apache.commons.io.build; diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java index c943f5f9e4d..6a9718c4c07 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -200,32 +200,38 @@ private RelativeSortedPaths(final Path dir1, final Path dir2, final int maxDepth private static final OpenOption[] OPEN_OPTIONS_TRUNCATE = { StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING }; private static final OpenOption[] OPEN_OPTIONS_APPEND = { StandardOpenOption.CREATE, StandardOpenOption.APPEND }; + /** * Empty {@link CopyOption} array. * * @since 2.8.0 */ public static final CopyOption[] EMPTY_COPY_OPTIONS = {}; + /** * Empty {@link DeleteOption} array. * * @since 2.8.0 */ public static final DeleteOption[] EMPTY_DELETE_OPTION_ARRAY = {}; + /** * Empty {@link FileAttribute} array. * * @since 2.13.0 */ public static final FileAttribute[] EMPTY_FILE_ATTRIBUTE_ARRAY = {}; + /** * Empty {@link FileVisitOption} array. */ public static final FileVisitOption[] EMPTY_FILE_VISIT_OPTION_ARRAY = {}; + /** * Empty {@link LinkOption} array. */ public static final LinkOption[] EMPTY_LINK_OPTION_ARRAY = {}; + /** * {@link LinkOption} array for {@link LinkOption#NOFOLLOW_LINKS}. * @@ -234,16 +240,19 @@ private RelativeSortedPaths(final Path dir1, final Path dir2, final int maxDepth */ @Deprecated public static final LinkOption[] NOFOLLOW_LINK_OPTION_ARRAY = { LinkOption.NOFOLLOW_LINKS }; + /** * A LinkOption used to follow link in this class, the inverse of {@link LinkOption#NOFOLLOW_LINKS}. * * @since 2.12.0 */ static final LinkOption NULL_LINK_OPTION = null; + /** * Empty {@link OpenOption} array. */ public static final OpenOption[] EMPTY_OPEN_OPTION_ARRAY = {}; + /** * Empty {@link Path} array. * diff --git a/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java index f4f414753cb..dd8674f3916 100644 --- a/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/DelegateFileFilter.java @@ -39,6 +39,7 @@ public class DelegateFileFilter extends AbstractFileFilter implements Serializab /** The File filter */ private final transient FileFilter fileFilter; + /** The Filename filter */ private final transient FilenameFilter fileNameFilter; 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 45f19cc94c5..51cddcd2e98 100644 --- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java @@ -209,6 +209,7 @@ private static CharsetEncoder newEncoder(final Charset charset) { * CharBuffer used as input for the decoder. It should be reasonably large as we read data from the underlying Reader into this buffer. */ private final CharBuffer encoderIn; + /** * ByteBuffer used as output for the decoder. This buffer can be small as it is only used to transfer data from the decoder to the buffer provided by the * caller. diff --git a/src/main/java/org/apache/commons/io/output/ClosedWriter.java b/src/main/java/org/apache/commons/io/output/ClosedWriter.java index 550b9daf523..446b31b7950 100644 --- a/src/main/java/org/apache/commons/io/output/ClosedWriter.java +++ b/src/main/java/org/apache/commons/io/output/ClosedWriter.java @@ -38,6 +38,7 @@ public class ClosedWriter extends Writer { * @since 2.12.0 */ public static final ClosedWriter INSTANCE = new ClosedWriter(); + /** * The singleton instance. * diff --git a/src/test/java/org/apache/commons/io/CharsetsTest.java b/src/test/java/org/apache/commons/io/CharsetsTest.java index 7c718c148bf..0b48c68404b 100644 --- a/src/test/java/org/apache/commons/io/CharsetsTest.java +++ b/src/test/java/org/apache/commons/io/CharsetsTest.java @@ -46,6 +46,7 @@ public class CharsetsTest { * For parameterized tests. */ public static final String AVAIL_CHARSETS = "org.apache.commons.io.CharsetsTest#availableCharsetsKeySet"; + /** * For parameterized tests. */ diff --git a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java index 101d61066d9..deef523cd18 100644 --- a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java +++ b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java @@ -85,6 +85,7 @@ protected void handleFile(final File file, final int depth, final Collection Date: Mon, 12 Jan 2026 10:49:36 -0500 Subject: [PATCH 124/174] Bump github/codeql-action from 4.31.9 to 4.31.10 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c83bf59255c..5d024662b1f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 980935089e8..2d7a1b0f8bc 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: sarif_file: results.sarif From 7246479f92ea4dd0988090c7e4f2d3bd4566e088 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 12 Jan 2026 13:53:38 -0500 Subject: [PATCH 125/174] Bump org.apache.commons:commons-parent from 94 to 95. --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 55070c9ba35..6a0b4c053df 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 94 + 95 4.0.0 commons-io diff --git a/src/changes/changes.xml b/src/changes/changes.xml index bc25f7aeeb8..a7003bb8713 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -53,7 +53,7 @@ The type attribute can be add,update,fix,remove. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. - Bump org.apache.commons:commons-parent from 91 to 94 #816. + Bump org.apache.commons:commons-parent from 91 to 95 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.3 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From 4cf10f99352a6ba1b58a4bb58b88caacf85619a7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 10:06:19 -0500 Subject: [PATCH 126/174] Fix TODO comment --- .../java/org/apache/commons/io/input/ThrottledInputStream.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java index 9b670bdae10..b6350fadca6 100644 --- a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java @@ -185,7 +185,7 @@ private Builder setMaxBytesPerSecond(final double maxBytesPerSecond) { */ public void setMaxBytesPerSecond(final long maxBytesPerSecond) { setMaxBytesPerSecond((double) maxBytesPerSecond); - // TODO 3.0 + // TODO 4.0 // return asThis(); } From bec4d9b10c9f197a59544101f83c7e6d2c801f94 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 10:08:24 -0500 Subject: [PATCH 127/174] Revert "Fix TODO comment" This reverts commit 4cf10f99352a6ba1b58a4bb58b88caacf85619a7. --- .../java/org/apache/commons/io/input/ThrottledInputStream.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java index b6350fadca6..9b670bdae10 100644 --- a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java @@ -185,7 +185,7 @@ private Builder setMaxBytesPerSecond(final double maxBytesPerSecond) { */ public void setMaxBytesPerSecond(final long maxBytesPerSecond) { setMaxBytesPerSecond((double) maxBytesPerSecond); - // TODO 4.0 + // TODO 3.0 // return asThis(); } From c28ac9ad3cfb1a0a2d009a330715f4c4c4c8986b Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 10:14:26 -0500 Subject: [PATCH 128/174] Better parameter name --- src/main/java/org/apache/commons/io/FilenameUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java index 19b1c80487a..c3a2a2dcfa5 100644 --- a/src/main/java/org/apache/commons/io/FilenameUtils.java +++ b/src/main/java/org/apache/commons/io/FilenameUtils.java @@ -300,11 +300,11 @@ public static boolean directoryContains(final String canonicalParent, final Stri * Does the work of getting the path. * * @param fileName the file name. - * @param includeSeparator true to include the end separator. + * @param includeEndSeparator true to include the end separator. * @return the path. * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000}). */ - private static String doGetFullPath(final String fileName, final boolean includeSeparator) { + private static String doGetFullPath(final String fileName, final boolean includeEndSeparator) { if (fileName == null) { return null; } @@ -313,7 +313,7 @@ private static String doGetFullPath(final String fileName, final boolean include return null; } if (prefix >= fileName.length()) { - if (includeSeparator) { + if (includeEndSeparator) { return getPrefix(fileName); // add end slash if necessary } return fileName; @@ -322,7 +322,7 @@ private static String doGetFullPath(final String fileName, final boolean include if (index < 0) { return fileName.substring(0, prefix); } - int end = index + (includeSeparator ? 1 : 0); + int end = index + (includeEndSeparator ? 1 : 0); if (end == 0) { end++; } From e156e77a2c7d6560e1775a913dcaed9937d7be00 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 10:15:12 -0500 Subject: [PATCH 129/174] Remove extra blank lines --- src/test/java/org/apache/commons/io/FilenameUtilsTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java index 0441c6ac2e6..6908e10e4a5 100644 --- a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java @@ -349,15 +349,12 @@ void testGetFullPathNoEndSeparator() { */ @Test void testGetFullPathNoEndSeparator_IO_248() { - // Test single separator assertEquals("/", FilenameUtils.getFullPathNoEndSeparator("/")); assertEquals("\\", FilenameUtils.getFullPathNoEndSeparator("\\")); - // Test one level directory assertEquals("/", FilenameUtils.getFullPathNoEndSeparator("/abc")); assertEquals("\\", FilenameUtils.getFullPathNoEndSeparator("\\abc")); - // Test one level directory assertEquals("/abc", FilenameUtils.getFullPathNoEndSeparator("/abc/xyz")); assertEquals("\\abc", FilenameUtils.getFullPathNoEndSeparator("\\abc\\xyz")); From d886319e56c9bbdd7338590e8acb88496f6191c7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 10:33:45 -0500 Subject: [PATCH 130/174] Add org.apache.commons.io.FilenameUtilsTest.testGetFullPathNoEndSeparator_IO_771() --- .../org/apache/commons/io/FilenameUtilsTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java index 6908e10e4a5..88ff939caee 100644 --- a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java @@ -34,6 +34,7 @@ import org.apache.commons.io.test.TestUtils; import org.apache.commons.lang3.SystemUtils; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -360,6 +361,20 @@ void testGetFullPathNoEndSeparator_IO_248() { assertEquals("\\abc", FilenameUtils.getFullPathNoEndSeparator("\\abc\\xyz")); } + /** + * Test for https://issues.apache.org/jira/browse/IO-771 + */ + @Test + @Disabled + void testGetFullPathNoEndSeparator_IO_771() { + // IO-771 + // On macOS while in the target folder in jshell: + // new java.io.File("X:\\path\\subfolder").getAbsolutePath() + // ==> "/Users/garygregory/git/commons/commons-lang/target/X:\\path\\subfolder" + assertEquals("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path", + FilenameUtils.getFullPathNoEndSeparator("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path\\\\subfolder")); + } + @Test void testGetName() { assertNull(FilenameUtils.getName(null)); From 3434b046c1c068ca97ecad691ecd7dfc827431c4 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 18 Jan 2026 12:57:53 -0500 Subject: [PATCH 131/174] Add more to FilenameUtilsTest.testGetFullPathNoEndSeparator_IO_771() --- src/test/java/org/apache/commons/io/FilenameUtilsTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java index 88ff939caee..3049b9ae098 100644 --- a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java @@ -371,8 +371,15 @@ void testGetFullPathNoEndSeparator_IO_771() { // On macOS while in the target folder in jshell: // new java.io.File("X:\\path\\subfolder").getAbsolutePath() // ==> "/Users/garygregory/git/commons/commons-lang/target/X:\\path\\subfolder" + assertEquals("/Users/garygregory/git/commons/commons-lang/target/X:\\path", + FilenameUtils.getFullPathNoEndSeparator("/Users/garygregory/git/commons/commons-lang/target/X:\\path\\subfolder")); + assertEquals("X:\\path", FilenameUtils.getFullPathNoEndSeparator("X:\\path\\subfolder")); assertEquals("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path", FilenameUtils.getFullPathNoEndSeparator("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path\\\\subfolder")); + assertEquals("/Users/garygregory/git/commons/commons-lang/target/X:\\\\\\path", + FilenameUtils.getFullPathNoEndSeparator("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path\\\\\\subfolder\\\\")); + assertEquals("/Users/garygregory/git/commons/commons-lang/target/X:\\\\\\path", + FilenameUtils.getFullPathNoEndSeparator("/Users/garygregory/git/commons/commons-lang/target/X:\\\\path\\\\\\subfolder")); } @Test From 3f79f1b03ed6a7975e56e44bc315227380ef2c9f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 19 Jan 2026 08:16:00 -0500 Subject: [PATCH 132/174] Javadoc --- .../apache/commons/io/input/ReadAheadInputStream.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index 57edd41bcb7..1dda06115eb 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -63,6 +63,9 @@ public class ReadAheadInputStream extends FilterInputStream { * .setExecutorService(Executors.newSingleThreadExecutor(ReadAheadInputStream::newThread)) * .get();} * + *

    + * If an {@link ExecutorService} is not set, then a single-threaded daemon executor service is used. + *

    * * @see #get() * @since 2.12.0 @@ -90,7 +93,7 @@ public Builder() { *
      *
    • {@link #getInputStream()} gets the target aspect.
    • *
    • {@link #getBufferSize()}
    • - *
    • {@link ExecutorService}
    • + *
    • {@link ExecutorService}, if not set, a single-threaded daemon executor service is used.
    • *
    * * @return a new instance. @@ -108,8 +111,11 @@ public ReadAheadInputStream get() throws IOException { /** * Sets the executor service for the read-ahead thread. + *

    + * If not set, a single-threaded daemon executor service is used. + *

    * - * @param executorService the executor service for the read-ahead thread. + * @param executorService the executor service for the read-ahead thread, may be {@code null}. * @return {@code this} instance. */ public Builder setExecutorService(final ExecutorService executorService) { From 3ce2774594c30a5154680011a1e1c2971112f85a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 19 Jan 2026 08:57:29 -0500 Subject: [PATCH 133/174] ReadAheadInputStream.close() doesn't always close its filtered input stream --- src/changes/changes.xml | 1 + .../io/input/ReadAheadInputStream.java | 13 ++++---- .../io/input/ReadAheadInputStreamTest.java | 33 ++++++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a7003bb8713..13dacc4b0c3 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -50,6 +50,7 @@ The type attribute can be add,update,fix,remove. Fix Apache RAT plugin console warnings. ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Fix malformed Javadoc comments. + ReadAheadInputStream.close() doesn't always close its filtered input stream. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index 1dda06115eb..a028bfbc0f6 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -209,7 +209,7 @@ private ReadAheadInputStream(final Builder builder) throws IOException { } /** - * Constructs an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold. * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. @@ -221,7 +221,7 @@ public ReadAheadInputStream(final InputStream inputStream, final int bufferSizeI } /** - * Constructs an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold. * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. @@ -234,7 +234,7 @@ public ReadAheadInputStream(final InputStream inputStream, final int bufferSizeI } /** - * Constructs an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold. * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. @@ -293,7 +293,6 @@ public void close() throws IOException { } finally { stateChangeLock.unlock(); } - if (shutdownExecutorService) { try { executorService.shutdownNow(); @@ -308,6 +307,9 @@ public void close() throws IOException { } } } + if (isSafeToCloseUnderlyingInputStream) { + super.close(); + } } private void closeUnderlyingInputStreamIfNecessary() { @@ -352,7 +354,6 @@ public int read(final byte[] b, final int offset, int len) throws IOException { if (len == 0) { return 0; } - if (!activeBuffer.hasRemaining()) { // No remaining in active buffer - lock and switch to write ahead buffer. stateChangeLock.lock(); @@ -538,7 +539,7 @@ private long skipInternal(final long n) throws IOException { } /** - * Flips the active and read ahead buffer + * Flips the active and read ahead buffers. */ private void swapBuffers() { final ByteBuffer temp = activeBuffer; diff --git a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java index 94d7b289edd..6ad34e9b2b4 100644 --- a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java @@ -14,24 +14,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.commons.io.input; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.StandardOpenOption; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** - * Tests {@link ReadAheadInputStream}. - * - * This class was ported and adapted from Apache Spark commit 933dc6cb7b3de1d8ccaf73d124d6eb95b947ed19 where it was called {@code ReadAheadInputStreamSuite}. + * Tests {@link ReadAheadInputStream}. This class was ported and adapted from Apache Spark commit 933dc6cb7b3de1d8ccaf73d124d6eb95b947ed19 where it was called + * {@code ReadAheadInputStreamSuite}. */ class ReadAheadInputStreamTest extends AbstractInputStreamTest { @SuppressWarnings("resource") @BeforeEach - public void setUpInputStreams() throws IOException { + void setUpInputStreams() throws IOException { inputStreams = new InputStream[] { // Tests equal and aligned buffers of wrapped an outer stream. new ReadAheadInputStream(new BufferedFileChannelInputStream(InputPath, 8 * 1024), 8 * 1024), @@ -57,4 +64,22 @@ public void setUpInputStreams() throws IOException { ReadAheadInputStream.builder().setPath(InputPath).setOpenOptions(StandardOpenOption.READ).get() }; } + @Test + void testClosePlusExecutorService() throws IOException { + final ExecutorService externalExecutor = Executors.newSingleThreadExecutor(); + // We use an outer try-with-resources for only the test fixture instead of combining it with the ReadAheadInputStream allocation. + try (FileInputStream inputStream = new FileInputStream("src/test/resources/org/apache/commons/io/FileUtilsTestDataLF.bin")) { + try { + try (ReadAheadInputStream rais = ReadAheadInputStream.builder().setInputStream(inputStream).setExecutorService(externalExecutor).get()) { + assertEquals('1', rais.read()); + } + // The underlying FileInputStream should be closed since ReadAheadInputStream is a FilterInputStream. + assertThrows(IOException.class, inputStream::read); + // The caller remains responsible for shutting down the executor. + } finally { + // TODO ExecutorService implements AutoCloseable in Java 19+. + externalExecutor.shutdown(); + } + } + } } From 5e39dd4778d58bf0c6314eae3da3781b809f5285 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 19 Jan 2026 15:40:04 +0000 Subject: [PATCH 134/174] Prepare for the next release candidate --- CONTRIBUTING.md | 1 - README.md | 5 ++-- RELEASE-NOTES.txt | 55 +++++++++++++++++++++++++++++++++++ src/changes/changes.xml | 2 +- src/site/xdoc/download_io.xml | 26 ++++++++--------- 5 files changed, 71 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 71936d344fd..e924b4ac04e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -110,7 +110,6 @@ Additional Resources + [Contributor License Agreement][cla] + [General GitHub documentation](https://help.github.com/) + [GitHub pull request documentation](https://help.github.com/articles/creating-a-pull-request/) -+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons) [cla]:https://www.apache.org/licenses/#clas [jira]:https://issues.apache.org/jira/browse/IO diff --git a/README.md b/README.md index 36a82594a8e..8e4ae6db426 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Apache Commons IO [![Java CI](https://github.com/apache/commons-io/actions/workflows/maven.yml/badge.svg)](https://github.com/apache/commons-io/actions/workflows/maven.yml) [![Maven Central](https://img.shields.io/maven-central/v/commons-io/commons-io?label=Maven%20Central)](https://search.maven.org/artifact/commons-io/commons-io) -[![Javadocs](https://javadoc.io/badge/commons-io/commons-io/2.21.0.svg)](https://javadoc.io/doc/commons-io/commons-io/2.21.0) +[![Javadocs](https://javadoc.io/badge/commons-io/commons-io/2.22.0.svg)](https://javadoc.io/doc/commons-io/commons-io/2.22.0) [![CodeQL](https://github.com/apache/commons-io/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/apache/commons-io/actions/workflows/codeql-analysis.yml) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/apache/commons-io/badge)](https://api.securityscorecards.dev/projects/github.com/apache/commons-io) @@ -69,7 +69,7 @@ Alternatively, you can pull it from the central Maven repositories: commons-io commons-io - 2.21.0 + 2.22.0 ``` @@ -112,7 +112,6 @@ Additional Resources + [Apache Commons Homepage](https://commons.apache.org/) + [Apache Issue Tracker (JIRA)](https://issues.apache.org/jira/browse/IO) + [Apache Commons Slack Channel](https://the-asf.slack.com/archives/C60NVB8AD) -+ [Apache Commons Twitter Account](https://twitter.com/ApacheCommons) Apache Commons Components ------------------------- diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 3f84b517499..7de38f13ad8 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,4 +1,59 @@ +Apache Commons IO 2.22.0 Release Notes + +The Apache Commons IO team is pleased to announce the release of Apache Commons IO 2.22.0. + +Introduction +------------ + +The Apache Commons IO library contains utility classes, stream implementations, file filters, +file comparators, endian transformation classes, and much more. + +This is a feature and maintenance release. Java 8 or later is required. + +New features +------------ + +o Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. Thanks to Gary Gregory. + +Fixed Bugs +---------- + +o Fix Apache RAT plugin console warnings. Thanks to Gary Gregory. +o ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Thanks to Gary Gregory, Piotr P. Karwasz. +o Fix malformed Javadoc comments. Thanks to Gary Gregory. +o ReadAheadInputStream.close() doesn't always close its filtered input stream. Thanks to Stanislav Fort, Gary Gregory. + +Changes +------- + +o Bump org.apache.commons:commons-parent from 91 to 95 #816. Thanks to Gary Gregory, Dependabot. +o Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Thanks to Gary Gregory, Dependabot. +o Bump commons.bytebuddy.version from 1.17.8 to 1.18.3 #814, #820. Thanks to Gary Gregory, Dependabot. +o Bump commons-lang3 from 3.19.0 to 3.20.0. Thanks to Gary Gregory, Dependabot. + + +Commons IO 2.7 and up requires Java 8 or above. +Commons IO 2.6 requires Java 7 or above. +Commons IO 2.3 through 2.5 requires Java 6 or above. +Commons IO 2.2 requires Java 5 or above. +Commons IO 1.4 requires Java 1.3 or above. + +Historical list of changes: https://commons.apache.org/proper/commons-io/changes.html + +For complete information on Apache Commons IO, including instructions on how to submit bug reports, +patches, or suggestions for improvement, see the Apache Commons IO website: + +https://commons.apache.org/proper/commons-io/ + +Download page: https://commons.apache.org/proper/commons-io/download_io.cgi + +Have fun! +-Apache Commons Team + +------------------------------------------------------------------------------ + + Apache Commons IO 2.21.0 Release Notes The Apache Commons IO team is pleased to announce the release of Apache Commons IO 2.21.0. diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 13dacc4b0c3..dc1e4972998 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,7 +45,7 @@ The type attribute can be add,update,fix,remove. Apache Commons IO Release Notes
    - + Fix Apache RAT plugin console warnings. ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 6a0ba144cd9..3f782a85373 100644 --- a/src/site/xdoc/download_io.xml +++ b/src/site/xdoc/download_io.xml @@ -115,32 +115,32 @@ limitations under the License.

    -
    +
    - - - + + + - - - + + +
    commons-io-2.21.0-bin.tar.gzsha512pgpcommons-io-2.22.0-bin.tar.gzsha512pgp
    commons-io-2.21.0-bin.zipsha512pgpcommons-io-2.22.0-bin.zipsha512pgp
    - - - + + + - - - + + +
    commons-io-2.21.0-src.tar.gzsha512pgpcommons-io-2.22.0-src.tar.gzsha512pgp
    commons-io-2.21.0-src.zipsha512pgpcommons-io-2.22.0-src.zipsha512pgp
    From ed2de75357c63fc57c62cd1ab87447aefe3acbaa Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 21 Jan 2026 06:43:28 -0500 Subject: [PATCH 135/174] [IO-884] IOUtils.contentEquals(Reader,Reader) makes an invalid assumption about read return value - Add test IOUtilsTest.testContentEquals_Reader_Reader_unevenReads() - Revert unreleased code to previous implementation --- .../java/org/apache/commons/io/IOUtils.java | 1275 ++++++++--------- .../org/apache/commons/io/IOUtilsTest.java | 43 +- .../commons/io/input/ChunkedReader.java | 49 + 3 files changed, 636 insertions(+), 731 deletions(-) create mode 100644 src/test/java/org/apache/commons/io/input/ChunkedReader.java diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index 42774b3f78f..b3d73648f02 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -88,18 +88,13 @@ *
  7. contentEquals - these methods compare the content of two streams
  8. * *

    - * The byte-to-char methods and char-to-byte methods involve a conversion step. - * Two methods are provided in each case, one that uses the platform default - * encoding and the other which allows you to specify an encoding. You are - * encouraged to always specify an encoding because relying on the platform - * default can lead to unexpected results, for example when moving from - * development to production. + * The byte-to-char methods and char-to-byte methods involve a conversion step. Two methods are provided in each case, one that uses the platform default + * encoding and the other which allows you to specify an encoding. You are encouraged to always specify an encoding because relying on the platform default can + * lead to unexpected results, for example when moving from development to production. *

    *

    - * All the methods in this class that read a stream are buffered internally. - * This means that there is no cause to use a {@link BufferedInputStream} - * or {@link BufferedReader}. The default buffer size of 4K has been shown - * to be efficient in tests. + * All the methods in this class that read a stream are buffered internally. This means that there is no cause to use a {@link BufferedInputStream} or + * {@link BufferedReader}. The default buffer size of 4K has been shown to be efficient in tests. *

    *

    * The various copy methods all delegate the actual copying to one of the following methods: @@ -110,18 +105,14 @@ *

  9. {@link #copyLarge(Reader, Writer, char[])}
  10. *
  11. {@link #copyLarge(Reader, Writer, long, long, char[])}
  12. * - * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)} - * which calls {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls - * {@link #copyLarge(InputStream, OutputStream, byte[])}. + * For example, {@link #copy(InputStream, OutputStream)} calls {@link #copyLarge(InputStream, OutputStream)} which calls + * {@link #copy(InputStream, OutputStream, int)} which creates the buffer and calls {@link #copyLarge(InputStream, OutputStream, byte[])}. *

    - * Applications can re-use buffers by using the underlying methods directly. - * This may improve performance for applications that need to do a lot of copying. + * Applications can re-use buffers by using the underlying methods directly. This may improve performance for applications that need to do a lot of copying. *

    *

    - * Wherever possible, the methods in this class do not flush or close - * the stream. This is to avoid making non-portable assumptions about the - * streams' origin and further use. Thus the caller is still responsible for - * closing streams after use. + * Wherever possible, the methods in this class do not flush or close the stream. This is to avoid making non-portable assumptions about the streams' + * origin and further use. Thus the caller is still responsible for closing streams after use. *

    *

    * Provenance: Excalibur. @@ -134,11 +125,13 @@ public class IOUtils { /** * Holder for per-thread internal scratch buffer. - * - *

    Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer - * is allocated to avoid data corruption.

    - * - *

    Typical usage:

    + *

    + * Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer is + * allocated to avoid data corruption. + *

    + *

    + * Typical usage: + *

    * *
    {@code
          * try (ScratchBytes scratch = ScratchBytes.get()) {
    @@ -151,10 +144,7 @@ public class IOUtils {
         static final class ScratchBytes implements AutoCloseable {
     
             /**
    -         * Wraps an internal byte array.
    -         *
    -         * [0] boolean in use.
    -         * [1] byte[] buffer.
    +         * Wraps an internal byte array. [0] boolean in use. [1] byte[] buffer.
              */
             private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, byteArray() });
     
    @@ -203,11 +193,13 @@ public void close() {
     
         /**
          * Holder for per-thread internal scratch buffer.
    -     *
    -     * 

    Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer - * is allocated to avoid data corruption.

    - * - *

    Typical usage:

    + *

    + * Buffers are created lazily and reused within the same thread to reduce allocation overhead. In the rare case of reentrant access, a temporary buffer is + * allocated to avoid data corruption. + *

    + *

    + * Typical usage: + *

    * *
    {@code
          * try (ScratchChars scratch = ScratchChars.get()) {
    @@ -220,10 +212,7 @@ public void close() {
         static final class ScratchChars implements AutoCloseable {
     
             /**
    -         * Wraps an internal char array.
    -         *
    -         * [0] boolean in use.
    -         * [1] char[] buffer.
    +         * Wraps an internal char array. [0] boolean in use. [1] char[] buffer.
              */
             private static final ThreadLocal LOCAL = ThreadLocal.withInitial(() -> new Object[] { false, charArray() });
     
    @@ -351,8 +340,7 @@ public void close() {
         public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
     
         /**
    -     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a
    -     * BufferedInputStream from the given InputStream.
    +     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a BufferedInputStream from the given InputStream.
          *
          * @param inputStream the InputStream to wrap or return (not null).
          * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
    @@ -364,16 +352,14 @@ public static BufferedInputStream buffer(final InputStream inputStream) {
             // reject null early on rather than waiting for IO operation to fail
             // not checked by BufferedInputStream
             Objects.requireNonNull(inputStream, "inputStream");
    -        return inputStream instanceof BufferedInputStream ?
    -                (BufferedInputStream) inputStream : new BufferedInputStream(inputStream);
    +        return inputStream instanceof BufferedInputStream ? (BufferedInputStream) inputStream : new BufferedInputStream(inputStream);
         }
     
         /**
    -     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a
    -     * BufferedInputStream from the given InputStream.
    +     * Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a BufferedInputStream from the given InputStream.
          *
          * @param inputStream the InputStream to wrap or return (not null).
    -     * @param size the buffer size, if a new BufferedInputStream is created.
    +     * @param size        the buffer size, if a new BufferedInputStream is created.
          * @return the given InputStream or a new {@link BufferedInputStream} for the given InputStream.
          * @throws NullPointerException if the input parameter is null.
          * @since 2.5
    @@ -383,13 +369,11 @@ public static BufferedInputStream buffer(final InputStream inputStream, final in
             // reject null early on rather than waiting for IO operation to fail
             // not checked by BufferedInputStream
             Objects.requireNonNull(inputStream, "inputStream");
    -        return inputStream instanceof BufferedInputStream ?
    -                (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size);
    +        return inputStream instanceof BufferedInputStream ? (BufferedInputStream) inputStream : new BufferedInputStream(inputStream, size);
         }
     
         /**
    -     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a
    -     * BufferedOutputStream from the given OutputStream.
    +     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a BufferedOutputStream from the given OutputStream.
          *
          * @param outputStream the OutputStream to wrap or return (not null).
          * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream.
    @@ -401,16 +385,14 @@ public static BufferedOutputStream buffer(final OutputStream outputStream) {
             // reject null early on rather than waiting for IO operation to fail
             // not checked by BufferedInputStream
             Objects.requireNonNull(outputStream, "outputStream");
    -        return outputStream instanceof BufferedOutputStream ?
    -                (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream);
    +        return outputStream instanceof BufferedOutputStream ? (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream);
         }
     
         /**
    -     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a
    -     * BufferedOutputStream from the given OutputStream.
    +     * Returns the given OutputStream if it is already a {@link BufferedOutputStream}, otherwise creates a BufferedOutputStream from the given OutputStream.
          *
          * @param outputStream the OutputStream to wrap or return (not null).
    -     * @param size the buffer size, if a new BufferedOutputStream is created.
    +     * @param size         the buffer size, if a new BufferedOutputStream is created.
          * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream.
          * @throws NullPointerException if the input parameter is null.
          * @since 2.5
    @@ -420,13 +402,11 @@ public static BufferedOutputStream buffer(final OutputStream outputStream, final
             // reject null early on rather than waiting for IO operation to fail
             // not checked by BufferedInputStream
             Objects.requireNonNull(outputStream, "outputStream");
    -        return outputStream instanceof BufferedOutputStream ?
    -                (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size);
    +        return outputStream instanceof BufferedOutputStream ? (BufferedOutputStream) outputStream : new BufferedOutputStream(outputStream, size);
         }
     
         /**
    -     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from
    -     * the given reader.
    +     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader.
          *
          * @param reader the reader to wrap or return (not null).
          * @return the given reader or a new {@link BufferedReader} for the given reader.
    @@ -438,11 +418,10 @@ public static BufferedReader buffer(final Reader reader) {
         }
     
         /**
    -     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the
    -     * given reader.
    +     * Returns the given reader if it is already a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader.
          *
          * @param reader the reader to wrap or return (not null).
    -     * @param size the buffer size, if a new BufferedReader is created.
    +     * @param size   the buffer size, if a new BufferedReader is created.
          * @return the given reader or a new {@link BufferedReader} for the given reader.
          * @throws NullPointerException if the input parameter is null.
          * @since 2.5
    @@ -452,8 +431,7 @@ public static BufferedReader buffer(final Reader reader, final int size) {
         }
     
         /**
    -     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the
    -     * given Writer.
    +     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the given Writer.
          *
          * @param writer the Writer to wrap or return (not null).
          * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
    @@ -465,11 +443,10 @@ public static BufferedWriter buffer(final Writer writer) {
         }
     
         /**
    -     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the
    -     * given Writer.
    +     * Returns the given Writer if it is already a {@link BufferedWriter}, otherwise creates a BufferedWriter from the given Writer.
          *
          * @param writer the Writer to wrap or return (not null).
    -     * @param size the buffer size, if a new BufferedWriter is created.
    +     * @param size   the buffer size, if a new BufferedWriter is created.
          * @return the given Writer or a new {@link BufferedWriter} for the given Writer.
          * @throws NullPointerException if the input parameter is null.
          * @since 2.5
    @@ -489,9 +466,7 @@ public static byte[] byteArray() {
         }
     
         /**
    -     * Returns a new byte array of the given size.
    -     *
    -     * TODO Consider guarding or warning against large allocations.
    +     * Returns a new byte array of the given size. TODO Consider guarding or warning against large allocations.
          *
          * @param size array size.
          * @return a new byte array of the given size.
    @@ -513,9 +488,7 @@ private static char[] charArray() {
         }
     
         /**
    -     * Returns a new char array of the given size.
    -     *
    -     * TODO Consider guarding or warning against large allocations.
    +     * Returns a new char array of the given size. TODO Consider guarding or warning against large allocations.
          *
          * @param size array size.
          * @return a new char array of the given size.
    @@ -527,19 +500,23 @@ private static char[] charArray(final int size) {
     
         /**
          * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array.
    -     *
    -     * 

    The range is valid if all of the following hold:

    + *

    + * The range is valid if all of the following hold: + *

    *
      - *
    • {@code off >= 0}
    • - *
    • {@code len >= 0}
    • - *
    • {@code off + len <= array.length}
    • + *
    • {@code off >= 0}
    • + *
    • {@code len >= 0}
    • + *
    • {@code off + len <= array.length}
    • *
    + *

    + * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message. + *

    + *

    + * Typical usage in {@link InputStream#read(byte[], int, int)} and {@link OutputStream#write(byte[], int, int)} implementations: + *

    * - *

    If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.

    - * - *

    Typical usage in {@link InputStream#read(byte[], int, int)} and {@link OutputStream#write(byte[], int, int)} implementations:

    - * - *
    
    +     * 
    +     * 
          * public int read(byte[] b, int off, int len) throws IOException {
          *     IOUtils.checkFromIndexSize(b, off, len);
          *     if (len == 0) {
    @@ -557,7 +534,8 @@ private static char[] charArray(final int size) {
          *     ensureOpen();
          *     // perform write...
          * }
    -     * 
    + *
    + *
    * * @param array the array against which the range is validated. * @param off the starting offset into the array (inclusive). @@ -574,19 +552,23 @@ public static void checkFromIndexSize(final byte[] array, final int off, final i /** * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given array. - * - *

    The range is valid if all of the following hold:

    + *

    + * The range is valid if all of the following hold: + *

    *
      - *
    • {@code off >= 0}
    • - *
    • {@code len >= 0}
    • - *
    • {@code off + len <= array.length}
    • + *
    • {@code off >= 0}
    • + *
    • {@code len >= 0}
    • + *
    • {@code off + len <= array.length}
    • *
    + *

    + * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message. + *

    + *

    + * Typical usage in {@link Reader#read(char[], int, int)} and {@link Writer#write(char[], int, int)} implementations: + *

    * - *

    If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.

    - * - *

    Typical usage in {@link Reader#read(char[], int, int)} and {@link Writer#write(char[], int, int)} implementations:

    - * - *
    
    +     * 
    +     * 
          * public int read(char[] cbuf, int off, int len) throws IOException {
          *     ensureOpen();
          *     IOUtils.checkFromIndexSize(cbuf, off, len);
    @@ -604,7 +586,8 @@ public static void checkFromIndexSize(final byte[] array, final int off, final i
          *     }
          *     // perform write...
          * }
    -     * 
    + *
    + *
    * * @param array the array against which the range is validated. * @param off the starting offset into the array (inclusive). @@ -627,19 +610,23 @@ static void checkFromIndexSize(final int off, final int len, final int arrayLeng /** * Validates that the sub-range {@code [off, off + len)} is within the bounds of the given string. - * - *

    The range is valid if all of the following hold:

    + *

    + * The range is valid if all of the following hold: + *

    *
      - *
    • {@code off >= 0}
    • - *
    • {@code len >= 0}
    • - *
    • {@code off + len <= str.length()}
    • + *
    • {@code off >= 0}
    • + *
    • {@code len >= 0}
    • + *
    • {@code off + len <= str.length()}
    • *
    + *

    + * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message. + *

    + *

    + * Typical usage in {@link Writer#write(String, int, int)} implementations: + *

    * - *

    If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.

    - * - *

    Typical usage in {@link Writer#write(String, int, int)} implementations:

    - * - *
    
    +     * 
    +     * 
          * public void write(String str, int off, int len) throws IOException {
          *     IOUtils.checkFromIndexSize(str, off, len);
          *     if (len == 0) {
    @@ -647,7 +634,8 @@ static void checkFromIndexSize(final int off, final int len, final int arrayLeng
          *     }
          *     // perform write...
          * }
    -     * 
    + *
    + *
    * * @param str the string against which the range is validated. * @param off the starting offset into the string (inclusive). @@ -663,27 +651,33 @@ public static void checkFromIndexSize(final String str, final int off, final int /** * Validates that the sub-sequence {@code [fromIndex, toIndex)} is within the bounds of the given {@link CharSequence}. - * - *

    The sub-sequence is valid if all of the following hold:

    + *

    + * The sub-sequence is valid if all of the following hold: + *

    *
      - *
    • {@code fromIndex >= 0}
    • - *
    • {@code fromIndex <= toIndex}
    • - *
    • {@code toIndex <= seq.length()}
    • + *
    • {@code fromIndex >= 0}
    • + *
    • {@code fromIndex <= toIndex}
    • + *
    • {@code toIndex <= seq.length()}
    • *
    + *

    + * If {@code seq} is {@code null}, it is treated as the literal string {@code "null"} (length {@code 4}). + *

    + *

    + * If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message. + *

    + *

    + * Typical usage in {@link Appendable#append(CharSequence, int, int)} implementations: + *

    * - *

    If {@code seq} is {@code null}, it is treated as the literal string {@code "null"} (length {@code 4}).

    - * - *

    If the range is invalid, throws {@link IndexOutOfBoundsException} with a descriptive message.

    - * - *

    Typical usage in {@link Appendable#append(CharSequence, int, int)} implementations:

    - * - *
    
    +     * 
    +     * 
          * public Appendable append(CharSequence csq, int start, int end) throws IOException {
          *     IOUtils.checkFromToIndex(csq, start, end);
          *     // perform append...
          *     return this;
          * }
    -     * 
    + *
    + *
    * * @param seq the character sequence to validate (may be {@code null}, treated as {@code "null"}). * @param fromIndex the starting index (inclusive). @@ -744,7 +738,7 @@ public static void close(final Closeable... closeables) throws IOExceptionList { * Closes the given {@link Closeable} as a null-safe operation. * * @param closeable The resource to close, may be null. - * @param consumer Consume the IOException thrown by {@link Closeable#close()}. + * @param consumer Consume the IOException thrown by {@link Closeable#close()}. * @throws IOException if an I/O error occurs. * @since 2.7 */ @@ -787,13 +781,12 @@ private static void closeQ(final Closeable closeable) { /** * Closes a {@link Closeable} unconditionally. - * *

    - * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in - * finally blocks. + * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    * Example code: *

    + * *
          * Closeable closeable = null;
          * try {
    @@ -809,6 +802,7 @@ private static void closeQ(final Closeable closeable) {
          * 

    * Closing all streams: *

    + * *
          * try {
          *     return IOUtils.copy(inputStream, outputStream);
    @@ -831,7 +825,6 @@ public static void closeQuietly(final Closeable closeable) {
     
         /**
          * Closes a {@link Closeable} unconditionally and adds any exception thrown by the {@code close()} to the given Throwable.
    -     *
          * 

    * For example: *

    @@ -850,7 +843,7 @@ public static void closeQuietly(final Closeable closeable) { * Also consider using a try-with-resources statement where appropriate. *

    * - * @param The Throwable type. + * @param The Throwable type. * @param closeable The object to close, may be null or already closed. * @param throwable Add the exception throw by the closeable to the given Throwable. * @return The given Throwable. @@ -867,17 +860,14 @@ public static T closeQuietly(final Closeable closeable, fi *

    * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. *

    - * This is typically used in finally blocks to ensure that the closeable is closed - * even if an Exception was thrown before the normal close statement was reached. - *
    - * It should not be used to replace the close statement(s) - * which should be present for the non-exceptional case. - *
    - * It is only intended to simplify tidying up where normal processing has already failed - * and reporting close failure as well is not necessary or useful. + * This is typically used in finally blocks to ensure that the closeable is closed even if an Exception was thrown before the normal close statement was + * reached.
    + * It should not be used to replace the close statement(s) which should be present for the non-exceptional case.
    + * It is only intended to simplify tidying up where normal processing has already failed and reporting close failure as well is not necessary or useful. *

    * Example code: *

    + * *
          * Closeable closeable = null;
          * try {
    @@ -891,8 +881,8 @@ public static  T closeQuietly(final Closeable closeable, fi
          * }
          * 
    *

    - * Closing all streams: - *
    + * Closing all streams:
    + * *

          * try {
          *     return IOUtils.copy(inputStream, outputStream);
    @@ -919,7 +909,7 @@ public static void closeQuietly(final Closeable... closeables) {
          * Closes the given {@link Closeable} as a null-safe operation while consuming IOException by the given {@code consumer}.
          *
          * @param closeable The resource to close, may be null.
    -     * @param consumer Consumes the Exception thrown by {@link Closeable#close()}.
    +     * @param consumer  Consumes the Exception thrown by {@link Closeable#close()}.
          * @since 2.7
          */
         public static void closeQuietly(final Closeable closeable, final Consumer consumer) {
    @@ -937,24 +927,24 @@ public static void closeQuietly(final Closeable closeable, final Consumer
    -     * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
    -     * This is typically used in finally blocks.
    +     * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored. This is typically used in finally blocks.
          * 

    *

    * Example code: *

    + * *
    -     *   byte[] data = new byte[1024];
    -     *   InputStream in = null;
    -     *   try {
    -     *       in = new FileInputStream("foo.txt");
    -     *       in.read(data);
    -     *       in.close(); //close errors are handled
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(in);
    -     *   }
    +     * byte[] data = new byte[1024];
    +     * InputStream in = null;
    +     * try {
    +     *     in = new FileInputStream("foo.txt");
    +     *     in.read(data);
    +     *     in.close(); // close errors are handled
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(in);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -986,20 +976,19 @@ public static void closeQuietly(final Iterable closeables) { /** * Closes an {@link OutputStream} unconditionally. *

    - * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
          * byte[] data = "Hello, World".getBytes();
    -     *
          * OutputStream out = null;
          * try {
          *     out = new FileOutputStream("foo.txt");
          *     out.write(data);
    -     *     out.close(); //close errors are handled
    +     *     out.close(); // close errors are handled
          * } catch (IOException e) {
          *     // error handling
          * } finally {
    @@ -1020,24 +1009,24 @@ public static void closeQuietly(final OutputStream output) {
         /**
          * Closes an {@link Reader} unconditionally.
          * 

    - * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link Reader#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
    -     *   char[] data = new char[1024];
    -     *   Reader in = null;
    -     *   try {
    -     *       in = new FileReader("foo.txt");
    -     *       in.read(data);
    -     *       in.close(); //close errors are handled
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(in);
    -     *   }
    +     * char[] data = new char[1024];
    +     * Reader in = null;
    +     * try {
    +     *     in = new FileReader("foo.txt");
    +     *     in.read(data);
    +     *     in.close(); // close errors are handled
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(in);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -1053,23 +1042,22 @@ public static void closeQuietly(final Reader reader) { /** * Closes a {@link Selector} unconditionally. *

    - * Equivalent to {@link Selector#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link Selector#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
    -     *   Selector selector = null;
    -     *   try {
    -     *       selector = Selector.open();
    -     *       // process socket
    -     *
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(selector);
    -     *   }
    +     * Selector selector = null;
    +     * try {
    +     *     selector = Selector.open();
    +     *     // process socket
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(selector);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -1086,23 +1074,23 @@ public static void closeQuietly(final Selector selector) { /** * Closes a {@link ServerSocket} unconditionally. *

    - * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
    -     *   ServerSocket socket = null;
    -     *   try {
    -     *       socket = new ServerSocket();
    -     *       // process socket
    -     *       socket.close();
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(socket);
    -     *   }
    +     * ServerSocket socket = null;
    +     * try {
    +     *     socket = new ServerSocket();
    +     *     // process socket
    +     *     socket.close();
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(socket);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -1119,23 +1107,23 @@ public static void closeQuietly(final ServerSocket serverSocket) { /** * Closes a {@link Socket} unconditionally. *

    - * Equivalent to {@link Socket#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link Socket#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
    -     *   Socket socket = null;
    -     *   try {
    -     *       socket = new Socket("http://www.foo.com/", 80);
    -     *       // process socket
    -     *       socket.close();
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(socket);
    -     *   }
    +     * Socket socket = null;
    +     * try {
    +     *     socket = new Socket("http://www.foo.com/", 80);
    +     *     // process socket
    +     *     socket.close();
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(socket);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -1168,23 +1156,23 @@ public static void closeQuietly(final Stream closeables) { /** * Closes an {@link Writer} unconditionally. *

    - * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. - * This is typically used in finally blocks. + * Equivalent to {@link Writer#close()}, except any exceptions will be ignored. This is typically used in finally blocks. *

    *

    * Example code: *

    + * *
    -     *   Writer out = null;
    -     *   try {
    -     *       out = new StringWriter();
    -     *       out.write("Hello World");
    -     *       out.close(); //close errors are handled
    -     *   } catch (Exception e) {
    -     *       // error handling
    -     *   } finally {
    -     *       IOUtils.closeQuietly(out);
    -     *   }
    +     * Writer out = null;
    +     * try {
    +     *     out = new StringWriter();
    +     *     out.write("Hello World");
    +     *     out.close(); // close errors are handled
    +     * } catch (Exception e) {
    +     *     // error handling
    +     * } finally {
    +     *     IOUtils.closeQuietly(out);
    +     * }
          * 
    *

    * Also consider using a try-with-resources statement where appropriate. @@ -1206,7 +1194,7 @@ public static void closeQuietly(final Writer writer) { * @param input the {@link InputStream} to read. * @return the number of bytes copied. or {@code 0} if {@code input is null}. * @throws NullPointerException if the InputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.8.0 */ public static long consume(final InputStream input) throws IOException { @@ -1222,7 +1210,7 @@ public static long consume(final InputStream input) throws IOException { * @param input the {@link Reader} to read. * @return the number of bytes copied. or {@code 0} if {@code input is null}. * @throws NullPointerException if the Reader is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.12.0 */ public static long consume(final Reader input) throws IOException { @@ -1230,18 +1218,15 @@ public static long consume(final Reader input) throws IOException { } /** - * Compares the contents of two Streams to determine if they are equal or - * not. + * Compares the contents of two Streams to determine if they are equal or not. *

    - * This method buffers the input internally using - * {@link BufferedInputStream} if they are not already buffered. + * This method buffers the input internally using {@link BufferedInputStream} if they are not already buffered. *

    * * @param input1 the first stream. * @param input2 the second stream. - * @return true if the content of the streams are equal or they both don't. - * exist, false otherwise. - * @throws IOException if an I/O error occurs. + * @return true if the content of the streams are equal or they both don't. exist, false otherwise. + * @throws IOException if an I/O error occurs. */ @SuppressWarnings("resource") // Caller closes input streams public static boolean contentEquals(final InputStream input1, final InputStream input2) throws IOException { @@ -1276,11 +1261,10 @@ private static boolean contentEquals(final Iterator iterator1, final Iterator * @param input2 the second reader. * @return true if the content of the readers are equal or they both don't exist, false otherwise. * @throws NullPointerException if either input is null. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 1.1 */ public static boolean contentEquals(final Reader input1, final Reader input2) throws IOException { - // See IOUtilsContentEqualsReadersBenchmark_2_22_0 for performance testing. if (input1 == input2) { return true; } @@ -1290,22 +1274,33 @@ public static boolean contentEquals(final Reader input1, final Reader input2) th try (ScratchChars scratch = IOUtils.ScratchChars.get()) { final char[] array1 = scratch.array(); final char[] array2 = charArray(); - int read1; - int read2; + int pos1; + int pos2; + int count1; + int count2; while (true) { - read1 = input1.read(array1, 0, DEFAULT_BUFFER_SIZE); - read2 = input2.read(array2, 0, DEFAULT_BUFFER_SIZE); - // If both read EOF here, they're equal. - if (read1 == EOF && read2 == EOF) { - return true; - } - // If only one read EOF or different amounts, they're not equal. - if (read1 != read2) { - return false; - } - // Compare the buffers - bulk comparison is faster than character-by-character - for (int i = 0; i < read1; i++) { - if (array1[i] != array2[i]) { + pos1 = 0; + pos2 = 0; + for (int index = 0; index < DEFAULT_BUFFER_SIZE; index++) { + if (pos1 == index) { + do { + count1 = input1.read(array1, pos1, DEFAULT_BUFFER_SIZE - pos1); + } while (count1 == 0); + if (count1 == EOF) { + return pos2 == index && input2.read() == EOF; + } + pos1 += count1; + } + if (pos2 == index) { + do { + count2 = input2.read(array2, pos2, DEFAULT_BUFFER_SIZE - pos2); + } while (count2 == 0); + if (count2 == EOF) { + return pos1 == index && input1.read() == EOF; + } + pos2 += count2; + } + if (array1[index] != array2[index]) { return false; } } @@ -1336,16 +1331,14 @@ private static boolean contentEqualsIgnoreEOL(final BufferedReader reader1, fina } /** - * Compares the contents of two Readers to determine if they are equal or - * not, ignoring EOL characters. + * Compares the contents of two Readers to determine if they are equal or not, ignoring EOL characters. *

    - * This method buffers the input internally using - * {@link BufferedReader} if they are not already buffered. + * This method buffers the input internally using {@link BufferedReader} if they are not already buffered. *

    * * @param reader1 the first reader. * @param reader2 the second reader. - * @return true if the content of the readers are equal (ignoring EOL differences), false otherwise. + * @return true if the content of the readers are equal (ignoring EOL differences), false otherwise. * @throws NullPointerException if either input is null. * @throws UncheckedIOException if an I/O error occurs. * @since 2.2 @@ -1367,17 +1360,16 @@ public static boolean contentEqualsIgnoreEOL(final Reader reader1, final Reader * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    - * Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has completed since - * the correct number of bytes cannot be returned as an int. For large streams use the - * {@link #copyLarge(InputStream, OutputStream)} method. + * Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has completed since the correct number of bytes cannot be returned + * as an int. For large streams use the {@link #copyLarge(InputStream, OutputStream)} method. *

    * - * @param inputStream the {@link InputStream} to read. + * @param inputStream the {@link InputStream} to read. * @param outputStream the {@link OutputStream} to write. * @return the number of bytes copied, or -1 if greater than {@link Integer#MAX_VALUE}. * @throws NullPointerException if the InputStream is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 1.1 */ public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException { @@ -1386,19 +1378,18 @@ public static int copy(final InputStream inputStream, final OutputStream outputS } /** - * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of the - * given size. + * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of the given size. *

    * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param inputStream the {@link InputStream} to read. + * @param inputStream the {@link InputStream} to read. * @param outputStream the {@link OutputStream} to write to. - * @param bufferSize the bufferSize used to copy from the input to the output. + * @param bufferSize the bufferSize used to copy from the input to the output. * @return the number of bytes copied. * @throws NullPointerException if the InputStream is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.5 */ public static long copy(final InputStream inputStream, final OutputStream outputStream, final int bufferSize) throws IOException { @@ -1406,17 +1397,15 @@ public static long copy(final InputStream inputStream, final OutputStream output } /** - * Copies bytes from an {@link InputStream} to chars on a - * {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Copies bytes from an {@link InputStream} to chars on a {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    * This method uses {@link InputStreamReader}. *

    * - * @param input the {@link InputStream} to read. + * @param input the {@link InputStream} to read. * @param writer the {@link Writer} to write to. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. @@ -1429,18 +1418,16 @@ public static void copy(final InputStream input, final Writer writer) throws IOE } /** - * Copies bytes from an {@link InputStream} to chars on a - * {@link Writer} using the specified character encoding. + * Copies bytes from an {@link InputStream} to chars on a {@link Writer} using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    * This method uses {@link InputStreamReader}. *

    * - * @param input the {@link InputStream} to read. - * @param writer the {@link Writer} to write to. + * @param input the {@link InputStream} to read. + * @param writer the {@link Writer} to write to. * @param inputCharset the charset to use for the input stream, null means platform default. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. @@ -1451,22 +1438,19 @@ public static void copy(final InputStream input, final Writer writer, final Char } /** - * Copies bytes from an {@link InputStream} to chars on a - * {@link Writer} using the specified character encoding. + * Copies bytes from an {@link InputStream} to chars on a {@link Writer} using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link InputStreamReader}. *

    * - * @param input the {@link InputStream} to read. - * @param writer the {@link Writer} to write to. + * @param input the {@link InputStream} to read. + * @param writer the {@link Writer} to write to. * @param inputCharsetName the name of the requested charset for the InputStream, null means platform default. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. @@ -1480,8 +1464,7 @@ public static void copy(final InputStream input, final Writer writer, final Stri /** * Copies bytes from a {@link ByteArrayOutputStream} to a {@link QueueInputStream}. *

    - * Unlike using JDK {@link PipedInputStream} and {@link PipedOutputStream} for this, this - * solution works safely in a single thread environment. + * Unlike using JDK {@link PipedInputStream} and {@link PipedOutputStream} for this, this solution works safely in a single thread environment. *

    *

    * Example usage: @@ -1490,14 +1473,13 @@ public static void copy(final InputStream input, final Writer writer, final Stri *

          * ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
          * outputStream.writeBytes("hello world".getBytes(StandardCharsets.UTF_8));
    -     *
          * InputStream inputStream = IOUtils.copy(outputStream);
          * 
    * * @param outputStream the {@link ByteArrayOutputStream} to read. * @return the {@link QueueInputStream} filled with the content of the outputStream. * @throws NullPointerException if the {@link ByteArrayOutputStream} is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.12 */ @SuppressWarnings("resource") // streams are closed by the caller. @@ -1511,14 +1493,11 @@ public static QueueInputStream copy(final java.io.ByteArrayOutputStream outputSt /** * Copies chars from a {@link Reader} to a {@link Appendable}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    *

    - * Large streams (over 2GB) will return a chars copied value of - * {@code -1} after the copy has completed since the correct - * number of chars cannot be returned as an int. For large streams - * use the {@link #copyLarge(Reader, Writer)} method. + * Large streams (over 2GB) will return a chars copied value of {@code -1} after the copy has completed since the correct number of chars cannot be returned + * as an int. For large streams use the {@link #copyLarge(Reader, Writer)} method. *

    * * @param reader the {@link Reader} to read. @@ -1535,8 +1514,7 @@ public static long copy(final Reader reader, final Appendable output) throws IOE /** * Copies chars from a {@link Reader} to an {@link Appendable}. *

    - * This method uses the provided buffer, so there is no need to use a - * {@link BufferedReader}. + * This method uses the provided buffer, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to read. @@ -1559,8 +1537,8 @@ public static long copy(final Reader reader, final Appendable output, final Char } /** - * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default - * charset}, and calling flush. + * Copies chars from a {@link Reader} to bytes on an {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}, + * and calling flush. *

    * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    @@ -1640,14 +1618,11 @@ public static void copy(final Reader reader, final OutputStream output, final St /** * Copies chars from a {@link Reader} to a {@link Writer}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    *

    - * Large streams (over 2GB) will return a chars copied value of - * {@code -1} after the copy has completed since the correct - * number of chars cannot be returned as an int. For large streams - * use the {@link #copyLarge(Reader, Writer)} method. + * Large streams (over 2GB) will return a chars copied value of {@code -1} after the copy has completed since the correct number of chars cannot be returned + * as an int. For large streams use the {@link #copyLarge(Reader, Writer)} method. *

    * * @param reader the {@link Reader} to read. @@ -1674,12 +1649,12 @@ public static int copy(final Reader reader, final Writer writer) throws IOExcept * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. *

    * - * @param url the {@link URL} to read. + * @param url the {@link URL} to read. * @param file the {@link OutputStream} to write. * @return the number of bytes copied. * @throws NullPointerException if the URL is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.9.0 */ public static long copy(final URL url, final File file) throws IOException { @@ -1697,12 +1672,12 @@ public static long copy(final URL url, final File file) throws IOException { * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. *

    * - * @param url the {@link URL} to read. + * @param url the {@link URL} to read. * @param outputStream the {@link OutputStream} to write. * @return the number of bytes copied. * @throws NullPointerException if the URL is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.9.0 */ public static long copy(final URL url, final OutputStream outputStream) throws IOException { @@ -1712,49 +1687,43 @@ public static long copy(final URL url, final OutputStream outputStream) throws I } /** - * Copies bytes from a large (over 2GB) {@link InputStream} to an - * {@link OutputStream}. + * Copies bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. *

    * - * @param inputStream the {@link InputStream} to read. + * @param inputStream the {@link InputStream} to read. * @param outputStream the {@link OutputStream} to write. * @return the number of bytes copied. * @throws NullPointerException if the InputStream is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 1.3 */ - public static long copyLarge(final InputStream inputStream, final OutputStream outputStream) - throws IOException { + public static long copyLarge(final InputStream inputStream, final OutputStream outputStream) throws IOException { return copy(inputStream, outputStream, DEFAULT_BUFFER_SIZE); } /** - * Copies bytes from a large (over 2GB) {@link InputStream} to an - * {@link OutputStream}. + * Copies bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}. *

    - * This method uses the provided buffer, so there is no need to use a - * {@link BufferedInputStream}. + * This method uses the provided buffer, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param inputStream the {@link InputStream} to read. + * @param inputStream the {@link InputStream} to read. * @param outputStream the {@link OutputStream} to write. - * @param buffer the buffer to use for the copy. + * @param buffer the buffer to use for the copy. * @return the number of bytes copied. * @throws NullPointerException if the InputStream is {@code null}. * @throws NullPointerException if the OutputStream is {@code null}. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @since 2.2 */ @SuppressWarnings("resource") // streams are closed by the caller. - public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer) - throws IOException { + public static long copyLarge(final InputStream inputStream, final OutputStream outputStream, final byte[] buffer) throws IOException { Objects.requireNonNull(inputStream, "inputStream"); Objects.requireNonNull(outputStream, "outputStream"); long count = 0; @@ -1767,23 +1736,20 @@ public static long copyLarge(final InputStream inputStream, final OutputStream o } /** - * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an - * {@link OutputStream}, optionally skipping input bytes. + * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input bytes. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    *

    - * Note that the implementation uses {@link #skip(InputStream, long)}. - * This means that the method may be considerably less efficient than using the actual skip implementation, - * this is done to guarantee that the correct number of characters are skipped. + * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual + * skip implementation, this is done to guarantee that the correct number of characters are skipped. *

    * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. * - * @param input the {@link InputStream} to read. - * @param output the {@link OutputStream} to write. + * @param input the {@link InputStream} to read. + * @param output the {@link OutputStream} to write. * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored. - * @param length number of bytes to copy. + * @param length number of bytes to copy. * @return the number of bytes copied. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. @@ -1796,30 +1762,27 @@ public static long copyLarge(final InputStream input, final OutputStream output, } /** - * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an - * {@link OutputStream}, optionally skipping input bytes. + * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an {@link OutputStream}, optionally skipping input bytes. *

    - * This method uses the provided buffer, so there is no need to use a - * {@link BufferedInputStream}. + * This method uses the provided buffer, so there is no need to use a {@link BufferedInputStream}. *

    *

    - * Note that the implementation uses {@link #skip(InputStream, long)}. - * This means that the method may be considerably less efficient than using the actual skip implementation, - * this is done to guarantee that the correct number of characters are skipped. + * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual + * skip implementation, this is done to guarantee that the correct number of characters are skipped. *

    * - * @param input the {@link InputStream} to read. - * @param output the {@link OutputStream} to write. + * @param input the {@link InputStream} to read. + * @param output the {@link OutputStream} to write. * @param inputOffset number of bytes to skip from input before copying, these bytes are ignored. - * @param length number of bytes to copy. - * @param buffer the buffer to use for the copy. + * @param length number of bytes to copy. + * @param buffer the buffer to use for the copy. * @return the number of bytes copied. * @throws NullPointerException if the input or output is null. * @throws IOException if an I/O error occurs. * @since 2.2 */ - public static long copyLarge(final InputStream input, final OutputStream output, - final long inputOffset, final long length, final byte[] buffer) throws IOException { + public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset, final long length, final byte[] buffer) + throws IOException { if (inputOffset > 0) { skipFully(input, inputOffset); } @@ -1847,8 +1810,7 @@ public static long copyLarge(final InputStream input, final OutputStream output, /** * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    *

    * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. @@ -1870,8 +1832,7 @@ public static long copyLarge(final Reader reader, final Writer writer) throws IO /** * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}. *

    - * This method uses the provided buffer, so there is no need to use a - * {@link BufferedReader}. + * This method uses the provided buffer, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to source. @@ -1960,21 +1921,13 @@ public static long copyLarge(final Reader reader, final Writer writer, final lon * Copies up to {@code size} bytes from the given {@link InputStream} into a new {@link UnsynchronizedByteArrayOutputStream}. * * @param input The {@link InputStream} to read; must not be {@code null}. - * @param limit The maximum number of bytes to read; must be {@code >= 0}. - * The actual bytes read are validated to equal {@code size}. + * @param limit The maximum number of bytes to read; must be {@code >= 0}. The actual bytes read are validated to equal {@code size}. * @param bufferSize The buffer size of the output stream; must be {@code > 0}. * @return a ByteArrayOutputStream containing the read bytes. */ - static UnsynchronizedByteArrayOutputStream copyToOutputStream( - final InputStream input, final long limit, final int bufferSize) throws IOException { - try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder() - .setBufferSize(bufferSize) - .get(); - InputStream boundedInput = BoundedInputStream.builder() - .setMaxCount(limit) - .setPropagateClose(false) - .setInputStream(input) - .get()) { + static UnsynchronizedByteArrayOutputStream copyToOutputStream(final InputStream input, final long limit, final int bufferSize) throws IOException { + try (UnsynchronizedByteArrayOutputStream output = UnsynchronizedByteArrayOutputStream.builder().setBufferSize(bufferSize).get(); + InputStream boundedInput = BoundedInputStream.builder().setMaxCount(limit).setPropagateClose(false).setInputStream(input).get()) { output.write(boundedInput); return output; } @@ -2025,31 +1978,29 @@ public static int length(final Object[] array) { } /** - * Returns an Iterator for the lines in an {@link InputStream}, using - * the character encoding specified (or default encoding if null). + * Returns an Iterator for the lines in an {@link InputStream}, using the character encoding specified (or default encoding if null). *

    - * {@link LineIterator} holds a reference to the open - * {@link InputStream} specified here. When you have finished with - * the iterator you should close the stream to free internal resources. - * This can be done by using a try-with-resources block, closing the stream directly, or by calling + * {@link LineIterator} holds a reference to the open {@link InputStream} specified here. When you have finished with the iterator you should close the + * stream to free internal resources. This can be done by using a try-with-resources block, closing the stream directly, or by calling * {@link LineIterator#close()}. *

    *

    * The recommended usage pattern is: *

    + * *
          * try {
    -     *   LineIterator it = IOUtils.lineIterator(stream, charset);
    -     *   while (it.hasNext()) {
    -     *     String line = it.nextLine();
    -     *     /// do something with line
    -     *   }
    +     *     LineIterator it = IOUtils.lineIterator(stream, charset);
    +     *     while (it.hasNext()) {
    +     *         String line = it.nextLine();
    +     *         /// do something with line
    +     *     }
          * } finally {
    -     *   IOUtils.closeQuietly(stream);
    +     *     IOUtils.closeQuietly(stream);
          * }
          * 
    * - * @param input the {@link InputStream} to read, not null. + * @param input the {@link InputStream} to read, not null. * @param charset the charset to use, null means platform default. * @return an Iterator of the lines in the reader, never null. * @throws IllegalArgumentException if the input is null. @@ -2060,31 +2011,29 @@ public static LineIterator lineIterator(final InputStream input, final Charset c } /** - * Returns an Iterator for the lines in an {@link InputStream}, using - * the character encoding specified (or default encoding if null). + * Returns an Iterator for the lines in an {@link InputStream}, using the character encoding specified (or default encoding if null). *

    - * {@link LineIterator} holds a reference to the open - * {@link InputStream} specified here. When you have finished with - * the iterator you should close the stream to free internal resources. - * This can be done by using a try-with-resources block, closing the stream directly, or by calling + * {@link LineIterator} holds a reference to the open {@link InputStream} specified here. When you have finished with the iterator you should close the + * stream to free internal resources. This can be done by using a try-with-resources block, closing the stream directly, or by calling * {@link LineIterator#close()}. *

    *

    * The recommended usage pattern is: *

    + * *
          * try {
    -     *   LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name());
    -     *   while (it.hasNext()) {
    -     *     String line = it.nextLine();
    -     *     /// do something with line
    -     *   }
    +     *     LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name());
    +     *     while (it.hasNext()) {
    +     *         String line = it.nextLine();
    +     *         /// do something with line
    +     *     }
          * } finally {
    -     *   IOUtils.closeQuietly(stream);
    +     *     IOUtils.closeQuietly(stream);
          * }
          * 
    * - * @param input the {@link InputStream} to read, not null. + * @param input the {@link InputStream} to read, not null. * @param charsetName the encoding to use, null means platform default. * @return an Iterator of the lines in the reader, never null. * @throws IllegalArgumentException if the input is null. @@ -2098,24 +2047,22 @@ public static LineIterator lineIterator(final InputStream input, final String ch /** * Returns an Iterator for the lines in a {@link Reader}. *

    - * {@link LineIterator} holds a reference to the open - * {@link Reader} specified here. When you have finished with the - * iterator you should close the reader to free internal resources. - * This can be done by using a try-with-resources block, closing the reader directly, or by calling - * {@link LineIterator#close()}. + * {@link LineIterator} holds a reference to the open {@link Reader} specified here. When you have finished with the iterator you should close the reader to + * free internal resources. This can be done by using a try-with-resources block, closing the reader directly, or by calling {@link LineIterator#close()}. *

    *

    * The recommended usage pattern is: *

    + * *
          * try {
    -     *   LineIterator it = IOUtils.lineIterator(reader);
    -     *   while (it.hasNext()) {
    -     *     String line = it.nextLine();
    -     *     /// do something with line
    -     *   }
    +     *     LineIterator it = IOUtils.lineIterator(reader);
    +     *     while (it.hasNext()) {
    +     *         String line = it.nextLine();
    +     *         /// do something with line
    +     *     }
          * } finally {
    -     *   IOUtils.closeQuietly(reader);
    +     *     IOUtils.closeQuietly(reader);
          * }
          * 
    * @@ -2131,16 +2078,15 @@ public static LineIterator lineIterator(final Reader reader) { /** * Reads bytes from an input stream. *

    - * This implementation guarantees that it will read as many bytes - * as possible before giving up; this may not always be the case for - * subclasses of {@link InputStream}. + * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for subclasses of + * {@link InputStream}. *

    * - * @param input where to read input from. + * @param input where to read input from. * @param buffer destination. * @return actual length read; may be less than requested if EOF was reached. * @throws NullPointerException if {@code input} or {@code buffer} is null. - * @throws IOException if a read error occurs. + * @throws IOException if a read error occurs. * @since 2.2 */ public static int read(final InputStream input, final byte[] buffer) throws IOException { @@ -2150,24 +2096,21 @@ public static int read(final InputStream input, final byte[] buffer) throws IOEx /** * Reads bytes from an input stream. *

    - * This implementation guarantees that it will read as many bytes - * as possible before giving up; this may not always be the case for - * subclasses of {@link InputStream}. + * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for subclasses of + * {@link InputStream}. *

    * - * @param input where to read input. + * @param input where to read input. * @param buffer destination. * @param offset initial offset into buffer. * @param length length to read, must be >= 0. * @return actual length read; may be less than requested if EOF was reached. - * @throws NullPointerException if {@code input} or {@code buffer} is null. - * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if - * {@code offset + length} is greater than {@code buffer.length}. - * @throws IOException if a read error occurs. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if {@code offset + length} is greater than {@code buffer.length}. + * @throws IOException if a read error occurs. * @since 2.2 */ - public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) - throws IOException { + public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { checkFromIndexSize(buffer, offset, length); int remaining = length; while (remaining > 0) { @@ -2184,12 +2127,11 @@ public static int read(final InputStream input, final byte[] buffer, final int o /** * Reads bytes from a ReadableByteChannel. *

    - * This implementation guarantees that it will read as many bytes - * as possible before giving up; this may not always be the case for - * subclasses of {@link ReadableByteChannel}. + * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for subclasses of + * {@link ReadableByteChannel}. *

    * - * @param input the byte channel to read. + * @param input the byte channel to read. * @param buffer byte buffer destination. * @return the actual length read; may be less than requested if EOF was reached. * @throws IOException if a read error occurs. @@ -2209,9 +2151,8 @@ public static int read(final ReadableByteChannel input, final ByteBuffer buffer) /** * Reads characters from an input character stream. *

    - * This implementation guarantees that it will read as many characters - * as possible before giving up; this may not always be the case for - * subclasses of {@link Reader}. + * This implementation guarantees that it will read as many characters as possible before giving up; this may not always be the case for subclasses of + * {@link Reader}. *

    * * @param reader where to read input from. @@ -2227,9 +2168,8 @@ public static int read(final Reader reader, final char[] buffer) throws IOExcept /** * Reads characters from an input character stream. *

    - * This implementation guarantees that it will read as many characters - * as possible before giving up; this may not always be the case for - * subclasses of {@link Reader}. + * This implementation guarantees that it will read as many characters as possible before giving up; this may not always be the case for subclasses of + * {@link Reader}. *

    * * @param reader where to read input from. @@ -2237,14 +2177,12 @@ public static int read(final Reader reader, final char[] buffer) throws IOExcept * @param offset initial offset into buffer. * @param length length to read, must be >= 0. * @return actual length read; may be less than requested if EOF was reached. - * @throws NullPointerException if {@code reader} or {@code buffer} is null. - * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if - * {@code offset + length} is greater than {@code buffer.length}. - * @throws IOException if a read error occurs. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if {@code offset + length} is greater than {@code buffer.length}. + * @throws IOException if a read error occurs. * @since 2.2 */ - public static int read(final Reader reader, final char[] buffer, final int offset, final int length) - throws IOException { + public static int read(final Reader reader, final char[] buffer, final int offset, final int length) throws IOException { checkFromIndexSize(buffer, offset, length); int remaining = length; while (remaining > 0) { @@ -2261,15 +2199,15 @@ public static int read(final Reader reader, final char[] buffer, final int offse /** * Reads the requested number of bytes or fail if there are not enough left. *

    - * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may - * not read as many bytes as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may not read as many bytes as requested (most likely because of reaching + * EOF). *

    * - * @param input where to read input from. + * @param input where to read input from. * @param buffer destination. - * @throws NullPointerException if {@code input} or {@code buffer} is null. - * @throws EOFException if the number of bytes read was incorrect. - * @throws IOException if there is a problem reading the file. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws EOFException if the number of bytes read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final InputStream input, final byte[] buffer) throws IOException { @@ -2279,23 +2217,21 @@ public static void readFully(final InputStream input, final byte[] buffer) throw /** * Reads the requested number of bytes or fail if there are not enough left. *

    - * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may - * not read as many bytes as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may not read as many bytes as requested (most likely because of reaching + * EOF). *

    * - * @param input where to read input from. + * @param input where to read input from. * @param buffer destination. * @param offset initial offset into buffer. * @param length length to read, must be >= 0. - * @throws NullPointerException if {@code input} or {@code buffer} is null. - * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if - * {@code offset + length} is greater than {@code buffer.length}. - * @throws EOFException if the number of bytes read was incorrect. - * @throws IOException if there is a problem reading the file. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if {@code offset + length} is greater than {@code buffer.length}. + * @throws EOFException if the number of bytes read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ - public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) - throws IOException { + public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { final int actual = read(input, buffer, offset, length); if (actual != length) { throw new EOFException("Length to read: " + length + " actual: " + actual); @@ -2305,11 +2241,11 @@ public static void readFully(final InputStream input, final byte[] buffer, final /** * Reads the requested number of bytes or fail if there are not enough left. *

    - * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may - * not read as many bytes as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link InputStream#read(byte[], int, int)} may not read as many bytes as requested (most likely because of reaching + * EOF). *

    * - * @param input where to read input from. + * @param input where to read input from. * @param length length to read, must be >= 0. * @return the bytes read from input. * @throws IOException if there is a problem reading the file. @@ -2326,11 +2262,11 @@ public static byte[] readFully(final InputStream input, final int length) throws /** * Reads the requested number of bytes or fail if there are not enough left. *

    - * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may - * not read as many bytes as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may not read as many bytes as requested (most likely because of + * reaching EOF). *

    * - * @param input the byte channel to read. + * @param input the byte channel to read. * @param buffer byte buffer destination. * @throws IOException if there is a problem reading the file. * @throws EOFException if the number of bytes read was incorrect. @@ -2347,15 +2283,15 @@ public static void readFully(final ReadableByteChannel input, final ByteBuffer b /** * Reads the requested number of characters or fail if there are not enough left. *

    - * This allows for the possibility that {@link Reader#read(char[], int, int)} may - * not read as many characters as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link Reader#read(char[], int, int)} may not read as many characters as requested (most likely because of reaching + * EOF). *

    * * @param reader where to read input from. * @param buffer destination. - * @throws NullPointerException if {@code reader} or {@code buffer} is null. - * @throws EOFException if the number of characters read was incorrect. - * @throws IOException if there is a problem reading the file. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. + * @throws EOFException if the number of characters read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ public static void readFully(final Reader reader, final char[] buffer) throws IOException { @@ -2365,23 +2301,21 @@ public static void readFully(final Reader reader, final char[] buffer) throws IO /** * Reads the requested number of characters or fail if there are not enough left. *

    - * This allows for the possibility that {@link Reader#read(char[], int, int)} may - * not read as many characters as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link Reader#read(char[], int, int)} may not read as many characters as requested (most likely because of reaching + * EOF). *

    * * @param reader where to read input from. * @param buffer destination. * @param offset initial offset into buffer. * @param length length to read, must be >= 0. - * @throws NullPointerException if {@code reader} or {@code buffer} is null. - * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if - * {@code offset + length} is greater than {@code buffer.length}. - * @throws EOFException if the number of characters read was incorrect. - * @throws IOException if there is a problem reading the file. + * @throws NullPointerException if {@code reader} or {@code buffer} is null. + * @throws IndexOutOfBoundsException if {@code offset} or {@code length} is negative, or if {@code offset + length} is greater than {@code buffer.length}. + * @throws EOFException if the number of characters read was incorrect. + * @throws IOException if there is a problem reading the file. * @since 2.2 */ - public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length) - throws IOException { + public static void readFully(final Reader reader, final char[] buffer, final int offset, final int length) throws IOException { final int actual = read(reader, buffer, offset, length); if (actual != length) { throw new EOFException("Length to read: " + length + " actual: " + actual); @@ -2403,11 +2337,10 @@ public static List readLines(final CharSequence csq) throws UncheckedIOE } /** - * Gets the contents of an {@link InputStream} as a list of Strings, - * one entry per line, using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of an {@link InputStream} as a list of Strings, one entry per line, using the virtual machine's {@linkplain Charset#defaultCharset() + * default charset}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * * @param input the {@link InputStream} to read, not null. @@ -2423,14 +2356,12 @@ public static List readLines(final InputStream input) throws UncheckedIO } /** - * Gets the contents of an {@link InputStream} as a list of Strings, - * one entry per line, using the specified character encoding. + * Gets the contents of an {@link InputStream} as a list of Strings, one entry per line, using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input the {@link InputStream} to read, not null. + * @param input the {@link InputStream} to read, not null. * @param charset the charset to use, null means platform default. * @return the list of Strings, never null. * @throws NullPointerException if the input is null. @@ -2442,18 +2373,15 @@ public static List readLines(final InputStream input, final Charset char } /** - * Gets the contents of an {@link InputStream} as a list of Strings, - * one entry per line, using the specified character encoding. + * Gets the contents of an {@link InputStream} as a list of Strings, one entry per line, using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input the {@link InputStream} to read, not null. + * @param input the {@link InputStream} to read, not null. * @param charsetName the name of the requested charset, null means platform default. * @return the list of Strings, never null. * @throws NullPointerException if the input is null. @@ -2466,11 +2394,9 @@ public static List readLines(final InputStream input, final String chars } /** - * Gets the contents of a {@link Reader} as a list of Strings, - * one entry per line. + * Gets the contents of a {@link Reader} as a list of Strings, one entry per line. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to read, not null. @@ -2506,7 +2432,7 @@ public static byte[] resourceToByteArray(final String name) throws IOException { * Delegates to {@link #resourceToURL(String, ClassLoader)}. *

    * - * @param name The resource name. + * @param name The resource name. * @param classLoader the class loader that the resolution of the resource is delegated to. * @return the requested byte array. * @throws IOException if an I/O error occurs or the resource is not found. @@ -2523,7 +2449,7 @@ public static byte[] resourceToByteArray(final String name, final ClassLoader cl * Delegates to {@link #resourceToString(String, Charset, ClassLoader) resourceToString(String, Charset, null)}. *

    * - * @param name The resource name. + * @param name The resource name. * @param charset the charset to use, null means platform default. * @return the requested String. * @throws IOException if an I/O error occurs or the resource is not found. @@ -2540,8 +2466,8 @@ public static String resourceToString(final String name, final Charset charset) * Delegates to {@link #resourceToURL(String, ClassLoader)}. *

    * - * @param name The resource name. - * @param charset the Charset to use, null means platform default. + * @param name The resource name. + * @param charset the Charset to use, null means platform default. * @param classLoader the class loader that the resolution of the resource is delegated to. * @return the requested String. * @throws IOException if an I/O error occurs. @@ -2570,11 +2496,11 @@ public static URL resourceToURL(final String name) throws IOException { /** * Gets a URL pointing to the given resource. *

    - * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call - * {@link Class#getResource(String) IOUtils.class.getResource(name)}. + * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call {@link Class#getResource(String) + * IOUtils.class.getResource(name)}. *

    * - * @param name The resource name. + * @param name The resource name. * @param classLoader Delegate to this class loader if not null. * @return A URL object for reading the resource. * @throws IOException if the resource is not found. @@ -2634,7 +2560,7 @@ public static long skip(final InputStream input, final long skip) throws IOExcep *

    * * @param input byte stream to skip. - * @param skip number of bytes to skip. + * @param skip number of bytes to skip. * @param skipBufferSupplier Supplies the buffer to use for reading. * @return number of bytes actually skipped. * @throws IOException if there is a problem reading the file. @@ -2666,11 +2592,9 @@ public static long skip(final InputStream input, final long skip, final Supplier } /** - * Skips bytes from a ReadableByteChannel. - * This implementation guarantees that it will read as many bytes - * as possible before giving up. + * Skips bytes from a ReadableByteChannel. This implementation guarantees that it will read as many bytes as possible before giving up. * - * @param input ReadableByteChannel to skip. + * @param input ReadableByteChannel to skip. * @param toSkip number of bytes to skip. * @return number of bytes actually skipped. * @throws IOException if there is a problem reading the ReadableByteChannel. @@ -2696,15 +2620,12 @@ public static long skip(final ReadableByteChannel input, final long toSkip) thro } /** - * Skips characters from an input character stream. - * This implementation guarantees that it will read as many characters - * as possible before giving up; this may not always be the case for - * skip() implementations in subclasses of {@link Reader}. + * Skips characters from an input character stream. This implementation guarantees that it will read as many characters as possible before giving up; this + * may not always be the case for skip() implementations in subclasses of {@link Reader}. *

    - * Note that the implementation uses {@link Reader#read(char[], int, int)} rather - * than delegating to {@link Reader#skip(long)}. - * This means that the method may be considerably less efficient than using the actual skip implementation, - * this is done to guarantee that the correct number of characters are skipped. + * Note that the implementation uses {@link Reader#read(char[], int, int)} rather than delegating to {@link Reader#skip(long)}. This means that the method + * may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of characters are + * skipped. *

    * * @param reader character stream to skip. @@ -2738,16 +2659,14 @@ public static long skip(final Reader reader, final long toSkip) throws IOExcepti /** * Skips the requested number of bytes or fail if there are not enough left. *

    - * This allows for the possibility that {@link InputStream#skip(long)} may - * not skip as many bytes as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF). *

    *

    - * Note that the implementation uses {@link #skip(InputStream, long)}. - * This means that the method may be considerably less efficient than using the actual skip implementation, - * this is done to guarantee that the correct number of characters are skipped. + * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual + * skip implementation, this is done to guarantee that the correct number of characters are skipped. *

    * - * @param input stream to skip. + * @param input stream to skip. * @param toSkip the number of bytes to skip. * @throws IOException if there is a problem reading the file. * @throws IllegalArgumentException if toSkip is negative. @@ -2798,7 +2717,7 @@ public static void skipFully(final InputStream input, final long toSkip, final S /** * Skips the requested number of bytes or fail if there are not enough left. * - * @param input ReadableByteChannel to skip. + * @param input ReadableByteChannel to skip. * @param toSkip the number of bytes to skip. * @throws IOException if there is a problem reading the ReadableByteChannel. * @throws IllegalArgumentException if toSkip is negative. @@ -2818,13 +2737,11 @@ public static void skipFully(final ReadableByteChannel input, final long toSkip) /** * Skips the requested number of characters or fail if there are not enough left. *

    - * This allows for the possibility that {@link Reader#skip(long)} may - * not skip as many characters as requested (most likely because of reaching EOF). + * This allows for the possibility that {@link Reader#skip(long)} may not skip as many characters as requested (most likely because of reaching EOF). *

    *

    - * Note that the implementation uses {@link #skip(Reader, long)}. - * This means that the method may be considerably less efficient than using the actual skip implementation, - * this is done to guarantee that the correct number of characters are skipped. + * Note that the implementation uses {@link #skip(Reader, long)}. This means that the method may be considerably less efficient than using the actual skip + * implementation, this is done to guarantee that the correct number of characters are skipped. *

    * * @param reader stream to skip. @@ -2892,8 +2809,7 @@ public static InputStream toBufferedInputStream(final InputStream input, final i } /** - * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given - * reader. + * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader. * * @param reader the reader to wrap or return (not null). * @return the given reader or a new {@link BufferedReader} for the given reader. @@ -2906,11 +2822,10 @@ public static BufferedReader toBufferedReader(final Reader reader) { } /** - * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given - * reader. + * Returns the given reader if it is a {@link BufferedReader}, otherwise creates a BufferedReader from the given reader. * * @param reader the reader to wrap or return (not null). - * @param size the buffer size, if a new BufferedReader is created. + * @param size the buffer size, if a new BufferedReader is created. * @return the given reader or a new {@link BufferedReader} for the given reader. * @throws NullPointerException if the input parameter is null. * @see #buffer(Reader) @@ -2922,16 +2837,15 @@ public static BufferedReader toBufferedReader(final Reader reader, final int siz /** * Reads all the bytes from an input stream in a byte array. - * - *

    The memory used by this method is proportional to the number - * of bytes read, which is only limited by {@link Integer#MAX_VALUE}. Only streams - * which fit into a single byte array with roughly 2 GiB limit can be processed - * with this method.

    + *

    + * The memory used by this method is proportional to the number of bytes read, which is only limited by {@link Integer#MAX_VALUE}. Only + * streams which fit into a single byte array with roughly 2 GiB limit can be processed with this method. + *

    * * @param inputStream The {@link InputStream} to read; must not be {@code null}. * @return A new byte array. - * @throws IOException If an I/O error occurs while reading or if the maximum array size is exceeded. - * @throws NullPointerException If {@code inputStream} is {@code null}. + * @throws IOException If an I/O error occurs while reading or if the maximum array size is exceeded. + * @throws NullPointerException If {@code inputStream} is {@code null}. */ public static byte[] toByteArray(final InputStream inputStream) throws IOException { // Using SOFT_MAX_ARRAY_LENGTH guarantees that size() will not overflow @@ -2944,10 +2858,10 @@ public static byte[] toByteArray(final InputStream inputStream) throws IOExcepti /** * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. - * - *

    This variant always allocates the whole requested array size, - * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, - * which enforces stricter memory usage constraints.

    + *

    + * This variant always allocates the whole requested array size, for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, which + * enforces stricter memory usage constraints. + *

    * * @param input the {@link InputStream} to read; must not be {@code null}. * @param size the exact number of bytes to read; must be {@code >= 0}. @@ -2964,19 +2878,17 @@ public static byte[] toByteArray(final InputStream input, final int size) throws /** * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. + *

    + * The memory used by this method is proportional to the number of bytes read and limited by the specified {@code size}. This makes it + * suitable for processing large input streams, provided that sufficient heap space is available. + *

    + *

    + * This method processes the input stream in successive chunks of up to {@code chunkSize} bytes. + *

    * - *

    The memory used by this method is proportional to the number - * of bytes read and limited by the specified {@code size}. This makes it suitable for - * processing large input streams, provided that sufficient heap space is - * available.

    - * - *

    This method processes the input stream in successive chunks of up to - * {@code chunkSize} bytes.

    - * - * @param input the {@link InputStream} to read; must not be {@code null}. - * @param size the exact number of bytes to read; must be {@code >= 0}. - * The actual bytes read are validated to equal {@code size}. - * @param chunkSize The chunk size for incremental reading; must be {@code > 0}. + * @param input the {@link InputStream} to read; must not be {@code null}. + * @param size the exact number of bytes to read; must be {@code >= 0}. The actual bytes read are validated to equal {@code size}. + * @param chunkSize The chunk size for incremental reading; must be {@code > 0}. * @return a new byte array of length {@code size}. * @throws IllegalArgumentException if {@code size} is negative or {@code chunkSize <= 0}. * @throws EOFException if the stream ends before {@code size} bytes are read. @@ -3003,10 +2915,10 @@ public static byte[] toByteArray(final InputStream input, final int size, final /** * Reads exactly {@code size} bytes from the given {@link InputStream} into a new {@code byte[]}. - * - *

    This variant always allocates the whole requested array size, - * for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, - * which enforces stricter memory usage constraints.

    + *

    + * This variant always allocates the whole requested array size, for a dynamic growing variant use {@link #toByteArray(InputStream, int, int)}, which + * enforces stricter memory usage constraints. + *

    * * @param input the {@link InputStream} to read; must not be {@code null}. * @param size the exact number of bytes to read; must be {@code >= 0} and {@code <= Integer.MAX_VALUE}. @@ -3029,10 +2941,10 @@ public static byte[] toByteArray(final InputStream input, final long size) throw * Gets the contents of an input as a {@code byte[]}. * * @param input the input to read, not null. - * @param size the size of the input to read, where 0 < {@code size} <= length of input. + * @param size the size of the input to read, where 0 < {@code size} <= length of input. * @return byte [] of length {@code size}. - * @throws EOFException if the end of the input is reached before reading {@code size} bytes. - * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}. + * @throws EOFException if the end of the input is reached before reading {@code size} bytes. + * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}. * @throws IllegalArgumentException if {@code size} is less than zero. */ static byte[] toByteArray(final IOTriFunction input, final int size) throws IOException { @@ -3055,11 +2967,9 @@ static byte[] toByteArray(final IOTriFunction } /** - * Gets the contents of a {@link Reader} as a {@code byte[]} - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of a {@link Reader} as a {@code byte[]} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to read. @@ -3074,14 +2984,12 @@ public static byte[] toByteArray(final Reader reader) throws IOException { } /** - * Gets the contents of a {@link Reader} as a {@code byte[]} - * using the specified character encoding. + * Gets the contents of a {@link Reader} as a {@code byte[]} using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * - * @param reader the {@link Reader} to read. + * @param reader the {@link Reader} to read. * @param charset the charset to use, null means platform default. * @return the requested byte array. * @throws NullPointerException if the input is null. @@ -3096,18 +3004,15 @@ public static byte[] toByteArray(final Reader reader, final Charset charset) thr } /** - * Gets the contents of a {@link Reader} as a {@code byte[]} - * using the specified character encoding. + * Gets the contents of a {@link Reader} as a {@code byte[]} using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * - * @param reader the {@link Reader} to read. + * @param reader the {@link Reader} to read. * @param charsetName the name of the requested charset, null means platform default. * @return the requested byte array. * @throws NullPointerException if the input is null. @@ -3120,8 +3025,7 @@ public static byte[] toByteArray(final Reader reader, final String charsetName) } /** - * Gets the contents of a {@link String} as a {@code byte[]} - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of a {@link String} as a {@code byte[]} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    * This is the same as {@link String#getBytes()}. *

    @@ -3171,7 +3075,7 @@ public static byte[] toByteArray(final URL url) throws IOException { * @param urlConnection the {@link URLConnection} to read. * @return the requested byte array. * @throws NullPointerException if the urlConn is null. - * @throws IOException if an I/O exception occurs. + * @throws IOException if an I/O exception occurs. * @since 2.4 */ public static byte[] toByteArray(final URLConnection urlConnection) throws IOException { @@ -3181,11 +3085,9 @@ public static byte[] toByteArray(final URLConnection urlConnection) throws IOExc } /** - * Gets the contents of an {@link InputStream} as a character array - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of an {@link InputStream} as a character array using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * * @param inputStream the {@link InputStream} to read. @@ -3201,37 +3103,31 @@ public static char[] toCharArray(final InputStream inputStream) throws IOExcepti } /** - * Gets the contents of an {@link InputStream} as a character array - * using the specified character encoding. + * Gets the contents of an {@link InputStream} as a character array using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * * @param inputStream the {@link InputStream} to read. - * @param charset the charset to use, null means platform default. + * @param charset the charset to use, null means platform default. * @return the requested character array. * @throws NullPointerException if the input is null. * @throws IOException if an I/O error occurs. * @since 2.3 */ - public static char[] toCharArray(final InputStream inputStream, final Charset charset) - throws IOException { + public static char[] toCharArray(final InputStream inputStream, final Charset charset) throws IOException { final CharArrayWriter writer = new CharArrayWriter(); copy(inputStream, writer, charset); return writer.toCharArray(); } /** - * Gets the contents of an {@link InputStream} as a character array - * using the specified character encoding. + * Gets the contents of an {@link InputStream} as a character array using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * * @param inputStream the {@link InputStream} to read. @@ -3249,8 +3145,7 @@ public static char[] toCharArray(final InputStream inputStream, final String cha /** * Gets the contents of a {@link Reader} as a character array. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to read. @@ -3266,8 +3161,8 @@ public static char[] toCharArray(final Reader reader) throws IOException { } /** - * Converts the specified CharSequence to an input stream, encoded as bytes - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Converts the specified CharSequence to an input stream, encoded as bytes using the virtual machine's {@linkplain Charset#defaultCharset() default + * charset}. * * @param input the CharSequence to convert. * @return an input stream. @@ -3280,10 +3175,9 @@ public static InputStream toInputStream(final CharSequence input) { } /** - * Converts the specified CharSequence to an input stream, encoded as bytes - * using the specified character encoding. + * Converts the specified CharSequence to an input stream, encoded as bytes using the specified character encoding. * - * @param input the CharSequence to convert. + * @param input the CharSequence to convert. * @param charset the charset to use, null means platform default. * @return an input stream. * @since 2.3 @@ -3293,14 +3187,12 @@ public static InputStream toInputStream(final CharSequence input, final Charset } /** - * Converts the specified CharSequence to an input stream, encoded as bytes - * using the specified character encoding. + * Converts the specified CharSequence to an input stream, encoded as bytes using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    * - * @param input the CharSequence to convert. + * @param input the CharSequence to convert. * @param charsetName the name of the requested charset, null means platform default. * @return an input stream. * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. @@ -3311,8 +3203,7 @@ public static InputStream toInputStream(final CharSequence input, final String c } /** - * Converts the specified string to an input stream, encoded as bytes - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Converts the specified string to an input stream, encoded as bytes using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param input the string to convert. * @return an input stream. @@ -3325,10 +3216,9 @@ public static InputStream toInputStream(final String input) { } /** - * Converts the specified string to an input stream, encoded as bytes - * using the specified character encoding. + * Converts the specified string to an input stream, encoded as bytes using the specified character encoding. * - * @param input the string to convert. + * @param input the string to convert. * @param charset the charset to use, null means platform default. * @return an input stream. * @since 2.3 @@ -3338,14 +3228,12 @@ public static InputStream toInputStream(final String input, final Charset charse } /** - * Converts the specified string to an input stream, encoded as bytes - * using the specified character encoding. + * Converts the specified string to an input stream, encoded as bytes using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    * - * @param input the string to convert. + * @param input the string to convert. * @param charsetName the name of the requested charset, null means platform default. * @return an input stream. * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. @@ -3356,8 +3244,7 @@ public static InputStream toInputStream(final String input, final String charset } /** - * Gets the contents of a {@code byte[]} as a String - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of a {@code byte[]} as a String using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. * * @param input the byte array to read. * @return the requested String. @@ -3371,14 +3258,12 @@ public static String toString(final byte[] input) { } /** - * Gets the contents of a {@code byte[]} as a String - * using the specified character encoding. + * Gets the contents of a {@code byte[]} as a String using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    * - * @param input the byte array to read. + * @param input the byte array to read. * @param charsetName the name of the requested charset, null means platform default. * @return the requested String. * @throws NullPointerException if the input is null. @@ -3388,11 +3273,9 @@ public static String toString(final byte[] input, final String charsetName) { } /** - * Gets the contents of an {@link InputStream} as a String - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Gets the contents of an {@link InputStream} as a String using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * * @param input the {@link InputStream} to read. @@ -3407,14 +3290,12 @@ public static String toString(final InputStream input) throws IOException { } /** - * Gets the contents of an {@link InputStream} as a String - * using the specified character encoding. + * Gets the contents of an {@link InputStream} as a String using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input the {@link InputStream} to read. + * @param input the {@link InputStream} to read. * @param charset the charset to use, null means platform default. * @return the requested String. * @throws NullPointerException if the input is null. @@ -3429,38 +3310,32 @@ public static String toString(final InputStream input, final Charset charset) th } /** - * Gets the contents of an {@link InputStream} as a String - * using the specified character encoding. + * Gets the contents of an {@link InputStream} as a String using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input the {@link InputStream} to read. + * @param input the {@link InputStream} to read. * @param charsetName the name of the requested charset, null means platform default. * @return the requested String. * @throws NullPointerException if the input is null. * @throws IOException if an I/O error occurs. * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. */ - public static String toString(final InputStream input, final String charsetName) - throws IOException { + public static String toString(final InputStream input, final String charsetName) throws IOException { return toString(input, Charsets.toCharset(charsetName)); } /** - * Gets the contents of an {@link InputStream} from a supplier as a String - * using the specified character encoding. + * Gets the contents of an {@link InputStream} from a supplier as a String using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input supplies the {@link InputStream} to read. + * @param input supplies the {@link InputStream} to read. * @param charset the charset to use, null means platform default. * @return the requested String. * @throws NullPointerException if the input is null. @@ -3474,15 +3349,13 @@ public static String toString(final IOSupplier input, final Charset } /** - * Gets the contents of an {@link InputStream} from a supplier as a String - * using the specified character encoding. + * Gets the contents of an {@link InputStream} from a supplier as a String using the specified character encoding. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedInputStream}. + * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}. *

    * - * @param input supplies the {@link InputStream} to read. - * @param charset the charset to use, null means platform default. + * @param input supplies the {@link InputStream} to read. + * @param charset the charset to use, null means platform default. * @param defaultString the default return value if the supplier or its value is null. * @return the requested String. * @throws NullPointerException if the input is null. @@ -3501,8 +3374,7 @@ public static String toString(final IOSupplier input, final Charset /** * Gets the contents of a {@link Reader} as a String. *

    - * This method buffers the input internally, so there is no need to use a - * {@link BufferedReader}. + * This method buffers the input internally, so there is no need to use a {@link BufferedReader}. *

    * * @param reader the {@link Reader} to read. @@ -3534,7 +3406,7 @@ public static String toString(final URI uri) throws IOException { /** * Gets the contents at the given URI. * - * @param uri The URI source. + * @param uri The URI source. * @param encoding The encoding name for the URL contents. * @return The contents of the URL as a String. * @throws IOException if an I/O exception occurs. @@ -3547,7 +3419,7 @@ public static String toString(final URI uri, final Charset encoding) throws IOEx /** * Gets the contents at the given URI. * - * @param uri The URI source. + * @param uri The URI source. * @param charsetName The encoding name for the URL contents. * @return The contents of the URL as a String. * @throws IOException if an I/O exception occurs. @@ -3575,7 +3447,7 @@ public static String toString(final URL url) throws IOException { /** * Gets the contents at the given URL. * - * @param url The URL source. + * @param url The URL source. * @param encoding The encoding name for the URL contents. * @return The contents of the URL as a String. * @throws IOException if an I/O exception occurs. @@ -3588,7 +3460,7 @@ public static String toString(final URL url, final Charset encoding) throws IOEx /** * Gets the contents at the given URL. * - * @param url The URL source. + * @param url The URL source. * @param charsetName The encoding name for the URL contents. * @return The contents of the URL as a String. * @throws IOException if an I/O exception occurs. @@ -3608,22 +3480,19 @@ public static String toString(final URL url, final String charsetName) throws IO * @throws IOException if an I/O error occurs. * @since 1.1 */ - public static void write(final byte[] data, final OutputStream output) - throws IOException { + public static void write(final byte[] data, final OutputStream output) throws IOException { if (data != null) { output.write(data); } } /** - * Writes bytes from a {@code byte[]} to chars on a {@link Writer} - * using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Writes bytes from a {@code byte[]} to chars on a {@link Writer} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    * This method uses {@link String#String(byte[])}. *

    * - * @param data the byte array to write, do not modify during output, - * null ignored. + * @param data the byte array to write, do not modify during output, null ignored. * @param writer the {@link Writer} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3636,15 +3505,13 @@ public static void write(final byte[] data, final Writer writer) throws IOExcept } /** - * Writes bytes from a {@code byte[]} to chars on a {@link Writer} - * using the specified character encoding. + * Writes bytes from a {@code byte[]} to chars on a {@link Writer} using the specified character encoding. *

    * This method uses {@link String#String(byte[], String)}. *

    * - * @param data the byte array to write, do not modify during output, - * null ignored. - * @param writer the {@link Writer} to write to. + * @param data the byte array to write, do not modify during output, null ignored. + * @param writer the {@link Writer} to write to. * @param charset the charset to use, null means platform default. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3691,8 +3558,7 @@ public static void write(final byte[] data, final Writer writer, final String ch * @deprecated Use {@link #write(char[], OutputStream, Charset)} instead. */ @Deprecated - public static void write(final char[] data, final OutputStream output) - throws IOException { + public static void write(final char[] data, final OutputStream output) throws IOException { write(data, output, Charset.defaultCharset()); } @@ -3732,8 +3598,7 @@ public static void write(final char[] data, final OutputStream output, final Cha * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @since 1.1 */ - public static void write(final char[] data, final OutputStream output, final String charsetName) - throws IOException { + public static void write(final char[] data, final OutputStream output, final String charsetName) throws IOException { write(data, output, Charsets.toCharset(charsetName)); } @@ -3767,8 +3632,7 @@ public static void write(final char[] data, final Writer writer) throws IOExcept * @deprecated Use {@link #write(CharSequence, OutputStream, Charset)} instead. */ @Deprecated - public static void write(final CharSequence data, final OutputStream output) - throws IOException { + public static void write(final CharSequence data, final OutputStream output) throws IOException { write(data, output, Charset.defaultCharset()); } @@ -3785,8 +3649,7 @@ public static void write(final CharSequence data, final OutputStream output) * @throws IOException if an I/O error occurs. * @since 2.3 */ - public static void write(final CharSequence data, final OutputStream output, final Charset charset) - throws IOException { + public static void write(final CharSequence data, final OutputStream output, final Charset charset) throws IOException { if (data != null) { write(data.toString(), output, charset); } @@ -3809,15 +3672,14 @@ public static void write(final CharSequence data, final OutputStream output, fin * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @since 2.0 */ - public static void write(final CharSequence data, final OutputStream output, final String charsetName) - throws IOException { + public static void write(final CharSequence data, final OutputStream output, final String charsetName) throws IOException { write(data, output, Charsets.toCharset(charsetName)); } /** * Writes chars from a {@link CharSequence} to a {@link Writer}. * - * @param data the {@link CharSequence} to write, null ignored. + * @param data the {@link CharSequence} to write, null ignored. * @param writer the {@link Writer} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3830,13 +3692,12 @@ public static void write(final CharSequence data, final Writer writer) throws IO } /** - * Writes chars from a {@link String} to bytes on an - * {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. + * Writes chars from a {@link String} to bytes on an {@link OutputStream} using the virtual machine's {@linkplain Charset#defaultCharset() default charset}. *

    * This method uses {@link String#getBytes()}. *

    * - * @param data the {@link String} to write, null ignored. + * @param data the {@link String} to write, null ignored. * @param output the {@link OutputStream} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3844,20 +3705,18 @@ public static void write(final CharSequence data, final Writer writer) throws IO * @deprecated Use {@link #write(String, OutputStream, Charset)} instead. */ @Deprecated - public static void write(final String data, final OutputStream output) - throws IOException { + public static void write(final String data, final OutputStream output) throws IOException { write(data, output, Charset.defaultCharset()); } /** - * Writes chars from a {@link String} to bytes on an - * {@link OutputStream} using the specified character encoding. + * Writes chars from a {@link String} to bytes on an {@link OutputStream} using the specified character encoding. *

    * This method uses {@link String#getBytes(String)}. *

    * - * @param data the {@link String} to write, null ignored. - * @param output the {@link OutputStream} to write to. + * @param data the {@link String} to write, null ignored. + * @param output the {@link OutputStream} to write to. * @param charset the charset to use, null means platform default. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3874,33 +3733,30 @@ public static void write(final String data, final OutputStream output, final Cha } /** - * Writes chars from a {@link String} to bytes on an - * {@link OutputStream} using the specified character encoding. + * Writes chars from a {@link String} to bytes on an {@link OutputStream} using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link String#getBytes(String)}. *

    * - * @param data the {@link String} to write, null ignored. - * @param output the {@link OutputStream} to write to. + * @param data the {@link String} to write, null ignored. + * @param output the {@link OutputStream} to write to. * @param charsetName the name of the requested charset, null means platform default. - * @throws NullPointerException if output is null. - * @throws IOException if an I/O error occurs. + * @throws NullPointerException if output is null. + * @throws IOException if an I/O error occurs. * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @since 1.1 */ - public static void write(final String data, final OutputStream output, final String charsetName) - throws IOException { + public static void write(final String data, final OutputStream output, final String charsetName) throws IOException { write(data, output, Charsets.toCharset(charsetName)); } /** * Writes chars from a {@link String} to a {@link Writer}. * - * @param data the {@link String} to write, null ignored. + * @param data the {@link String} to write, null ignored. * @param writer the {@link Writer} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3913,14 +3769,12 @@ public static void write(final String data, final Writer writer) throws IOExcept } /** - * Writes chars from a {@link StringBuffer} to bytes on an - * {@link OutputStream} using the default character encoding of the - * platform. + * Writes chars from a {@link StringBuffer} to bytes on an {@link OutputStream} using the default character encoding of the platform. *

    * This method uses {@link String#getBytes()}. *

    * - * @param data the {@link StringBuffer} to write, null ignored. + * @param data the {@link StringBuffer} to write, null ignored. * @param output the {@link OutputStream} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3928,34 +3782,32 @@ public static void write(final String data, final Writer writer) throws IOExcept * @deprecated Use {@link #write(CharSequence, OutputStream)}. */ @Deprecated - public static void write(final StringBuffer data, final OutputStream output) //NOSONAR + public static void write(final StringBuffer data, final OutputStream output) // NOSONAR throws IOException { write(data, output, (String) null); } /** - * Writes chars from a {@link StringBuffer} to bytes on an - * {@link OutputStream} using the specified character encoding. + * Writes chars from a {@link StringBuffer} to bytes on an {@link OutputStream} using the specified character encoding. *

    - * Character encoding names can be found at - * IANA. + * Character encoding names can be found at IANA. *

    *

    * This method uses {@link String#getBytes(String)}. *

    * - * @param data the {@link StringBuffer} to write, null ignored. - * @param output the {@link OutputStream} to write to. + * @param data the {@link StringBuffer} to write, null ignored. + * @param output the {@link OutputStream} to write to. * @param charsetName the name of the requested charset, null means platform default. - * @throws NullPointerException if output is null. - * @throws IOException if an I/O error occurs. + * @throws NullPointerException if output is null. + * @throws IOException if an I/O error occurs. * @throws java.nio.charset.UnsupportedCharsetException if the encoding is not supported. * @since 1.1 * @deprecated Use {@link #write(CharSequence, OutputStream, String)}. */ @Deprecated - public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR - throws IOException { + public static void write(final StringBuffer data, final OutputStream output, final String charsetName) // NOSONAR + throws IOException { if (data != null) { write(data.toString(), output, Charsets.toCharset(charsetName)); } @@ -3964,7 +3816,7 @@ public static void write(final StringBuffer data, final OutputStream output, fin /** * Writes chars from a {@link StringBuffer} to a {@link Writer}. * - * @param data the {@link StringBuffer} to write, null ignored. + * @param data the {@link StringBuffer} to write, null ignored. * @param writer the {@link Writer} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. @@ -3972,7 +3824,7 @@ public static void write(final StringBuffer data, final OutputStream output, fin * @deprecated Use {@link #write(CharSequence, Writer)}. */ @Deprecated - public static void write(final StringBuffer data, final Writer writer) //NOSONAR + public static void write(final StringBuffer data, final Writer writer) // NOSONAR throws IOException { if (data != null) { writer.write(data.toString()); @@ -3980,19 +3832,16 @@ public static void write(final StringBuffer data, final Writer writer) //NOSONAR } /** - * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes. - * This is intended for writing very large byte arrays which might otherwise cause excessive - * memory usage if the native code has to allocate a copy. + * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes. This is intended for writing very large byte arrays which might + * otherwise cause excessive memory usage if the native code has to allocate a copy. * - * @param data the byte array to write, do not modify during output, - * null ignored. + * @param data the byte array to write, do not modify during output, null ignored. * @param output the {@link OutputStream} to write to. * @throws NullPointerException if output is null. * @throws IOException if an I/O error occurs. * @since 2.5 */ - public static void writeChunked(final byte[] data, final OutputStream output) - throws IOException { + public static void writeChunked(final byte[] data, final OutputStream output) throws IOException { if (data != null) { int bytes = data.length; int offset = 0; @@ -4126,11 +3975,10 @@ public static void writeLines(final Collection lines, String lineEnding, fina } /** - * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the - * given Appendable. + * Returns the given Appendable if it is already a {@link Writer}, otherwise creates a Writer wrapper around the given Appendable. * * @param appendable the Appendable to wrap or return (not null). - * @return the given Appendable or a Writer wrapper around the given Appendable. + * @return the given Appendable or a Writer wrapper around the given Appendable. * @throws NullPointerException if the input parameter is null. * @since 2.7 */ @@ -4151,8 +3999,7 @@ public static Writer writer(final Appendable appendable) { * @deprecated TODO Make private in 3.0. */ @Deprecated - public IOUtils() { //NOSONAR + public IOUtils() { // NOSONAR // empty } - } diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 5684bf09470..12017ce5aab 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.commons.io; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -76,6 +77,7 @@ import org.apache.commons.io.function.IOConsumer; import org.apache.commons.io.input.BrokenInputStream; import org.apache.commons.io.input.CharSequenceInputStream; +import org.apache.commons.io.input.ChunkedReader; import org.apache.commons.io.input.CircularInputStream; import org.apache.commons.io.input.NullInputStream; import org.apache.commons.io.input.NullReader; @@ -540,18 +542,6 @@ void testCloseQuietly_AllCloseableIOException() { assertDoesNotThrow(() -> IOUtils.closeQuietly((Iterable) null)); } - @SuppressWarnings("resource") - @Test - void testCloseQuietly_CloseableIOExceptionAddSuppressed() { - final Throwable e = new Exception("test").fillInStackTrace(); - assertEquals(0, e.getSuppressed().length); - assertSame(e, IOUtils.closeQuietly(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); - assertEquals(1, e.getSuppressed().length); - final Throwable suppressed0 = e.getSuppressed()[0]; - assertInstanceOf(EOFException.class, suppressed0); - assertEquals("Suppressed", suppressed0.getMessage()); - } - @Test void testCloseQuietly_CloseableException() { // IOException @@ -589,6 +579,18 @@ void testCloseQuietly_CloseableExceptionConsumer() { assertTrue(b.get()); } + @SuppressWarnings("resource") + @Test + void testCloseQuietly_CloseableIOExceptionAddSuppressed() { + final Throwable e = new Exception("test").fillInStackTrace(); + assertEquals(0, e.getSuppressed().length); + assertSame(e, IOUtils.closeQuietly(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); + assertEquals(1, e.getSuppressed().length); + final Throwable suppressed0 = e.getSuppressed()[0]; + assertInstanceOf(EOFException.class, suppressed0); + assertEquals("Suppressed", suppressed0.getMessage()); + } + @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testCloseQuietly_Selector() { @@ -781,9 +783,7 @@ void testContentEquals_InputStream_InputStream() throws Exception { @Test void testContentEquals_Reader_Reader() throws Exception { - { - assertTrue(IOUtils.contentEquals((Reader) null, null)); - } + assertTrue(IOUtils.contentEquals((Reader) null, null)); { final StringReader input1 = new StringReader(""); assertFalse(IOUtils.contentEquals(null, input1)); @@ -801,14 +801,23 @@ void testContentEquals_Reader_Reader() throws Exception { assertTrue(IOUtils.contentEquals(input1, input1)); } assertTrue(IOUtils.contentEquals(new StringReader(""), new StringReader(""))); - assertTrue( - IOUtils.contentEquals(new BufferedReader(new StringReader("")), new BufferedReader(new StringReader("")))); + assertTrue(IOUtils.contentEquals(new BufferedReader(new StringReader("")), new BufferedReader(new StringReader("")))); assertTrue(IOUtils.contentEquals(new StringReader("ABC"), new StringReader("ABC"))); assertFalse(IOUtils.contentEquals(new StringReader("ABCD"), new StringReader("ABC"))); assertFalse(IOUtils.contentEquals(new StringReader("ABC"), new StringReader("ABCD"))); assertFalse(IOUtils.contentEquals(new StringReader("apache"), new StringReader("apacha"))); } + @Test + void testContentEquals_Reader_Reader_unevenReads() throws Exception { + // sanity test, same chunk size + assertFalse(IOUtils.contentEquals(new ChunkedReader(new StringReader("apache"), 1000), new ChunkedReader(new StringReader("apacha"), 1000))); + assertTrue(IOUtils.contentEquals(new ChunkedReader(new StringReader("ABC"), 1000), new ChunkedReader(new StringReader("ABC"), 1000))); + // test with uneven chunk sizes + assertTrue(IOUtils.contentEquals(new ChunkedReader(new StringReader("ABC"), 1), new ChunkedReader(new StringReader("ABC"), 2))); + assertFalse(IOUtils.contentEquals(new ChunkedReader(new StringReader("apache"), 1), new ChunkedReader(new StringReader("apacha"), 2))); + } + @Test void testContentEqualsIgnoreEOL() throws Exception { { diff --git a/src/test/java/org/apache/commons/io/input/ChunkedReader.java b/src/test/java/org/apache/commons/io/input/ChunkedReader.java new file mode 100644 index 00000000000..7e6fd27363c --- /dev/null +++ b/src/test/java/org/apache/commons/io/input/ChunkedReader.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.input; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; + +/** + * Reader that limits the number of characters read in a chunk of the specified size or less. + */ +public class ChunkedReader extends FilterReader { + + private final int chunkSize; + + public ChunkedReader(final Reader reader, final int chunkSize) { + super(reader); + if (chunkSize <= 0) { + throw new IllegalArgumentException("chunkSize must be > 0"); + } + this.chunkSize = chunkSize; + } + + @Override + public void close() throws IOException { + // nothing to do. + } + + @Override + public int read(final char[] cbuf, final int off, final int len) throws IOException { + return super.read(cbuf, off, len > chunkSize ? chunkSize : len); + } + +} \ No newline at end of file From 2862268d9024d3377f9dc50b50a5b29b6247ab17 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 21 Jan 2026 07:15:28 -0500 Subject: [PATCH 136/174] Bump commons.rc.version from RC1 to RC2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6a0b4c053df..df301d46c13 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,7 @@ file comparators, endian transformation classes, and much more. 1.8 io org.apache.commons.io - RC1 + RC2 2.21.0 2.22.0 2.22.1 From 1fe472cf10ab38797830ea6943d7eb3e13393d98 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 21 Jan 2026 07:19:37 -0500 Subject: [PATCH 137/174] Bump commons.bytebuddy.version from 1.18.3 to 1.18.4 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index df301d46c13..d10511548d0 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ file comparators, endian transformation classes, and much more. https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-io/ site-content - 1.18.3 + 1.18.4 false true diff --git a/src/changes/changes.xml b/src/changes/changes.xml index dc1e4972998..4e9448904a5 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,7 +56,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 91 to 95 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. - Bump commons.bytebuddy.version from 1.17.8 to 1.18.3 #814, #820. + Bump commons.bytebuddy.version from 1.17.8 to 1.18.4 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From a207334e26e2c0b34f93929ff7d421ade35d644a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 21 Jan 2026 17:12:09 -0500 Subject: [PATCH 138/174] Bump org.apache.commons:commons-parent from 95 to 96 --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d10511548d0..86fbb10676b 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.apache.commons commons-parent - 95 + 96 4.0.0 commons-io diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 4e9448904a5..fc7f1f3c9ca 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,7 +54,7 @@ The type attribute can be add,update,fix,remove. Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. - Bump org.apache.commons:commons-parent from 91 to 95 #816. + Bump org.apache.commons:commons-parent from 91 to 96 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.4 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From 283db9f375ca9cd015fc986394639bba23ad2cff Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 22 Jan 2026 15:39:40 +0000 Subject: [PATCH 139/174] Bump actions/setup-java from 5.1.0 to 5.2.0 --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b5daa9a6ee6..3ebde531b94 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -70,7 +70,7 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: distribution: ${{ runner.os == 'macOS' && matrix.java == '8' && 'zulu' || 'temurin' }} java-version: ${{ matrix.java }} From 3901b51c00f481a691ef292a8b78be63d089c6c8 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 22 Jan 2026 17:20:12 -0500 Subject: [PATCH 140/174] Add IOUtilsTest.testToByteArray_InputStream_Empty() Debugging Jadler... --- .../org/apache/commons/io/IOUtilsTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 12017ce5aab..46985353573 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -75,12 +75,14 @@ import java.util.stream.Stream; import org.apache.commons.io.function.IOConsumer; +import org.apache.commons.io.input.BoundedInputStream; import org.apache.commons.io.input.BrokenInputStream; import org.apache.commons.io.input.CharSequenceInputStream; import org.apache.commons.io.input.ChunkedReader; import org.apache.commons.io.input.CircularInputStream; import org.apache.commons.io.input.NullInputStream; import org.apache.commons.io.input.NullReader; +import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; import org.apache.commons.io.output.AppendableWriter; import org.apache.commons.io.output.BrokenOutputStream; import org.apache.commons.io.output.CountingOutputStream; @@ -90,6 +92,7 @@ import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.commons.io.test.TestUtils; import org.apache.commons.io.test.ThrowOnCloseReader; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.JavaVersion; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; @@ -1743,6 +1746,22 @@ void testToByteArray_InputStream() throws Exception { } } + @Test + void testToByteArray_InputStream_Empty() throws Exception { + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, IOUtils.toByteArray(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY))); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, + IOUtils.toByteArray(BoundedInputStream.builder().setInputStream(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)).get())); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, + IOUtils.toByteArray(UnsynchronizedByteArrayInputStream.builder().setInputStream(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)).get())); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, + IOUtils.toByteArray(BoundedInputStream.builder().setInputStream(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)).setMaxCount(1).get())); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, IOUtils.toByteArray(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY))); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, + IOUtils.toByteArray(BoundedInputStream.builder().setInputStream(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)).get())); + assertArrayEquals(ArrayUtils.EMPTY_BYTE_ARRAY, + IOUtils.toByteArray(BoundedInputStream.builder().setInputStream(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY)).setMaxCount(0).get())); + } + @Test @Disabled("Disable by default as it uses too much memory and can cause builds to fail.") void testToByteArray_InputStream_LongerThanIntegerMaxValue() throws Exception { From 7bc386f86cf10469cf39d3b5a96508208ebe924a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 23 Jan 2026 07:18:02 -0500 Subject: [PATCH 141/174] Add JUnit assertions --- .../org/apache/commons/io/IOUtilsTest.java | 30 ++++++++++--------- .../apache/commons/io/input/TailerTest.java | 7 +++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 46985353573..6c16a4b1840 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -580,6 +580,9 @@ void testCloseQuietly_CloseableExceptionConsumer() { // RuntimeException subclass assertDoesNotThrow(() -> IOUtils.closeQuietly(new BrokenOutputStream(new UnsupportedOperationException()), consumer)); assertTrue(b.get()); + // in-line + assertDoesNotThrow(() -> IOUtils.closeQuietly(new BrokenOutputStream(new UnsupportedOperationException()), (Consumer) e -> b.set(true))); + assertTrue(b.get()); } @SuppressWarnings("resource") @@ -594,7 +597,6 @@ void testCloseQuietly_CloseableIOExceptionAddSuppressed() { assertEquals("Suppressed", suppressed0.getMessage()); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testCloseQuietly_Selector() { Selector selector = null; @@ -604,9 +606,9 @@ void testCloseQuietly_Selector() { } finally { IOUtils.closeQuietly(selector); } + assertFalse(selector.isOpen()); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testCloseQuietly_SelectorIOException() { final Selector selector = new SelectorAdapter() { @@ -616,7 +618,8 @@ public void close() throws IOException { } }; IOUtils.closeQuietly(selector); - } + assertFalse(selector.isOpen()); +} @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test @@ -625,7 +628,6 @@ void testCloseQuietly_SelectorNull() { IOUtils.closeQuietly(selector); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testCloseQuietly_SelectorTwice() { Selector selector = null; @@ -636,12 +638,15 @@ void testCloseQuietly_SelectorTwice() { IOUtils.closeQuietly(selector); IOUtils.closeQuietly(selector); } + assertFalse(selector.isOpen()); } @Test - void testCloseQuietly_ServerSocket() { + void testCloseQuietly_ServerSocket() throws IOException { assertDoesNotThrow(() -> IOUtils.closeQuietly((ServerSocket) null)); - assertDoesNotThrow(() -> IOUtils.closeQuietly(new ServerSocket())); + final ServerSocket serverSocket = new ServerSocket(); + IOUtils.closeQuietly(serverSocket); + assertTrue(serverSocket.isClosed()); } @Test @@ -659,7 +664,9 @@ public void close() throws IOException { @Test void testCloseQuietly_Socket() { assertDoesNotThrow(() -> IOUtils.closeQuietly((Socket) null)); - assertDoesNotThrow(() -> IOUtils.closeQuietly(new Socket())); + final Socket socket = new Socket(); + IOUtils.closeQuietly(socket); + assertTrue(socket.isClosed()); } @Test @@ -704,13 +711,10 @@ void testConsumeInputStream() throws Exception { final long size = (long) Integer.MAX_VALUE + (long) 1; final NullInputStream in = new NullInputStream(size); final OutputStream out = NullOutputStream.INSTANCE; - // Test copy() method assertEquals(-1, IOUtils.copy(in, out)); - // reset the input in.init(); - // Test consume() method assertEquals(size, IOUtils.consume(in), "consume()"); } @@ -1491,16 +1495,14 @@ void testResourceToString_NonExistingResource_WithClassLoader() { ClassLoader.getSystemClassLoader())); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testResourceToString_NullCharset() throws Exception { - IOUtils.resourceToString("/org/apache/commons/io//test-file-utf8.bin", null); + assertNotNull(IOUtils.resourceToString("/org/apache/commons/io//test-file-utf8.bin", null)); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testResourceToString_NullCharset_WithClassLoader() throws Exception { - IOUtils.resourceToString("org/apache/commons/io/test-file-utf8.bin", null, ClassLoader.getSystemClassLoader()); + assertNotNull(IOUtils.resourceToString("org/apache/commons/io/test-file-utf8.bin", null, ClassLoader.getSystemClassLoader())); } @Test diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java index dcada2f8f3f..8455dc84deb 100644 --- a/src/test/java/org/apache/commons/io/input/TailerTest.java +++ b/src/test/java/org/apache/commons/io/input/TailerTest.java @@ -231,17 +231,18 @@ private List expectLinesWithLongTimeout(final TestTailerListener listene } @Test - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" void testBufferBreak() throws Exception { final long delay = 50; final File file = new File(temporaryFolder, "testBufferBreak.txt"); createFile(file, 0); - writeStrings(file, "SBTOURIST\n"); + final String data = "SBTOURIST\n"; + writeStrings(file, data); final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = new Tailer(file, listener, delay, false, 1)) { final Thread thread = new Thread(tailer); thread.start(); List lines = listener.getLines(); + assertEquals(data.length(), tailer.getTailable().size()); while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { lines = listener.getLines(); } @@ -386,7 +387,6 @@ void testIO335() throws Exception { // test CR behavior } @Test - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" void testLongFile() throws Exception { final long delay = 50; final File file = new File(temporaryFolder, "testLongFile.txt"); @@ -407,6 +407,7 @@ void testLongFile() throws Exception { lines = listener.getLines(); } // System.out.println("Elapsed: " + (System.currentTimeMillis() - start)); + assertFalse(lines.isEmpty()); listener.clear(); } } From a9a571d2729c1556e906810bc60af09357c0793d Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 23 Jan 2026 07:41:55 -0500 Subject: [PATCH 142/174] Bump actions/checkout from 6.0.1 to 6.0.2 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/maven.yml | 2 +- .github/workflows/scorecards-analysis.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5d024662b1f..6a5db14e0e4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,7 +50,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 1df86660448..a04da50909a 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -26,6 +26,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 'Dependency Review PR' uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3ebde531b94..f596ab8bef1 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -60,7 +60,7 @@ jobs: experimental: true fail-fast: false steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 2d7a1b0f8bc..dd582b61b44 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -42,7 +42,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false From f8e233273f7775a77a435b246cf8147c2468a802 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 24 Jan 2026 13:10:20 -0500 Subject: [PATCH 143/174] Rename new method --- .../java/org/apache/commons/io/FileUtils.java | 2 +- .../java/org/apache/commons/io/IOUtils.java | 64 +++++++++---------- .../org/apache/commons/io/LineIterator.java | 2 +- .../io/output/FileWriterWithEncoding.java | 2 +- .../org/apache/commons/io/IOUtilsTest.java | 4 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index d340a2baadc..9c85e9d281e 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -2290,7 +2290,7 @@ public static LineIterator lineIterator(final File file, final String charsetNam inputStream = Files.newInputStream(file.toPath()); return IOUtils.lineIterator(inputStream, charsetName); } catch (final IOException | RuntimeException ex) { - IOUtils.closeQuietly(inputStream, ex); + IOUtils.closeQuietlyAdd(inputStream, ex); throw ex; } } diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index b3d73648f02..da6d3e00ddb 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -823,38 +823,6 @@ public static void closeQuietly(final Closeable closeable) { closeQuietly(closeable, (Consumer) null); } - /** - * Closes a {@link Closeable} unconditionally and adds any exception thrown by the {@code close()} to the given Throwable. - *

    - * For example: - *

    - * - *
    -     * Closeable closeable = ...;
    -     * try {
    -     *     // process closeable
    -     *     closeable.close();
    -     * } catch (Exception e) {
    -     *     // error handling
    -     *     throw IOUtils.closeQuietly(closeable, e);
    -     * }
    -     * 
    - *

    - * Also consider using a try-with-resources statement where appropriate. - *

    - * - * @param The Throwable type. - * @param closeable The object to close, may be null or already closed. - * @param throwable Add the exception throw by the closeable to the given Throwable. - * @return The given Throwable. - * @since 2.22.0 - * @see Throwable#addSuppressed(Throwable) - */ - public static T closeQuietly(final Closeable closeable, final T throwable) { - closeQuietly(closeable, (Consumer) throwable::addSuppressed); - return throwable; - } - /** * Closes a {@link Closeable} unconditionally. *

    @@ -1185,6 +1153,38 @@ public static void closeQuietly(final Writer writer) { closeQ(writer); } + /** + * Closes a {@link Closeable} unconditionally and adds any exception thrown by the {@code close()} to the given Throwable. + *

    + * For example: + *

    + * + *
    +     * Closeable closeable = ...;
    +     * try {
    +     *     // process closeable
    +     *     closeable.close();
    +     * } catch (Exception e) {
    +     *     // error handling
    +     *     throw IOUtils.closeQuietly(closeable, e);
    +     * }
    +     * 
    + *

    + * Also consider using a try-with-resources statement where appropriate. + *

    + * + * @param The Throwable type. + * @param closeable The object to close, may be null or already closed. + * @param throwable Add the exception throw by the closeable to the given Throwable. + * @return The given Throwable. + * @since 2.22.0 + * @see Throwable#addSuppressed(Throwable) + */ + public static T closeQuietlyAdd(final Closeable closeable, final T throwable) { + closeQuietly(closeable, (Consumer) throwable::addSuppressed); + return throwable; + } + /** * Consumes bytes from a {@link InputStream} and ignores them. *

    diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index 741eae08ddc..5b7f531e71e 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -135,7 +135,7 @@ public boolean hasNext() { } } } catch (final IOException ioe) { - throw new IllegalStateException(IOUtils.closeQuietly(this, ioe)); + throw new IllegalStateException(IOUtils.closeQuietlyAdd(this, ioe)); } } 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 1bb15a37a19..8d3f4fc6fc8 100644 --- a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java +++ b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java @@ -188,7 +188,7 @@ private static OutputStreamWriter initWriter(final File file, final Object encod } return new OutputStreamWriter(outputStream, (String) encoding); } catch (final IOException | RuntimeException ex) { - IOUtils.closeQuietly(outputStream, ex); + IOUtils.closeQuietlyAdd(outputStream, ex); if (!fileExistedAlready) { FileUtils.deleteQuietly(file); } diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 6c16a4b1840..082d5960d87 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -581,7 +581,7 @@ void testCloseQuietly_CloseableExceptionConsumer() { assertDoesNotThrow(() -> IOUtils.closeQuietly(new BrokenOutputStream(new UnsupportedOperationException()), consumer)); assertTrue(b.get()); // in-line - assertDoesNotThrow(() -> IOUtils.closeQuietly(new BrokenOutputStream(new UnsupportedOperationException()), (Consumer) e -> b.set(true))); + assertDoesNotThrow(() -> IOUtils.closeQuietly(new BrokenOutputStream(new UnsupportedOperationException()), e -> b.set(true))); assertTrue(b.get()); } @@ -590,7 +590,7 @@ void testCloseQuietly_CloseableExceptionConsumer() { void testCloseQuietly_CloseableIOExceptionAddSuppressed() { final Throwable e = new Exception("test").fillInStackTrace(); assertEquals(0, e.getSuppressed().length); - assertSame(e, IOUtils.closeQuietly(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); + assertSame(e, IOUtils.closeQuietlyAdd(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); assertEquals(1, e.getSuppressed().length); final Throwable suppressed0 = e.getSuppressed()[0]; assertInstanceOf(EOFException.class, suppressed0); From 60a5f989182d9b07d6650457b81764eb4893a240 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 25 Jan 2026 09:19:30 -0500 Subject: [PATCH 144/174] Sort members --- ...eArraySeekableByteChannelCompressTest.java | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java index 60c294f0d65..26281d4e08b 100644 --- a/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java +++ b/src/test/java/org/apache/commons/io/channels/ByteArraySeekableByteChannelCompressTest.java @@ -161,43 +161,6 @@ void testShouldThrowExceptionOnWritingToClosedChannel() { assertThrows(ClosedChannelException.class, () -> c.write(ByteBuffer.allocate(1))); } - @Test - void testThrowWhenSettingIncorrectPosition() throws IOException { - try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - final ByteBuffer buffer = ByteBuffer.allocate(1); - // write - c.write(buffer); - assertEquals(1, c.position()); - // bad pos A - c.position(c.size() + 1); - assertEquals(c.size() + 1, c.position()); - assertEquals(-1, c.read(buffer)); - // bad pos B - c.position(Integer.MAX_VALUE + 1L); - assertEquals(Integer.MAX_VALUE + 1L, c.position()); - assertEquals(-1, c.read(buffer)); - assertThrows(IOException.class, () -> c.write(buffer)); - // negative input is the only illegal input - assertThrows(IllegalArgumentException.class, () -> c.position(-1)); - assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MIN_VALUE)); - assertThrows(IllegalArgumentException.class, () -> c.position(Long.MIN_VALUE)); - } - } - - @Test - void testThrowWhenTruncatingToIncorrectSize() throws IOException { - try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - final ByteBuffer buffer = ByteBuffer.allocate(1); - c.truncate(c.size() + 1); - assertEquals(-1, c.read(buffer)); - c.truncate(Integer.MAX_VALUE + 1L); - assertEquals(-1, c.read(buffer)); - assertThrows(IllegalArgumentException.class, () -> c.truncate(-1)); - assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MIN_VALUE)); - assertThrows(IllegalArgumentException.class, () -> c.truncate(Long.MIN_VALUE)); - } - } - @Test void testShouldTruncateContentsProperly() throws ClosedChannelException { try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) { @@ -267,6 +230,43 @@ void testThrowsIOExceptionWhenPositionIsSetToANegativeValue() throws Exception { } } + @Test + void testThrowWhenSettingIncorrectPosition() throws IOException { + try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { + final ByteBuffer buffer = ByteBuffer.allocate(1); + // write + c.write(buffer); + assertEquals(1, c.position()); + // bad pos A + c.position(c.size() + 1); + assertEquals(c.size() + 1, c.position()); + assertEquals(-1, c.read(buffer)); + // bad pos B + c.position(Integer.MAX_VALUE + 1L); + assertEquals(Integer.MAX_VALUE + 1L, c.position()); + assertEquals(-1, c.read(buffer)); + assertThrows(IOException.class, () -> c.write(buffer)); + // negative input is the only illegal input + assertThrows(IllegalArgumentException.class, () -> c.position(-1)); + assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> c.position(Long.MIN_VALUE)); + } + } + + @Test + void testThrowWhenTruncatingToIncorrectSize() throws IOException { + try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { + final ByteBuffer buffer = ByteBuffer.allocate(1); + c.truncate(c.size() + 1); + assertEquals(-1, c.read(buffer)); + c.truncate(Integer.MAX_VALUE + 1L); + assertEquals(-1, c.read(buffer)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(-1)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> c.truncate(Long.MIN_VALUE)); + } + } + /* * In either case, if the current position is greater than the given size then it is set to that size. */ From 9c6ed7a9eac10baa9b124fd9b9938dee7514cb5e Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 25 Jan 2026 09:30:29 -0500 Subject: [PATCH 145/174] Merge if expressions that have the same true block Reduce vertical whitespace --- .../org/apache/commons/io/FilenameUtils.java | 69 ++++--------------- .../commons/io/channels/FileChannels.java | 5 +- .../commons/io/input/BoundedReader.java | 9 +-- .../input/BufferedFileChannelInputStream.java | 5 +- .../commons/io/input/XmlStreamReader.java | 6 +- .../input/compatibility/XmlStreamReader.java | 7 +- 6 files changed, 17 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java index c3a2a2dcfa5..416720a02f8 100644 --- a/src/main/java/org/apache/commons/io/FilenameUtils.java +++ b/src/main/java/org/apache/commons/io/FilenameUtils.java @@ -282,17 +282,11 @@ public static String concat(final String basePath, final String fullFileNameToAd * @see FileUtils#directoryContains(File, File) */ public static boolean directoryContains(final String canonicalParent, final String canonicalChild) { - if (isEmpty(canonicalParent) || isEmpty(canonicalChild)) { + if (isEmpty(canonicalParent) || isEmpty(canonicalChild) || IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) { return false; } - - if (IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) { - return false; - } - final char separator = toSeparator(canonicalParent.charAt(0) == UNIX_NAME_SEPARATOR); final String parentWithEndSeparator = canonicalParent.charAt(canonicalParent.length() - 1) == separator ? canonicalParent : canonicalParent + separator; - return IOCase.SYSTEM.checkStartsWith(canonicalChild, parentWithEndSeparator); } @@ -366,9 +360,7 @@ private static String doNormalize(final String fileName, final char separator, f if (fileName == null) { return null; } - requireNonNullChars(fileName); - int size = fileName.length(); if (size == 0) { return fileName; @@ -377,10 +369,8 @@ private static String doNormalize(final String fileName, final char separator, f if (prefix < 0) { return null; } - - final char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy + final char[] array = new char[size + 2]; // +1 for possible extra slash, +2 for arraycopy fileName.getChars(0, fileName.length(), array, 0); - // fix separators throughout final char otherSeparator = flipSeparator(separator); for (int i = 0; i < array.length; i++) { @@ -388,14 +378,12 @@ private static String doNormalize(final String fileName, final char separator, f array[i] = separator; } } - // add extra separator on the end to simplify code below boolean lastIsDirectory = true; if (array[size - 1] != separator) { array[size++] = separator; lastIsDirectory = false; } - // adjoining slashes // If we get here, prefix can only be 0 or greater, size 1 or greater // If prefix is 0, set loop start to 1 to prevent index errors @@ -406,11 +394,9 @@ private static String doNormalize(final String fileName, final char separator, f i--; } } - // period slash for (int i = prefix + 1; i < size; i++) { - if (array[i] == separator && array[i - 1] == '.' && - (i == prefix + 1 || array[i - 2] == separator)) { + if (array[i] == separator && array[i - 1] == '.' && (i == prefix + 1 || array[i - 2] == separator)) { if (i == size - 1) { lastIsDirectory = true; } @@ -419,12 +405,9 @@ private static String doNormalize(final String fileName, final char separator, f i--; } } - // double period slash - outer: - for (int i = prefix + 2; i < size; i++) { - if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' && - (i == prefix + 2 || array[i - 3] == separator)) { + outer: for (int i = prefix + 2; i < size; i++) { + if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' && (i == prefix + 2 || array[i - 3] == separator)) { if (i == prefix + 2) { return null; } @@ -432,7 +415,7 @@ private static String doNormalize(final String fileName, final char separator, f lastIsDirectory = true; } int j; - for (j = i - 4 ; j >= prefix; j--) { + for (j = i - 4; j >= prefix; j--) { if (array[j] == separator) { // remove b/../ from a/b/../c System.arraycopy(array, i + 1, array, j + 1, size - i); @@ -447,17 +430,13 @@ private static String doNormalize(final String fileName, final char separator, f i = prefix + 1; } } - - if (size <= 0) { // should never be less than 0 + if (size <= 0) { // should never be less than 0 return EMPTY_STRING; } - if (size <= prefix) { // should never be less than prefix - return new String(array, 0, size); - } - if (lastIsDirectory && keepSeparator) { - return new String(array, 0, size); // keep trailing separator + if (size <= prefix || lastIsDirectory && keepSeparator) { + return new String(array, 0, size); // keep trailing separator } - return new String(array, 0, size - 1); // lose trailing separator + return new String(array, 0, size - 1); // lose trailing separator } /** @@ -488,7 +467,6 @@ public static boolean equals(final String fileName1, final String fileName2) { * @since 1.3 */ public static boolean equals(String fileName1, String fileName2, final boolean normalize, final IOCase ioCase) { - if (fileName1 == null || fileName2 == null) { return fileName1 == null && fileName2 == null; } @@ -1044,7 +1022,6 @@ public static boolean isExtension(final String fileName, final Collection IPV4_MAX_OCTET_VALUE) { + if (iIpSegment > IPV4_MAX_OCTET_VALUE || ipSegment.length() > 1 && ipSegment.startsWith("0")) { return false; } - - if (ipSegment.length() > 1 && ipSegment.startsWith("0")) { - return false; - } - } - return true; } @@ -1466,7 +1435,6 @@ public static String removeExtension(final String fileName) { return null; } requireNonNullChars(fileName); - final int index = indexOfExtension(fileName); if (index == NOT_FOUND) { return fileName; @@ -1532,11 +1500,9 @@ public static String separatorsToWindows(final String path) { static String[] splitOnTokens(final String text) { // used by wildcardMatch // package level so a unit test may run on this - if (text.indexOf('?') == NOT_FOUND && text.indexOf('*') == NOT_FOUND) { return new String[] { text }; } - final char[] array = text.toCharArray(); final ArrayList list = new ArrayList<>(); final StringBuilder buffer = new StringBuilder(); @@ -1560,7 +1526,6 @@ static String[] splitOnTokens(final String text) { if (buffer.length() != 0) { list.add(buffer.toString()); } - return list.toArray(EMPTY_STRING_ARRAY); } @@ -1627,7 +1592,6 @@ public static boolean wildcardMatch(final String fileName, final String wildcard int textIdx = 0; int wcsIdx = 0; final Deque backtrack = new ArrayDeque<>(wcs.length); - // loop around a backtrack stack, to handle complex * matching do { if (!backtrack.isEmpty()) { @@ -1636,10 +1600,8 @@ public static boolean wildcardMatch(final String fileName, final String wildcard textIdx = array[1]; anyChars = true; } - // loop whilst tokens and text left to process while (wcsIdx < wcs.length) { - if (wcs[wcsIdx].equals("?")) { // ? so move to next text char textIdx++; @@ -1647,14 +1609,12 @@ public static boolean wildcardMatch(final String fileName, final String wildcard break; } anyChars = false; - } else if (wcs[wcsIdx].equals("*")) { // set any chars status anyChars = true; if (wcsIdx == wcs.length - 1) { textIdx = fileName.length(); } - } else { // matching text token if (anyChars) { @@ -1666,29 +1626,24 @@ public static boolean wildcardMatch(final String fileName, final String wildcard } final int repeat = ioCase.checkIndexOf(fileName, textIdx + 1, wcs[wcsIdx]); if (repeat >= 0) { - backtrack.push(new int[] {wcsIdx, repeat}); + backtrack.push(new int[] { wcsIdx, repeat }); } } else if (!ioCase.checkRegionMatches(fileName, textIdx, wcs[wcsIdx])) { // matching from current position // couldn't match token break; } - // matched text token, move text index to end of matched token textIdx += wcs[wcsIdx].length(); anyChars = false; } - wcsIdx++; } - // full match if (wcsIdx == wcs.length && textIdx == fileName.length()) { return true; } - } while (!backtrack.isEmpty()); - return false; } diff --git a/src/main/java/org/apache/commons/io/channels/FileChannels.java b/src/main/java/org/apache/commons/io/channels/FileChannels.java index b529c281e11..6629ead4931 100644 --- a/src/main/java/org/apache/commons/io/channels/FileChannels.java +++ b/src/main/java/org/apache/commons/io/channels/FileChannels.java @@ -91,10 +91,7 @@ public static boolean contentEquals(final ReadableByteChannel channel1, final Re Thread.yield(); continue; } - if (c1NumRead != c2NumRead) { - return false; - } - if (!c1Buffer.equals(c2Buffer)) { + if (c1NumRead != c2NumRead || !c1Buffer.equals(c2Buffer)) { return false; } } diff --git a/src/main/java/org/apache/commons/io/input/BoundedReader.java b/src/main/java/org/apache/commons/io/input/BoundedReader.java index f7ce2975308..e3eefe3b57b 100644 --- a/src/main/java/org/apache/commons/io/input/BoundedReader.java +++ b/src/main/java/org/apache/commons/io/input/BoundedReader.java @@ -84,9 +84,7 @@ public void close() throws IOException { @Override public void mark(final int readAheadLimit) throws IOException { this.readAheadLimit = readAheadLimit - charsRead; - markedAt = charsRead; - target.mark(readAheadLimit); } @@ -99,12 +97,7 @@ public void mark(final int readAheadLimit) throws IOException { */ @Override public int read() throws IOException { - - if (charsRead >= maxCharsFromTargetReader) { - return EOF; - } - - if (markedAt >= 0 && charsRead - markedAt >= readAheadLimit) { + if (charsRead >= maxCharsFromTargetReader || markedAt >= 0 && charsRead - markedAt >= readAheadLimit) { return EOF; } charsRead++; 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 bd579b618cf..aefd00e597e 100644 --- a/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java +++ b/src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java @@ -198,10 +198,7 @@ public BufferedFileChannelInputStream(final Path path, final int bufferSize) thr @Override public synchronized int available() throws IOException { - if (!fileChannel.isOpen()) { - return 0; - } - if (!refill()) { + if (!fileChannel.isOpen() || !refill()) { return 0; } return byteBuffer.remaining(); diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java index d8343fd9371..3d8a667c815 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java @@ -795,11 +795,7 @@ String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, final // BOM is UTF-8 if (bomEnc.equals(UTF_8)) { - if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8)) { - final String msg = MessageFormat.format(RAW_EX_1, bomEnc, xmlGuessEnc, xmlEnc); - throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); - } - if (xmlEnc != null && !xmlEnc.equals(UTF_8)) { + if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8) || xmlEnc != null && !xmlEnc.equals(UTF_8)) { final String msg = MessageFormat.format(RAW_EX_1, bomEnc, xmlGuessEnc, xmlEnc); throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); } diff --git a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java index b73c9991dc3..3cf8a437961 100644 --- a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java +++ b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java @@ -612,12 +612,7 @@ String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, encoding = xmlEnc; } } else if (bomEnc.equals(UTF_8)) { - if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8)) { - throw new XmlStreamReaderException(RAW_EX_1 - .format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), - bomEnc, xmlGuessEnc, xmlEnc, is); - } - if (xmlEnc != null && !xmlEnc.equals(UTF_8)) { + if (xmlGuessEnc != null && !xmlGuessEnc.equals(UTF_8) || xmlEnc != null && !xmlEnc.equals(UTF_8)) { throw new XmlStreamReaderException(RAW_EX_1 .format(new Object[] { bomEnc, xmlGuessEnc, xmlEnc }), bomEnc, xmlGuessEnc, xmlEnc, is); From 994da0a267a81709b66a9c81560828367306ee75 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 25 Jan 2026 14:41:56 +0000 Subject: [PATCH 146/174] Prepare for the next release candidate --- RELEASE-NOTES.txt | 54 +++++++++++++++++++++++++++++++++++++++++ src/changes/changes.xml | 4 +-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 7de38f13ad8..569810a1325 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -14,6 +14,60 @@ This is a feature and maintenance release. Java 8 or later is required. New features ------------ +o Add and use IOUtils.closeQuietlyAdd(Closeable, Throwable) #818. Thanks to Gary Gregory. + +Fixed Bugs +---------- + +o Fix Apache RAT plugin console warnings. Thanks to Gary Gregory. +o ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Thanks to Gary Gregory, Piotr P. Karwasz. +o Fix malformed Javadoc comments. Thanks to Gary Gregory. +o ReadAheadInputStream.close() doesn't always close its filtered input stream. Thanks to Stanislav Fort, Gary Gregory. + +Changes +------- + +o Bump org.apache.commons:commons-parent from 91 to 96 #816. Thanks to Gary Gregory, Dependabot. +o Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. Thanks to Gary Gregory, Dependabot. +o Bump commons.bytebuddy.version from 1.17.8 to 1.18.4 #814, #820. Thanks to Gary Gregory, Dependabot. +o Bump commons-lang3 from 3.19.0 to 3.20.0. Thanks to Gary Gregory, Dependabot. + + +Commons IO 2.7 and up requires Java 8 or above. +Commons IO 2.6 requires Java 7 or above. +Commons IO 2.3 through 2.5 requires Java 6 or above. +Commons IO 2.2 requires Java 5 or above. +Commons IO 1.4 requires Java 1.3 or above. + +Historical list of changes: https://commons.apache.org/proper/commons-io/changes.html + +For complete information on Apache Commons IO, including instructions on how to submit bug reports, +patches, or suggestions for improvement, see the Apache Commons IO website: + +https://commons.apache.org/proper/commons-io/ + +Download page: https://commons.apache.org/proper/commons-io/download_io.cgi + +Have fun! +-Apache Commons Team + +------------------------------------------------------------------------------ + +Apache Commons IO 2.22.0 Release Notes + +The Apache Commons IO team is pleased to announce the release of Apache Commons IO 2.22.0. + +Introduction +------------ + +The Apache Commons IO library contains utility classes, stream implementations, file filters, +file comparators, endian transformation classes, and much more. + +This is a feature and maintenance release. Java 8 or later is required. + +New features +------------ + o Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. Thanks to Gary Gregory. Fixed Bugs diff --git a/src/changes/changes.xml b/src/changes/changes.xml index fc7f1f3c9ca..6862891e173 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,14 +45,14 @@ The type attribute can be add,update,fix,remove. Apache Commons IO Release Notes - + Fix Apache RAT plugin console warnings. ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Fix malformed Javadoc comments. ReadAheadInputStream.close() doesn't always close its filtered input stream. - Add and use IOUtils.closeQuietly(Closeable, Throwable) #818. + Add and use IOUtils.closeQuietlyAdd(Closeable, Throwable) #818. Bump org.apache.commons:commons-parent from 91 to 96 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. From 40b954f7ae975cb59b3e8c2b37e01824401db53f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 26 Jan 2026 09:37:15 -0500 Subject: [PATCH 147/174] Bump github/codeql-action from 4.31.10 to 4.31.11 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6a5db14e0e4..58611ed0a39 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 + uses: github/codeql-action/init@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 + uses: github/codeql-action/autobuild@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 + uses: github/codeql-action/analyze@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index dd582b61b44..417e0d0fb24 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 + uses: github/codeql-action/upload-sarif@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 with: sarif_file: results.sarif From 2eb4ff6a65563254689ab6b49f4124aa00bd7391 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Mon, 26 Jan 2026 18:02:59 -0500 Subject: [PATCH 148/174] Rename new method --- RELEASE-NOTES.txt | 2 +- src/changes/changes.xml | 2 +- .../java/org/apache/commons/io/FileUtils.java | 2 +- .../java/org/apache/commons/io/IOUtils.java | 2 +- .../org/apache/commons/io/LineIterator.java | 2 +- .../io/output/FileWriterWithEncoding.java | 2 +- .../org/apache/commons/io/IOUtilsTest.java | 24 +++++++++---------- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 569810a1325..5daadd53bfc 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -14,7 +14,7 @@ This is a feature and maintenance release. Java 8 or later is required. New features ------------ -o Add and use IOUtils.closeQuietlyAdd(Closeable, Throwable) #818. Thanks to Gary Gregory. +o Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. Thanks to Gary Gregory, Piotr P. Karwasz. Fixed Bugs ---------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 6862891e173..f3ea648c1a1 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -52,7 +52,7 @@ The type attribute can be add,update,fix,remove. Fix malformed Javadoc comments. ReadAheadInputStream.close() doesn't always close its filtered input stream. - Add and use IOUtils.closeQuietlyAdd(Closeable, Throwable) #818. + Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. Bump org.apache.commons:commons-parent from 91 to 96 #816. Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index 9c85e9d281e..c7c0d1ad19c 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -2290,7 +2290,7 @@ public static LineIterator lineIterator(final File file, final String charsetNam inputStream = Files.newInputStream(file.toPath()); return IOUtils.lineIterator(inputStream, charsetName); } catch (final IOException | RuntimeException ex) { - IOUtils.closeQuietlyAdd(inputStream, ex); + IOUtils.closeQuietlySuppress(inputStream, ex); throw ex; } } diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index da6d3e00ddb..3cd6e9cb995 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -1180,7 +1180,7 @@ public static void closeQuietly(final Writer writer) { * @since 2.22.0 * @see Throwable#addSuppressed(Throwable) */ - public static T closeQuietlyAdd(final Closeable closeable, final T throwable) { + public static T closeQuietlySuppress(final Closeable closeable, final T throwable) { closeQuietly(closeable, (Consumer) throwable::addSuppressed); return throwable; } diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index 5b7f531e71e..fd07e9325c9 100644 --- a/src/main/java/org/apache/commons/io/LineIterator.java +++ b/src/main/java/org/apache/commons/io/LineIterator.java @@ -135,7 +135,7 @@ public boolean hasNext() { } } } catch (final IOException ioe) { - throw new IllegalStateException(IOUtils.closeQuietlyAdd(this, ioe)); + throw new IllegalStateException(IOUtils.closeQuietlySuppress(this, ioe)); } } 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 8d3f4fc6fc8..4b6ebe1ba3e 100644 --- a/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java +++ b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java @@ -188,7 +188,7 @@ private static OutputStreamWriter initWriter(final File file, final Object encod } return new OutputStreamWriter(outputStream, (String) encoding); } catch (final IOException | RuntimeException ex) { - IOUtils.closeQuietlyAdd(outputStream, ex); + IOUtils.closeQuietlySuppress(outputStream, ex); if (!fileExistedAlready) { FileUtils.deleteQuietly(file); } diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 082d5960d87..d9d073357b5 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -585,18 +585,6 @@ void testCloseQuietly_CloseableExceptionConsumer() { assertTrue(b.get()); } - @SuppressWarnings("resource") - @Test - void testCloseQuietly_CloseableIOExceptionAddSuppressed() { - final Throwable e = new Exception("test").fillInStackTrace(); - assertEquals(0, e.getSuppressed().length); - assertSame(e, IOUtils.closeQuietlyAdd(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); - assertEquals(1, e.getSuppressed().length); - final Throwable suppressed0 = e.getSuppressed()[0]; - assertInstanceOf(EOFException.class, suppressed0); - assertEquals("Suppressed", suppressed0.getMessage()); - } - @Test void testCloseQuietly_Selector() { Selector selector = null; @@ -681,6 +669,18 @@ public synchronized void close() throws IOException { }); } + @SuppressWarnings("resource") + @Test + void testCloseQuietlySuppress_CloseableIOExceptionAddSuppressed() { + final Throwable e = new Exception("test").fillInStackTrace(); + assertEquals(0, e.getSuppressed().length); + assertSame(e, IOUtils.closeQuietlySuppress(new BrokenInputStream(new EOFException("Suppressed").fillInStackTrace()), e)); + assertEquals(1, e.getSuppressed().length); + final Throwable suppressed0 = e.getSuppressed()[0]; + assertInstanceOf(EOFException.class, suppressed0); + assertEquals("Suppressed", suppressed0.getMessage()); + } + @Test void testCloseURLConnection() { assertDoesNotThrow(() -> IOUtils.close((URLConnection) null)); From e026bf9cda9a8b66e0c47b5fb4e7a2475fcba880 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 08:44:39 -0500 Subject: [PATCH 149/174] ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException --- src/changes/changes.xml | 1 + .../java/org/apache/commons/io/input/ReadAheadInputStream.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f3ea648c1a1..86e51bfd58f 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -51,6 +51,7 @@ The type attribute can be add,update,fix,remove. ByteArraySeekableByteChannel.position(long) and truncate(long) shouldn't throw an IllegalArgumentException for a new positive position that's too large #817. Fix malformed Javadoc comments. ReadAheadInputStream.close() doesn't always close its filtered input stream. + ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index a028bfbc0f6..1d695d4d5aa 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -298,6 +298,7 @@ public void close() throws IOException { executorService.shutdownNow(); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); iio.initCause(e); throw iio; @@ -557,6 +558,7 @@ private void waitForAsyncReadComplete() throws IOException { asyncReadComplete.await(); } } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); iio.initCause(e); throw iio; From ec8254e4681ef184e4cc625c1cea1b62f30f9189 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:20:04 -0500 Subject: [PATCH 150/174] Update test to match InterruptedException guidelines --- .../org/apache/commons/io/file/AccumulatorPathVisitorTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/apache/commons/io/file/AccumulatorPathVisitorTest.java b/src/test/java/org/apache/commons/io/file/AccumulatorPathVisitorTest.java index 4380823d1bf..1bfe338db9d 100644 --- a/src/test/java/org/apache/commons/io/file/AccumulatorPathVisitorTest.java +++ b/src/test/java/org/apache/commons/io/file/AccumulatorPathVisitorTest.java @@ -207,6 +207,7 @@ public FileVisitResult visitFile(final Path path, final BasicFileAttributes attr try { ThreadUtils.sleep(Duration.ofMillis(10)); } catch (final InterruptedException ignore) { + Thread.currentThread().interrupt(); // e.printStackTrace(); } return super.visitFile(path, attributes); From 35cf21faeba0f2f992134b99d24e6158a6b2250a Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:20:14 -0500 Subject: [PATCH 151/174] Update test to match InterruptedException guidelines --- .../commons/io/input/UnsynchronizedBufferedInputStreamTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java index a47604020e1..ee1e2e983fc 100644 --- a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java @@ -134,7 +134,7 @@ public int read(final byte[] buf, final int offset, final int length) { try { lock.wait(3000); } catch (final InterruptedException e) { - // Ignore + Thread.currentThread().interrupt(); } } return 1; From dc654295195c4607e58a332cf20e13764d8b5b51 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:20:18 -0500 Subject: [PATCH 152/174] Update test to match InterruptedException guidelines --- src/test/java/org/apache/commons/io/ThreadMonitorTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/apache/commons/io/ThreadMonitorTest.java b/src/test/java/org/apache/commons/io/ThreadMonitorTest.java index 085f210c087..fe611a7f840 100644 --- a/src/test/java/org/apache/commons/io/ThreadMonitorTest.java +++ b/src/test/java/org/apache/commons/io/ThreadMonitorTest.java @@ -40,6 +40,7 @@ void testCompletedWithoutTimeout() { TestUtils.sleep(1); ThreadMonitor.stop(monitor); } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); fail("Timed Out", e); } } From a1ed47cf6bf3555238eb27ce094509a7e04d76f7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:20:25 -0500 Subject: [PATCH 153/174] Update test to match InterruptedException guidelines --- .../java/org/apache/commons/io/filefilter/FileFilterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java index 6e11b5e770f..36698b48028 100644 --- a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java @@ -78,7 +78,7 @@ void testAgeFilter() throws Exception { try { TestUtils.sleep(1000); } catch (final InterruptedException ie) { - // ignore + Thread.currentThread().interrupt(); } if (!reference.getParentFile().exists()) { fail("Cannot create file " + reference + " as the parent directory does not exist"); From c9e7cd7480c7eeba3fdae458352e8801364bd7e9 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:20:45 -0500 Subject: [PATCH 154/174] Update test to match InterruptedException guidelines --- src/test/java/org/apache/commons/io/test/TestUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/test/TestUtils.java b/src/test/java/org/apache/commons/io/test/TestUtils.java index 619c1e3eb30..c8f035fff09 100644 --- a/src/test/java/org/apache/commons/io/test/TestUtils.java +++ b/src/test/java/org/apache/commons/io/test/TestUtils.java @@ -260,7 +260,7 @@ public static void sleepQuietly(final long millis) { try { sleep(millis); } catch (final InterruptedException ignored) { - // ignore InterruptedException. + Thread.currentThread().interrupt(); } } From e6ada97797a7ddb234a17192d1c063148c8308f7 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:21:12 -0500 Subject: [PATCH 155/174] FileAlterationMonitor.stop(long) now restores the current thread's interrupt flag when catching InterruptedException. --- src/changes/changes.xml | 1 + .../org/apache/commons/io/monitor/FileAlterationMonitor.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 86e51bfd58f..3819b3e6c6b 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -52,6 +52,7 @@ The type attribute can be add,update,fix,remove. Fix malformed Javadoc comments. ReadAheadInputStream.close() doesn't always close its filtered input stream. ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException. + FileAlterationMonitor.stop(long) now restores the current thread's interrupt flag when catching InterruptedException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java index 77f7fa56b02..b14155fe943 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java @@ -149,7 +149,7 @@ public void run() { try { ThreadUtils.sleep(Duration.ofMillis(intervalMillis)); } catch (final InterruptedException ignored) { - // ignore + Thread.currentThread().interrupt(); } } } From c1f13a50321380feb488d9de164f5850106dcc4c Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:27:12 -0500 Subject: [PATCH 156/174] FileCleaningTracker now restores the current thread's interrupt flag when catching InterruptedException. --- src/changes/changes.xml | 1 + src/main/java/org/apache/commons/io/FileCleaningTracker.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3819b3e6c6b..823ca5d24f7 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -53,6 +53,7 @@ The type attribute can be add,update,fix,remove. ReadAheadInputStream.close() doesn't always close its filtered input stream. ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException. FileAlterationMonitor.stop(long) now restores the current thread's interrupt flag when catching InterruptedException. + FileCleaningTracker now restores the current thread's interrupt flag when catching InterruptedException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index 4fa8e973b6f..c453415cd34 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -76,6 +76,7 @@ public void run() { } tracker.clear(); } catch (final InterruptedException e) { + interrupt(); continue; } } From a2f3ab9dd6e293ba08e765e0f37f71199c5143e1 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:28:07 -0500 Subject: [PATCH 157/174] ThreadMonitor.run() now restores the current thread's interrupt flag when catching InterruptedException. --- src/changes/changes.xml | 1 + src/main/java/org/apache/commons/io/ThreadMonitor.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 823ca5d24f7..91bab21defc 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,7 @@ The type attribute can be add,update,fix,remove. ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException. FileAlterationMonitor.stop(long) now restores the current thread's interrupt flag when catching InterruptedException. FileCleaningTracker now restores the current thread's interrupt flag when catching InterruptedException. + ThreadMonitor.run() now restores the current thread's interrupt flag when catching InterruptedException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/ThreadMonitor.java b/src/main/java/org/apache/commons/io/ThreadMonitor.java index 37e7bfabe71..24ebe705a1d 100644 --- a/src/main/java/org/apache/commons/io/ThreadMonitor.java +++ b/src/main/java/org/apache/commons/io/ThreadMonitor.java @@ -104,6 +104,7 @@ public void run() { thread.interrupt(); } catch (final InterruptedException ignored) { // timeout not reached + Thread.currentThread().interrupt(); } } } From 82a97a54728e33dee2deba6836108efd5c8a4598 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:29:14 -0500 Subject: [PATCH 158/174] ThrottledInputStream.throttle() now restores the current thread's interrupt flag when catching InterruptedException. --- src/changes/changes.xml | 1 + .../java/org/apache/commons/io/input/ThrottledInputStream.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 91bab21defc..f191ca002c4 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,6 +55,7 @@ The type attribute can be add,update,fix,remove. FileAlterationMonitor.stop(long) now restores the current thread's interrupt flag when catching InterruptedException. FileCleaningTracker now restores the current thread's interrupt flag when catching InterruptedException. ThreadMonitor.run() now restores the current thread's interrupt flag when catching InterruptedException. + ThrottledInputStream.throttle() now restores the current thread's interrupt flag when catching InterruptedException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java index 9b670bdae10..529d9256fc7 100644 --- a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java @@ -271,6 +271,7 @@ private void throttle() throws InterruptedIOException { try { TimeUnit.MILLISECONDS.sleep(sleepMillis); } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); throw new InterruptedIOException("Thread aborted"); } } From e061d95bbcd89896ac3423dbcd7e94020eb0617c Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Wed, 28 Jan 2026 15:45:31 -0500 Subject: [PATCH 159/174] Bump github/codeql-action from 4.31.11 to 4.32.0 --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 58611ed0a39..c46b8e23195 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -62,7 +62,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -73,7 +73,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/autobuild@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -87,4 +87,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 417e0d0fb24..6a7fedc37ca 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -66,6 +66,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11 + uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: sarif_file: results.sarif From b83664fabcae8236a9e9c1223f9b00ecfb1b1f93 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Thu, 29 Jan 2026 17:34:45 -0500 Subject: [PATCH 160/174] Bump commons-codec:commons-codec from 1.20.0 to 1.21.0. --- pom.xml | 2 +- src/changes/changes.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 86fbb10676b..8827b9d8aa0 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ file comparators, endian transformation classes, and much more. commons-codec commons-codec - 1.20.0 + 1.21.0 test diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f191ca002c4..a1be68ee625 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -60,7 +60,7 @@ The type attribute can be add,update,fix,remove. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. Bump org.apache.commons:commons-parent from 91 to 96 #816. - Bump commons-codec:commons-codec from 1.19.0 to 1.20.0 #812. + Bump commons-codec:commons-codec from 1.19.0 to 1.21.0 #812. Bump commons.bytebuddy.version from 1.17.8 to 1.18.4 #814, #820. Bump commons-lang3 from 3.19.0 to 3.20.0. From ada97446544f9132fa4abdcb4b0e693a977ccbbf Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 10:36:35 -0500 Subject: [PATCH 161/174] ThrottledInputStream.throttle() doesn't preserve the original InterruptedException as the cause of its InterruptedIOException ThrottledInputStream.throttle() now restores the current thread's interrupt flag when catching InterruptedException. --- src/changes/changes.xml | 1 + .../org/apache/commons/io/input/Input.java | 20 ++++++++++++++- .../io/input/ReadAheadInputStream.java | 9 ++----- .../io/input/ThrottledInputStream.java | 25 ++++++++++++++++--- .../io/input/ThrottledInputStreamTest.java | 20 +++++++++++++++ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a1be68ee625..bc9d1ce9088 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -56,6 +56,7 @@ The type attribute can be add,update,fix,remove. FileCleaningTracker now restores the current thread's interrupt flag when catching InterruptedException. ThreadMonitor.run() now restores the current thread's interrupt flag when catching InterruptedException. ThrottledInputStream.throttle() now restores the current thread's interrupt flag when catching InterruptedException. + ThrottledInputStream.throttle() doesn't preserve the original InterruptedException as the cause of its InterruptedIOException. Add and use IOUtils.closeQuietlySuppress(Closeable, Throwable) #818. diff --git a/src/main/java/org/apache/commons/io/input/Input.java b/src/main/java/org/apache/commons/io/input/Input.java index 70147681178..a1ac19b5b38 100644 --- a/src/main/java/org/apache/commons/io/input/Input.java +++ b/src/main/java/org/apache/commons/io/input/Input.java @@ -18,11 +18,12 @@ package org.apache.commons.io.input; import java.io.IOException; +import java.io.InterruptedIOException; /** * Package-wide internals for input. */ -class Input { +final class Input { /** * Throws an IOException on false input. @@ -36,4 +37,21 @@ static void checkOpen(final boolean isOpen) throws IOException { } } + /** + * Converts an InterruptedException to an InterruptedIOException. + *

    + * The cause of the returned InterruptedIOException is set to the original. + *

    + * + * @param e The InterruptedException to convert. + * @return The converted InterruptedIOException. + * @see InterruptedIOException + * @see Throwable#initCause(Throwable) + * @see Throwable#getCause() + */ + static InterruptedIOException toInterruptedIOException(final InterruptedException e) { + final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); + iio.initCause(e); + return iio; + } } diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index 1d695d4d5aa..5b694e2503e 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -20,7 +20,6 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InterruptedIOException; import java.nio.ByteBuffer; import java.util.Objects; import java.util.concurrent.ExecutorService; @@ -299,9 +298,7 @@ public void close() throws IOException { executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); - final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); - iio.initCause(e); - throw iio; + throw Input.toInterruptedIOException(e); } finally { if (isSafeToCloseUnderlyingInputStream) { super.close(); @@ -559,9 +556,7 @@ private void waitForAsyncReadComplete() throws IOException { } } catch (final InterruptedException e) { Thread.currentThread().interrupt(); - final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); - iio.initCause(e); - throw iio; + throw Input.toInterruptedIOException(e); } finally { try { isWaiting.set(false); diff --git a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java index 529d9256fc7..e07cdc3eadb 100644 --- a/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ThrottledInputStream.java @@ -245,21 +245,38 @@ private long getBytesPerSecond() { return getByteCount() / elapsedSeconds; } - // package private for testing. + /** + * Gets the maximum bytes per second. + *

    + * Package private for testing. + *

    + * + * @return The maximum bytes per second. + */ double getMaxBytesPerSecond() { return maxBytesPerSecond; } - private long getSleepMillis() { + /** + * Gets the number of milliseconds to sleep to match to the maximum bytes per second. + *

    + * Package private for testing. + *

    + * + * @return the number of milliseconds to sleep to match to the maximum bytes per second. + */ + long getSleepMillis() { return toSleepMillis(getByteCount(), System.currentTimeMillis() - startTime, maxBytesPerSecond); } /** * Gets the total duration spent in sleep. + *

    + * Package private for testing + *

    * * @return Duration spent in sleep. */ - // package private for testing Duration getTotalSleepDuration() { return totalSleepDuration; } @@ -272,7 +289,7 @@ private void throttle() throws InterruptedIOException { TimeUnit.MILLISECONDS.sleep(sleepMillis); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); - throw new InterruptedIOException("Thread aborted"); + throw Input.toInterruptedIOException(e); } } } diff --git a/src/test/java/org/apache/commons/io/input/ThrottledInputStreamTest.java b/src/test/java/org/apache/commons/io/input/ThrottledInputStreamTest.java index d44f29746a5..4f66cb1254c 100644 --- a/src/test/java/org/apache/commons/io/input/ThrottledInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/ThrottledInputStreamTest.java @@ -18,12 +18,16 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrowsExactly; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -188,4 +192,20 @@ void testGet() throws IOException { } } + @Test + synchronized void testReadInterrupt() throws IOException { + try (ThrottledInputStream inputStream = ThrottledInputStream.builder() + // @formatter:off + .setInputStream(createOriginInputStream()) + .setMaxBytes(1, ChronoUnit.HOURS) + .get()) { + // @formatter:on + final ThrottledInputStream spy = spy(inputStream); + when(spy.getSleepMillis()).thenReturn(1L); + Thread.currentThread().interrupt(); + assertInstanceOf(InterruptedException.class, assertThrows(InterruptedIOException.class, spy::read).getCause()); + assertTrue(Thread.interrupted()); + } + } + } From b6629582f0d6f60285093dee4af8f48d3c9ab726 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 11:01:28 -0500 Subject: [PATCH 162/174] Test fix for ReadAheadInputStream now restores the current thread's interrupt flag when catching InterruptedException. --- .../io/input/ReadAheadInputStream.java | 8 +++++-- .../io/input/ReadAheadInputStreamTest.java | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index 5b694e2503e..152cd42a586 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -294,8 +294,7 @@ public void close() throws IOException { } if (shutdownExecutorService) { try { - executorService.shutdownNow(); - executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + shutdownAwait(); } catch (final InterruptedException e) { Thread.currentThread().interrupt(); throw Input.toInterruptedIOException(e); @@ -464,6 +463,11 @@ private void readAsync() throws IOException { }); } + boolean shutdownAwait() throws InterruptedException { + executorService.shutdownNow(); + return executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + } + private void signalAsyncReadComplete() { stateChangeLock.lock(); try { diff --git a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java index 6ad34e9b2b4..c58324724de 100644 --- a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java @@ -18,17 +18,24 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.nio.file.StandardOpenOption; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; /** * Tests {@link ReadAheadInputStream}. This class was ported and adapted from Apache Spark commit 933dc6cb7b3de1d8ccaf73d124d6eb95b947ed19 where it was called @@ -64,6 +71,22 @@ void setUpInputStreams() throws IOException { ReadAheadInputStream.builder().setPath(InputPath).setOpenOptions(StandardOpenOption.READ).get() }; } + @Test + @Timeout(value = 5, unit = TimeUnit.SECONDS) + synchronized void testCloseInterrupt() throws IOException, InterruptedException { + try (ReadAheadInputStream inputStream = ReadAheadInputStream.builder() + // @formatter:off + .setPath(InputPath) + .get()) { + // @formatter:on + final ReadAheadInputStream spy = spy(inputStream); + when(spy.shutdownAwait()).thenThrow(InterruptedException.class); + Thread.currentThread().interrupt(); + assertInstanceOf(InterruptedException.class, assertThrows(InterruptedIOException.class, spy::close).getCause()); + assertTrue(Thread.interrupted()); + } + } + @Test void testClosePlusExecutorService() throws IOException { final ExecutorService externalExecutor = Executors.newSingleThreadExecutor(); @@ -82,4 +105,5 @@ void testClosePlusExecutorService() throws IOException { } } } + } From 9882f7d94ecfffa53403af7d3857762d5c0bf18b Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 11:45:08 -0500 Subject: [PATCH 163/174] Change timeout for testCloseInterrupt to 30 seconds Increased timeout duration for testCloseInterrupt method. --- .../org/apache/commons/io/input/ReadAheadInputStreamTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java index c58324724de..1a2520ba4bb 100644 --- a/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java @@ -72,7 +72,7 @@ void setUpInputStreams() throws IOException { } @Test - @Timeout(value = 5, unit = TimeUnit.SECONDS) + @Timeout(value = 30, unit = TimeUnit.SECONDS) synchronized void testCloseInterrupt() throws IOException, InterruptedException { try (ReadAheadInputStream inputStream = ReadAheadInputStream.builder() // @formatter:off From ef2c5e3c5aaa30b8d1ba209ba802c5d38a338e7c Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 15:44:58 -0500 Subject: [PATCH 164/174] Better internal name --- .../java/org/apache/commons/io/FileCleaningTracker.java | 6 +++--- .../java/org/apache/commons/io/FileCleaningTrackerTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index c453415cd34..e203079e502 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -69,7 +69,7 @@ public void run() { while (!exitWhenFinished || !trackers.isEmpty()) { try { // Wait for a tracker to remove. - final Tracker tracker = (Tracker) q.remove(); // cannot return null + final Tracker tracker = (Tracker) refQueue.remove(); // cannot return null trackers.remove(tracker); if (!tracker.delete()) { deleteFailures.add(tracker.getPath()); @@ -136,7 +136,7 @@ public String getPath() { /** * Queue of {@link Tracker} instances being watched. */ - ReferenceQueue q = new ReferenceQueue<>(); + ReferenceQueue refQueue = new ReferenceQueue<>(); /** * Collection of {@link Tracker} instances in existence. @@ -182,7 +182,7 @@ private synchronized void addTracker(final String path, final Object marker, fin reaper = new Reaper(); reaper.start(); } - trackers.add(new Tracker(path, deleteStrategy, marker, q)); + trackers.add(new Tracker(path, deleteStrategy, marker, refQueue)); } /** diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java index 33771fe4554..95c3d4797ad 100644 --- a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java +++ b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java @@ -100,7 +100,7 @@ public void tearDown() { */ { if (fileCleaningTracker != null) { - fileCleaningTracker.q = new ReferenceQueue<>(); + fileCleaningTracker.refQueue = new ReferenceQueue<>(); fileCleaningTracker.trackers.clear(); fileCleaningTracker.deleteFailures.clear(); fileCleaningTracker.exitWhenFinished = false; From e69cedbc38aa0a07afc5994a80131a7ee1e4f541 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 15:51:31 -0500 Subject: [PATCH 165/174] Push down null invariant check and Javadoc. --- .../java/org/apache/commons/io/FileCleaningTracker.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index e203079e502..f390814ed1f 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -106,10 +106,9 @@ private static final class Tracker extends PhantomReference { * @param marker the marker object used to track the file, not null. * @param queue the queue on to which the tracker will be pushed, not null. */ - Tracker(final String path, final FileDeleteStrategy deleteStrategy, final Object marker, - final ReferenceQueue queue) { + Tracker(final String path, final FileDeleteStrategy deleteStrategy, final Object marker, final ReferenceQueue queue) { super(marker, queue); - this.path = path; + this.path = Objects.requireNonNull(path, "path"); this.deleteStrategy = deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy; } @@ -171,6 +170,7 @@ public FileCleaningTracker() { * @param path the full path to the file to be tracked, not null. * @param marker the marker object used to track the file, not null. * @param deleteStrategy the strategy to delete the file, null means normal. + * @throws NullPointerException Thrown if the path is null. */ private synchronized void addTracker(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) { @@ -316,10 +316,9 @@ public void track(final String path, final Object marker) { * @param path the full path to the file to be tracked, not null. * @param marker the marker object used to track the file, not null. * @param deleteStrategy the strategy to delete the file, null means normal. - * @throws NullPointerException if the path is null. + * @throws NullPointerException Thrown if the path is null. */ public void track(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) { - Objects.requireNonNull(path, "path"); addTracker(path, marker, deleteStrategy); } From 12d849263336a405c31593ce70764efeb4084e9f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 15:52:16 -0500 Subject: [PATCH 166/174] Javadoc --- src/main/java/org/apache/commons/io/FileCleaner.java | 2 +- .../java/org/apache/commons/io/input/TailerListenerAdapter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaner.java b/src/main/java/org/apache/commons/io/FileCleaner.java index fbb0bf51d7e..df9bc924f49 100644 --- a/src/main/java/org/apache/commons/io/FileCleaner.java +++ b/src/main/java/org/apache/commons/io/FileCleaner.java @@ -53,7 +53,7 @@ public class FileCleaner { * loader it was started from terminates. This can constitute a memory leak. *

    * For example, suppose that you have developed a web application, which - * contains the commons-io jar file in your WEB-INF/lib directory. In other + * contains the Commons IO jar file in your WEB-INF/lib directory. In other * words, the FileCleaner class is loaded through the class loader of your * web application. If the web application is terminated, but the servlet * container is still running, then the file cleaner thread will still exist, diff --git a/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java b/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java index ac9380f3e79..1a9dfd76c4a 100644 --- a/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java +++ b/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java @@ -35,7 +35,7 @@ public TailerListenerAdapter() { * * Note: this is called from the tailer thread. * - * Note: a future version of commons-io will pull this method up to the TailerListener interface, + * Note: a future version of Commons IO will pull this method up to the TailerListener interface, * for now clients must subclass this class to use this feature. * * @since 2.5 From 9df1e7ffa5eca5d4b802d21b3f45481f4a79445f Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 16:02:14 -0500 Subject: [PATCH 167/174] Better internal typing --- src/main/java/org/apache/commons/io/FileCleaningTracker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index f390814ed1f..f0f383a5685 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -21,11 +21,11 @@ import java.lang.ref.ReferenceQueue; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; /** * Keeps track of files awaiting deletion, and deletes them when an associated @@ -140,7 +140,7 @@ public String getPath() { /** * Collection of {@link Tracker} instances in existence. */ - final Collection trackers = Collections.synchronizedSet(new HashSet<>()); // synchronized + final Set trackers = Collections.synchronizedSet(new HashSet<>()); // synchronized /** * Collection of File paths that failed to delete. From eabcbf5e9162aab4eefbc1bc1d699e3e93077948 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 16:10:57 -0500 Subject: [PATCH 168/174] Javadoc and comments Javadoc and comments --- .../org/apache/commons/io/FileCleaningTracker.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index f0f383a5685..c3913f4f7c5 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -28,7 +28,7 @@ import java.util.Set; /** - * Keeps track of files awaiting deletion, and deletes them when an associated + * Tracks files awaiting deletion, and deletes them when an associated * marker object is reclaimed by the garbage collector. *

    * This utility creates a background thread to handle file deletion. @@ -76,6 +76,7 @@ public void run() { } tracker.clear(); } catch (final InterruptedException e) { + // interrupted removing from the queue. interrupt(); continue; } @@ -172,9 +173,8 @@ public FileCleaningTracker() { * @param deleteStrategy the strategy to delete the file, null means normal. * @throws NullPointerException Thrown if the path is null. */ - private synchronized void addTracker(final String path, final Object marker, final FileDeleteStrategy - deleteStrategy) { - // synchronized block protects reaper + private synchronized void addTracker(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) { + // synchronized method guards reaper if (exitWhenFinished) { throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called"); } @@ -194,6 +194,7 @@ private synchronized void addTracker(final String path, final Object marker, fin * with multiple class loaders (such as an application server), you should be * aware that the file cleaner thread will continue running even if the class * loader it was started from terminates. This can constitute a memory leak. + *

    *

    * For example, suppose that you have developed a web application, which * contains the commons-io jar file in your WEB-INF/lib directory. In other @@ -201,14 +202,16 @@ private synchronized void addTracker(final String path, final Object marker, fin * web application. If the web application is terminated, but the servlet * container is still running, then the file cleaner thread will still exist, * posing a memory leak. + *

    *

    * This method allows the thread to be terminated. Simply call this method * in the resource cleanup code, such as * {@code javax.servlet.ServletContextListener.contextDestroyed(javax.servlet.ServletContextEvent)}. * Once called, no new objects can be tracked by the file cleaner. + *

    */ public synchronized void exitWhenFinished() { - // synchronized block protects reaper + // synchronized method guards reaper exitWhenFinished = true; if (reaper != null) { synchronized (reaper) { From 70ad75d7128755f315062de95eb4318c4549d9ad Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 21:17:44 -0500 Subject: [PATCH 169/174] Make internal class final --- src/main/java/org/apache/commons/io/FileDeleteStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/FileDeleteStrategy.java b/src/main/java/org/apache/commons/io/FileDeleteStrategy.java index 9ce7ab2461a..a73ea719a75 100644 --- a/src/main/java/org/apache/commons/io/FileDeleteStrategy.java +++ b/src/main/java/org/apache/commons/io/FileDeleteStrategy.java @@ -37,7 +37,7 @@ public class FileDeleteStrategy { /** * Force file deletion strategy. */ - static class ForceFileDeleteStrategy extends FileDeleteStrategy { + static final class ForceFileDeleteStrategy extends FileDeleteStrategy { /** Default Constructor */ ForceFileDeleteStrategy() { From 58909e8e30168362b8cb54ef2d26253ab0d6eda2 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Fri, 30 Jan 2026 21:33:36 -0500 Subject: [PATCH 170/174] Better test name Longer lines --- .../commons/io/FileCleaningTrackerTest.java | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java index 95c3d4797ad..a4083a53cbb 100644 --- a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java +++ b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java @@ -90,16 +90,16 @@ private String showFailures() { @AfterEach public void tearDown() { - // reset file cleaner class, so as not to break other tests - /** - * The following block of code can possibly be removed when the deprecated {@link FileCleaner} is gone. The - * question is, whether we want to support reuse of {@link FileCleaningTracker} instances, which we should, IMO, - * not. + * The following block of code can possibly be removed when the deprecated {@link FileCleaner} is gone. The question is, whether we want to support + * reuse of {@link FileCleaningTracker} instances, which we should, IMO, not. */ { if (fileCleaningTracker != null) { + if (fileCleaningTracker.reaper != null) { + fileCleaningTracker.reaper.interrupt(); + } fileCleaningTracker.refQueue = new ReferenceQueue<>(); fileCleaningTracker.trackers.clear(); fileCleaningTracker.deleteFailures.clear(); @@ -107,15 +107,13 @@ public void tearDown() { fileCleaningTracker.reaper = null; } } - fileCleaningTracker = null; } @Test void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception { if (!testFile.getParentFile().exists()) { - throw new IOException("Cannot create file " + testFile - + " as the parent directory does not exist"); + throw new IOException("Cannot create file " + testFile + " as the parent directory does not exist"); } try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) { @@ -131,7 +129,7 @@ void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(testFile.getParentFile()); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -142,8 +140,7 @@ void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception { @Test void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception { if (!Files.exists(testPath.getParent())) { - throw new IOException("Cannot create file " + testPath - + " as the parent directory does not exist"); + throw new IOException("Cannot create file " + testPath + " as the parent directory does not exist"); } try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(testPath))) { @@ -159,7 +156,7 @@ void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(testPath.getParent()); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -180,7 +177,7 @@ void testFileCleanerDirectory_NullStrategy() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(testFile.exists()); // not deleted, as dir not empty @@ -200,7 +197,7 @@ void testFileCleanerDirectoryFileSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(testFile.exists()); // not deleted, as dir not empty @@ -220,7 +217,7 @@ void testFileCleanerDirectoryPathSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(Files.exists(testPath)); // not deleted, as dir not empty @@ -267,7 +264,7 @@ void testFileCleanerExitWhenFinished1() throws Exception { testFile = null; raf = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount(), "10-Track Count"); @@ -294,7 +291,7 @@ void testFileCleanerExitWhenFinished2() throws Exception { testFile = null; r = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -318,7 +315,7 @@ void testFileCleanerExitWhenFinishedFirst() throws Exception { assertTrue(fileCleaningTracker.exitWhenFinished); assertNull(fileCleaningTracker.reaper); - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(fileCleaningTracker.exitWhenFinished); @@ -341,7 +338,7 @@ void testFileCleanerFile() throws Exception { testFile = null; raf = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -355,7 +352,7 @@ void testFileCleanerNull() { assertThrows(NullPointerException.class, () -> fileCleaningTracker.track((String) null, new Object(), FileDeleteStrategy.NORMAL)); } - private void waitUntilTrackCount() throws Exception { + private void waitUntilTrackCount0() throws Exception { System.gc(); TestUtils.sleep(500); int count = 0; @@ -365,8 +362,8 @@ private void waitUntilTrackCount() throws Exception { long i = 0; while (fileCleaningTracker.getTrackCount() != 0) { list.add( - "A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String " - + i++); + "A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String A Big String " + + i++); } } catch (final Throwable ignored) { } @@ -377,6 +374,5 @@ private void waitUntilTrackCount() throws Exception { if (fileCleaningTracker.getTrackCount() != 0) { throw new IllegalStateException("Your JVM is not releasing References, try running the test with less memory (-Xmx)"); } - } } From 8bae73649f6b6edd1411a65d286edf82bdfc8e98 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 31 Jan 2026 07:43:48 -0500 Subject: [PATCH 171/174] Better internal names --- .../io/monitor/FileAlterationMonitor.java | 2 +- .../commons/io/FileCleaningTrackerTest.java | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java index b14155fe943..630e8ed051d 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java @@ -148,7 +148,7 @@ public void run() { } try { ThreadUtils.sleep(Duration.ofMillis(intervalMillis)); - } catch (final InterruptedException ignored) { + } catch (final InterruptedException e) { Thread.currentThread().interrupt(); } } diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java index a4083a53cbb..85bfea1aa00 100644 --- a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java +++ b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java @@ -54,6 +54,11 @@ RandomAccessFile createRandomAccessFile() throws FileNotFoundException { return RandomAccessFileMode.READ_WRITE.create(testFile); } + private void gcFinalize() { + System.gc(); + System.runFinalization(); + } + protected FileCleaningTracker newInstance() { return new FileCleaningTracker(); } @@ -278,18 +283,18 @@ void testFileCleanerExitWhenFinished2() throws Exception { final String path = testFile.getPath(); assertFalse(testFile.exists()); - RandomAccessFile r = createRandomAccessFile(); + RandomAccessFile raf = createRandomAccessFile(); assertTrue(testFile.exists()); assertEquals(0, fileCleaningTracker.getTrackCount()); - fileCleaningTracker.track(path, r); + fileCleaningTracker.track(path, raf); assertEquals(1, fileCleaningTracker.getTrackCount()); assertFalse(fileCleaningTracker.exitWhenFinished); assertTrue(fileCleaningTracker.reaper.isAlive()); - r.close(); + raf.close(); testFile = null; - r = null; + raf = null; waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); @@ -306,6 +311,7 @@ void testFileCleanerExitWhenFinished2() throws Exception { } assertTrue(fileCleaningTracker.exitWhenFinished); assertFalse(fileCleaningTracker.reaper.isAlive()); + assertFalse(Files.exists(Paths.get(path))); } @Test @@ -344,6 +350,7 @@ void testFileCleanerFile() throws Exception { assertEquals(0, fileCleaningTracker.getTrackCount()); assertFalse(new File(path).exists(), showFailures()); } + @Test void testFileCleanerNull() { assertThrows(NullPointerException.class, () -> fileCleaningTracker.track((File) null, new Object())); @@ -352,6 +359,7 @@ void testFileCleanerNull() { assertThrows(NullPointerException.class, () -> fileCleaningTracker.track((String) null, new Object(), FileDeleteStrategy.NORMAL)); } + private void waitUntilTrackCount0() throws Exception { System.gc(); TestUtils.sleep(500); @@ -368,11 +376,11 @@ private void waitUntilTrackCount0() throws Exception { } catch (final Throwable ignored) { } list = null; - System.gc(); + gcFinalize(); TestUtils.sleep(1000); } if (fileCleaningTracker.getTrackCount() != 0) { throw new IllegalStateException("Your JVM is not releasing References, try running the test with less memory (-Xmx)"); } } -} + } From b44a564196068839ac48d4465a2c9ac7e4731820 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 31 Jan 2026 08:07:21 -0500 Subject: [PATCH 172/174] Javadoc --- src/main/java/org/apache/commons/io/FileCleaningTracker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index c3913f4f7c5..816bacb0f5d 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -197,7 +197,7 @@ private synchronized void addTracker(final String path, final Object marker, fin *

    *

    * For example, suppose that you have developed a web application, which - * contains the commons-io jar file in your WEB-INF/lib directory. In other + * contains the Commons IO JAR file in your WEB-INF/lib directory. In other * words, the FileCleaner class is loaded through the class loader of your * web application. If the web application is terminated, but the servlet * container is still running, then the file cleaner thread will still exist, From 6eb4fa0788649cc467d12d377f6a7e0b01431655 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 31 Jan 2026 08:41:39 -0500 Subject: [PATCH 173/174] Give test threads better names for debugging --- .../commons/io/FileCleaningTracker.java | 2 +- .../commons/io/FileUtilsWaitForTest.java | 2 +- .../io/input/QueueInputStreamTest.java | 2 +- .../apache/commons/io/input/TailerTest.java | 34 +++++++++---------- ...UnsynchronizedBufferedInputStreamTest.java | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index 816bacb0f5d..043a63c7a6a 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -54,7 +54,7 @@ private final class Reaper extends Thread { /** Constructs a new Reaper */ Reaper() { - super("File Reaper"); + super("commons-io-FileCleaningTracker-Reaper"); setPriority(MAX_PRIORITY); setDaemon(true); } diff --git a/src/test/java/org/apache/commons/io/FileUtilsWaitForTest.java b/src/test/java/org/apache/commons/io/FileUtilsWaitForTest.java index 97170323ecf..2eb2c89823b 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsWaitForTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsWaitForTest.java @@ -48,7 +48,7 @@ void testIO_488() throws InterruptedException { // This will wait (assuming the file is not found) assertFalse(FileUtils.waitFor(NOSUCHFILE, seconds), "Should not find file"); wasInterrupted.set(Thread.currentThread().isInterrupted()); - }); + }, "commos-io-Test-IO-488-Thread"); thread1.start(); Thread.sleep(500); // This should be enough to ensure the waitFor loop has been entered thread1.interrupt(); // Try to interrupt waitFor diff --git a/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java b/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java index 3ad593035b2..16639dfe245 100644 --- a/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/QueueInputStreamTest.java @@ -326,7 +326,7 @@ void testTimeoutInterrupted() throws Exception { assertTrue(Thread.currentThread().isInterrupted()); result.set(true); latch.countDown(); - }); + }, "commons-io-QueueInputStreamTest-testTimeoutInterrupted"); thread.setDaemon(true); thread.start(); diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java index 8455dc84deb..937f59755b0 100644 --- a/src/test/java/org/apache/commons/io/input/TailerTest.java +++ b/src/test/java/org/apache/commons/io/input/TailerTest.java @@ -239,7 +239,7 @@ void testBufferBreak() throws Exception { writeStrings(file, data); final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = new Tailer(file, listener, delay, false, 1)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testBufferBreak"); thread.start(); List lines = listener.getLines(); assertEquals(data.length(), tailer.getTailable().size()); @@ -347,7 +347,7 @@ void testInterrupt() throws Exception { final int delay = 1000; final int idle = 50; // allow time for thread to work try (Tailer tailer = new Tailer(file, listener, delay, false, IOUtils.DEFAULT_BUFFER_SIZE)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testInterrupt"); thread.setDaemon(true); thread.start(); TestUtils.sleep(idle); @@ -370,7 +370,7 @@ void testIO335() throws Exception { // test CR behavior createFile(file, 0); final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = new Tailer(file, listener, delayMillis, false)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testIO335"); thread.start(); // Write some lines to the file @@ -400,7 +400,7 @@ void testLongFile() throws Exception { final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = new Tailer(file, listener, delay, false)) { // final long start = System.currentTimeMillis(); - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testLongFile"); thread.start(); List lines = listener.getLines(); while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { @@ -425,7 +425,7 @@ void testMultiByteBreak() throws Exception { // Need to use UTF-8 to read & write the file otherwise it can be corrupted (depending on the default charset) final Charset charsetUTF8 = StandardCharsets.UTF_8; try (Tailer tailer = new Tailer(file, charsetUTF8, listener, delay, false, isWindows, IOUtils.DEFAULT_BUFFER_SIZE)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testMultiByteBreak"); thread.start(); try (Writer out = new OutputStreamWriter(Files.newOutputStream(file.toPath()), charsetUTF8); BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(origin.toPath()), charsetUTF8))) { @@ -458,7 +458,7 @@ void testSimpleConstructor() throws Exception { createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructor"); thread.start(); validateTailer(listener, file); } @@ -470,7 +470,7 @@ void testSimpleConstructorWithDelay() throws Exception { createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelay"); thread.start(); validateTailer(listener, file); } @@ -482,7 +482,7 @@ void testSimpleConstructorWithDelayAndFromStart() throws Exception { createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelayAndFromStart"); thread.start(); validateTailer(listener, file); } @@ -494,7 +494,7 @@ void testSimpleConstructorWithDelayAndFromStartWithBufferSize() throws Exception createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelayAndFromStartWithBufferSize"); thread.start(); validateTailer(listener, file); } @@ -506,7 +506,7 @@ void testSimpleConstructorWithDelayAndFromStartWithReopen() throws Exception { createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, false)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelayAndFromStartWithReopen"); thread.start(); validateTailer(listener, file); } @@ -518,7 +518,7 @@ void testSimpleConstructorWithDelayAndFromStartWithReopenAndBufferSize() throws createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelayAndFromStartWithReopenAndBufferSize"); thread.start(); validateTailer(listener, file); } @@ -530,7 +530,7 @@ void testSimpleConstructorWithDelayAndFromStartWithReopenAndBufferSizeAndCharset createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); try (Tailer tailer = new Tailer(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testSimpleConstructorWithDelayAndFromStartWithReopenAndBufferSizeAndCharset"); thread.start(); validateTailer(listener, file); } @@ -587,7 +587,7 @@ void testTailer() throws Exception { final String osname = SystemProperties.getOsName(); final boolean isWindows = osname.startsWith("Windows"); try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testTailer"); thread.start(); // Write some lines to the file writeLines(file, "Line one", "Line two"); @@ -649,7 +649,7 @@ void testTailerEndOfFileReached() throws Exception { final String osname = SystemProperties.getOsName(); final boolean isWindows = osname.startsWith("Windows"); try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testTailerEndOfFileReached"); thread.start(); // write a few lines writeLines(file, "line1", "line2", "line3"); @@ -673,7 +673,7 @@ void testTailerEof() throws Exception { createFile(file, 0); final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = new Tailer(file, listener, delayMillis, false)) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testTailerEof"); thread.start(); // Write some lines to the file writeStrings(file, "Line"); @@ -698,7 +698,7 @@ void testTailerIgnoreTouch() throws Exception { final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = Tailer.builder().setFile(file).setTailerListener(listener).setDelayDuration(Duration.ofMillis(delayMillis)).setStartThread(false) .setIgnoreTouch(true).get()) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testTailerIgnoreTouch"); thread.start(); // Write some lines to the file writeLines(file, "Line one"); @@ -724,7 +724,7 @@ void testTailerReissueOnTouch() throws Exception { final TestTailerListener listener = new TestTailerListener(); try (Tailer tailer = Tailer.builder().setFile(file).setTailerListener(listener).setDelayDuration(Duration.ofMillis(delayMillis)).setStartThread(false) .setIgnoreTouch(false).get()) { - final Thread thread = new Thread(tailer); + final Thread thread = new Thread(tailer, "commons-io-tailer-testTailerReissueOnTouch"); thread.start(); // Write some lines to the file writeLines(file, "Line one"); diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java index ee1e2e983fc..1566dbc06ef 100644 --- a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java @@ -148,7 +148,7 @@ public int read(final byte[] buf, final int offset, final int length) { } catch (final Exception e) { // Ignored } - }); + }, "commons-io-UnsynchronizedBufferedInputStream-close"); thread.start(); assertThrows(IOException.class, () -> bufin.read(new byte[100], 0, 99), "Should throw IOException"); } From 107ca91f7844097532473470d14a93c5c33c5d25 Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 31 Jan 2026 08:41:47 -0500 Subject: [PATCH 174/174] Give threads better names for debugging --- src/main/java/org/apache/commons/io/ThreadMonitor.java | 2 +- .../org/apache/commons/io/monitor/FileAlterationMonitor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/apache/commons/io/ThreadMonitor.java b/src/main/java/org/apache/commons/io/ThreadMonitor.java index 24ebe705a1d..f9fe24957c5 100644 --- a/src/main/java/org/apache/commons/io/ThreadMonitor.java +++ b/src/main/java/org/apache/commons/io/ThreadMonitor.java @@ -60,7 +60,7 @@ static Thread start(final Thread thread, final Duration timeout) { if (timeout.isZero() || timeout.isNegative()) { return null; } - final Thread monitor = new Thread(new ThreadMonitor(thread, timeout), ThreadMonitor.class.getSimpleName()); + final Thread monitor = new Thread(new ThreadMonitor(thread, timeout), "commons-io-ThreadMonitor"); monitor.setDaemon(true); monitor.start(); return monitor; diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java index 630e8ed051d..ab3a65b9416 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java +++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java @@ -179,7 +179,7 @@ public synchronized void start() throws Exception { if (threadFactory != null) { thread = threadFactory.newThread(this); } else { - thread = new Thread(this); + thread = new Thread(this, "commons-io-FileAlterationMonitor"); } thread.start(); }