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 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" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7578b4da036..9ff35c83e79 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -23,8 +23,8 @@ 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 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. diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index fcc16fe390a..c46b8e23195 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -50,10 +50,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 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') }} @@ -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@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@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + 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@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 1e043924237..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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 'Dependency Review PR' - uses: actions/dependency-review-action@595b5aeba73380359d98a5e087f648dbb0edce1b # v4.7.3 + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 7d0f0892434..f596ab8bef1 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -38,8 +38,8 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-13] - java: [ 8, 11, 17, 21 ] + os: [ubuntu-latest, windows-latest, macos-latest] + 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 @@ -70,19 +60,19 @@ jobs: experimental: true fail-fast: false steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 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') }} restore-keys: | ${{ runner.os }}-maven- - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index cf4d6ba87b0..6a7fedc37ca 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -42,12 +42,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: 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 @@ -59,13 +59,13 @@ jobs: publish_results: true - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: SARIF file path: results.sarif retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5 + uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: sarif_file: results.sarif 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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f708680735d..e924b4ac04e 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. @@ -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/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/). diff --git a/README.md b/README.md index bb31ce854a6..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.20.0.svg)](https://javadoc.io/doc/commons-io/commons-io/2.20.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.20.0 + 2.22.0 ``` @@ -90,7 +90,7 @@ There are some guidelines which will make applying PRs easier for us: + Respect the existing code style for each file. + 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. + Provide JUnit tests for your changes and make sure your changes don't break any existing tests by running `mvn`. -+ Before you pushing a PR, run `mvn` (by itself), this runs the default goal, which contains all build checks. ++ Before you push a PR, run `mvn` (without arguments). This runs the default goal which contains all build checks. + To see the code coverage report, regardless of coverage failures, run `mvn clean site -Dcommons.jacoco.haltOnFailure=false -Pjacoco` If you plan to contribute on a regular basis, please consider filing a [contributor license agreement](https://www.apache.org/licenses/#clas). @@ -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 1f30f8b0f5a..5daadd53bfc 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,4 +1,191 @@ +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.closeQuietlySuppress(Closeable, Throwable) #818. Thanks to Gary Gregory, Piotr P. Karwasz. + +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 +---------- + +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. + +Introduction +------------ + +The Apache Commons IO library contains utility classes, stream implementations, file filters, +file comparators, endian transformation classes, and much more. + +Version 2.21.0: Java 8 or later is required. + +New features +------------ + +o FileUtils#byteCountToDisplaySize() supports Zettabyte, Yottabyte, Ronnabyte and Quettabyte #763. Thanks to strangelookingnerd, Gary Gregory. +o Add org.apache.commons.io.FileUtils.ONE_RB #763. Thanks to strangelookingnerd, Gary Gregory. +o Add org.apache.commons.io.FileUtils.ONE_QB #763. Thanks to strangelookingnerd, Gary Gregory. +o Add org.apache.commons.io.output.ProxyOutputStream.writeRepeat(byte[], int, int, long). Thanks to Gary Gregory. +o Add org.apache.commons.io.output.ProxyOutputStream.writeRepeat(byte[], long). Thanks to Gary Gregory. +o Add org.apache.commons.io.output.ProxyOutputStream.writeRepeat(int, long). Thanks to Gary Gregory. +o Add length unit support in FileSystem limits. Thanks to Piotr P. Karwasz. +o Add IOUtils.toByteArray(InputStream, int, int) for safer chunked reading with size validation. Thanks to Piotr P. Karwasz. +o Add org.apache.commons.io.file.PathUtils.getPath(String, String). Thanks to Gary Gregory. +o Add org.apache.commons.io.channels.ByteArraySeekableByteChannel. Thanks to Gary Gregory. +o Add IOIterable.asIterable(). Thanks to Gary Gregory. +o Add NIO channel support to `AbstractStreamBuilder`. Thanks to Piotr P. Karwasz. +o Add CloseShieldChannel to close-shielded NIO Channels #786. Thanks to Piotr P. Karwasz. +o Added IOUtils.checkFromIndexSize as a Java 8 backport of Objects.checkFromIndexSize #790. Thanks to Piotr P. Karwasz. + +Fixed Bugs +---------- + +o When testing on Java 21 and up, enable -XX:+EnableDynamicAgentLoading. Thanks to Gary Gregory. +o When testing on Java 24 and up, don't fail FileUtilsListFilesTest for a different behavior in the JRE. Thanks to Gary Gregory. +o ValidatingObjectInputStream does not validate dynamic proxy interfaces. Thanks to Stanislav Fort, Gary Gregory. +o BoundedInputStream.getRemaining() now reports Long.MAX_VALUE instead of 0 when no limit is set. Thanks to Piotr P. Karwasz. +o BoundedInputStream.available() correctly accounts for the maximum read limit. Thanks to Piotr P. Karwasz. +o Deprecate IOUtils.readFully(InputStream, int) in favor of toByteArray(InputStream, int). Thanks to Gary Gregory, Piotr P. Karwasz. +o IOUtils.toByteArray(InputStream) now throws IOException on byte array overflow. Thanks to Piotr P. Karwasz. +o Javadoc general improvements. Thanks to Gary Gregory, Piotr P. Karwasz. +o IOUtils.toByteArray() now throws EOFException when not enough data is available #796. Thanks to Piotr P. Karwasz. +o Fix IOUtils.skip() usage in concurrent scenarios. Thanks to Piotr P. Karwasz. +o [javadoc] Fix XmlStreamReader Javadoc to indicate the correct class that is built #806. Thanks to J Hawkins. + +Changes +------- + +o Bump org.apache.commons:commons-parent from 85 to 91 #774, #783, #808. Thanks to Gary Gregory, Dependabot. +o [test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0. Thanks to Gary Gregory. +o [test] Bump commons.bytebuddy.version from 1.17.6 to 1.17.8 #769. Thanks to Gary Gregory, Dependabot. +o [test] Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. Thanks to Gary Gregory. + +Removed +------- + +o Inline private constant field ProxyInputStream.exceptionHandler #780. Thanks to Piotr P. Karwasz. +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.20.0 Release Notes The Apache Commons IO team is pleased to announce the release of Apache Commons IO 2.20.0. diff --git a/pom.xml b/pom.xml index c356baf502a..8827b9d8aa0 100644 --- a/pom.xml +++ b/pom.xml @@ -19,12 +19,12 @@ org.apache.commons commons-parent - 88 + 96 4.0.0 commons-io commons-io - 2.21.0-SNAPSHOT + 2.22.0-SNAPSHOT Apache Commons IO 2002 @@ -32,10 +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/ - - jira - https://issues.apache.org/jira/browse/IO - apache.website @@ -43,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 @@ -93,13 +79,13 @@ file comparators, endian transformation classes, and much more. org.apache.commons commons-lang3 - 3.19.0 + 3.20.0 test commons-codec commons-codec - 1.19.0 + 1.21.0 test @@ -114,12 +100,12 @@ file comparators, endian transformation classes, and much more. 1.8 io org.apache.commons.io - RC1 - 2.20.0 - 2.21.0 - 2.21.1 + RC2 + 2.21.0 + 2.22.0 + 2.22.1 - 2025-07-18T21:12:04Z + 2025-11-06T21:58:17Z (requires Java 8) IO 12310477 @@ -146,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.17.7 + 1.18.4 false true @@ -170,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 fb68216e20a..bc9d1ce9088 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -45,7 +45,27 @@ 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. + 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. + 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. + + Bump org.apache.commons:commons-parent from 91 to 96 #816. + 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. + + 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. @@ -55,6 +75,9 @@ 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. + 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. @@ -71,9 +94,9 @@ 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 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.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. 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. - diff --git a/src/main/java/org/apache/commons/io/ByteOrderMark.java b/src/main/java/org/apache/commons/io/ByteOrderMark.java index 0067f7d2d6f..b9209cb316f 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 */ @@ -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 ad426952e4e..ed816826305 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}, @@ -44,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 @@ -115,9 +117,10 @@ 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); @@ -128,10 +131,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 { @@ -143,12 +146,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 + * 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); @@ -159,10 +162,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(); @@ -179,13 +182,13 @@ 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 - * @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( @@ -201,12 +204,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 + * 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, @@ -221,13 +224,13 @@ 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 - * @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( @@ -246,12 +249,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 + * 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( @@ -269,23 +272,25 @@ 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, 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; + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] buffer = scratch.array(); + int count = 0; + int n; + while (EOF != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; } - return count; } /** @@ -293,13 +298,13 @@ 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 - * @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( @@ -320,12 +325,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 + * 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( @@ -344,9 +349,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 ac3d8bd5fd7..1d2a7678fd4 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: @@ -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) {
@@ -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;
 
@@ -272,8 +273,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);
@@ -284,9 +285,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 canceled.
+         * @param depth  the depth when the operation was canceled.
          */
         public CancelException(final String message, final File file, final int depth) {
             super(message);
@@ -295,23 +296,24 @@ 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;
         }
     }
+
     /**
      * The file filter to use to filter files and directories.
      */
@@ -338,9 +340,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 +359,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) { @@ -376,7 +378,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 @@ -385,10 +387,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 +405,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. @@ -417,18 +419,18 @@ 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. *

* 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 +449,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 +468,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 +485,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 +502,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 +516,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 { @@ -526,7 +528,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 +536,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,23 +552,23 @@ 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. *

* - * @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 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 } /** @@ -575,10 +577,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 +594,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 +615,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 +634,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..cae06b8345e 100644 --- a/src/main/java/org/apache/commons/io/EndianUtils.java +++ b/src/main/java/org/apache/commons/io/EndianUtils.java @@ -50,9 +50,10 @@ 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 +66,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 +78,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 +89,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 +101,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 +112,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 +128,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 +143,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 +158,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 +173,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 +186,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 +198,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 +215,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 +233,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 +246,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 +264,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 +274,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 +284,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 +298,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 +316,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 +327,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 +341,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 +353,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 +364,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 +376,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 +387,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 +403,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 +417,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 +437,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 +455,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 +469,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..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, @@ -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 @@ -76,7 +77,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 +87,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 +100,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 +115,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 +131,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 +146,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..043a63c7a6a 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -21,14 +21,14 @@ 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 + * 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. @@ -51,9 +51,10 @@ public class FileCleaningTracker { * The reaper thread. */ private final class Reaper extends Thread { + /** Constructs a new Reaper */ Reaper() { - super("File Reaper"); + super("commons-io-FileCleaningTracker-Reaper"); setPriority(MAX_PRIORITY); setDaemon(true); } @@ -68,13 +69,15 @@ 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()); } tracker.clear(); } catch (final InterruptedException e) { + // interrupted removing from the queue. + interrupt(); continue; } } @@ -99,15 +102,14 @@ 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) { + 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; } @@ -124,7 +126,7 @@ public boolean delete() { /** * Gets the path. * - * @return the path + * @return the path. */ public String getPath() { return path; @@ -134,12 +136,12 @@ 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. */ - final Collection trackers = Collections.synchronizedSet(new HashSet<>()); // synchronized + final Set trackers = Collections.synchronizedSet(new HashSet<>()); // synchronized /** * Collection of File paths that failed to delete. @@ -166,13 +168,13 @@ 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. + * @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"); } @@ -180,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)); } /** @@ -192,21 +194,24 @@ 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 + * 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, * 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) { @@ -218,7 +223,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 +234,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 +245,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 +258,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 +273,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 +287,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 +303,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,13 +316,12 @@ 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 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); } diff --git a/src/main/java/org/apache/commons/io/FileDeleteStrategy.java b/src/main/java/org/apache/commons/io/FileDeleteStrategy.java index 62cf28c1631..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() { @@ -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 4169e1a53b1..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 @@ -266,7 +267,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 +285,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 +295,8 @@ public static FileSystem getCurrent() { * Decides if the operating system matches. * * @param osNamePrefix - * the prefix for the os 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 +310,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 +346,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 203fe84bfc5..c7c0d1ad19c 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 @@ -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 *
  • No exceptions are thrown when a file or directory cannot be deleted.
  • * * - * @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. @@ -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.closeQuietlySuppress(inputStream, ex); throw ex; } } @@ -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 @@ -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. @@ -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) @@ -3501,12 +3501,12 @@ 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 - * @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 { @@ -3514,14 +3514,14 @@ 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 - * @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..416720a02f8 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); @@ -231,10 +233,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); @@ -280,29 +282,23 @@ 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)) { - return false; - } - - if (IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) { + if (isEmpty(canonicalParent) || isEmpty(canonicalChild) || 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); } /** * 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 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; } @@ -311,7 +307,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; @@ -320,7 +316,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++; } @@ -330,10 +326,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,19 +350,17 @@ 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) { return null; } - requireNonNullChars(fileName); - int size = fileName.length(); if (size == 0) { return fileName; @@ -375,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++) { @@ -386,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 @@ -404,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; } @@ -417,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; } @@ -430,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); @@ -445,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 } /** @@ -465,9 +446,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,15 +459,14 @@ 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) { - if (fileName1 == null || fileName2 == null) { return fileName1 == null && fileName2 == null; } @@ -510,9 +490,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 +508,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 +524,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 +552,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 +589,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 +662,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 +695,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 +720,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 +753,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 +784,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 +819,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 +878,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 +959,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 +988,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,17 +1012,16 @@ 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) { return false; } requireNonNullChars(fileName); - if (extensions == null || extensions.isEmpty()) { return indexOfExtension(fileName) == NOT_FOUND; } @@ -1056,17 +1035,16 @@ 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; } @@ -1132,8 +1103,8 @@ private static boolean isIPv4Address(final String name) { /** * Checks whether a given string represents a valid IPv6 address. * - * @param inet6Address the name to validate - * @return true if the given name is a valid IPv6 address + * @param inet6Address the name to validate. + * @return true if the given name is a valid IPv6 address. */ private static boolean isIPv6Address(final String inet6Address) { final boolean containsCompressedZeroes = inet6Address.contains("::"); @@ -1200,8 +1171,8 @@ private static boolean isIPv6Address(final String inet6Address) { * RFC 3986 - not accepting IP addresses. * * @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 isRFC3986HostName(final String name) { final String[] parts = name.split("\\.", -1); @@ -1220,8 +1191,8 @@ private static boolean isRFC3986HostName(final String name) { /** * Checks if the character is a separator. * - * @param ch the character to check - * @return true if it is a separator character + * @param ch the character to check. + * @return true if it is a separator character. */ private static boolean isSeparator(final char ch) { return ch == UNIX_NAME_SEPARATOR || ch == WINDOWS_NAME_SEPARATOR; @@ -1230,7 +1201,7 @@ private static boolean isSeparator(final char ch) { /** * Determines if Windows file system is in use. * - * @return true if the system is Windows + * @return true if the system is Windows. */ static boolean isSystemWindows() { return SYSTEM_NAME_SEPARATOR == WINDOWS_NAME_SEPARATOR; @@ -1245,8 +1216,8 @@ static boolean isSystemWindows() { * valid names in UNC paths.

    * * @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 +1259,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 +1305,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 +1354,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 +1399,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,16 +1426,15 @@ 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) { return null; } requireNonNullChars(fileName); - final int index = indexOfExtension(fileName); if (index == NOT_FOUND) { return fileName; @@ -1477,9 +1447,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,17 +1494,15 @@ 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 // 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(); @@ -1558,7 +1526,6 @@ static String[] splitOnTokens(final String text) { if (buffer.length() != 0) { list.add(buffer.toString()); } - return list.toArray(EMPTY_STRING_ARRAY); } @@ -1589,9 +1556,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 +1573,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) { @@ -1625,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()) { @@ -1634,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++; @@ -1645,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) { @@ -1664,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; } @@ -1707,9 +1664,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 cb7efa7b2f2..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, @@ -169,19 +169,19 @@ 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 - * @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/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/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 a882d4d87cb..3cd6e9cb995 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -81,25 +81,20 @@ * 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. - * 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 @@ *

  • {@link #copyLarge(Reader, Writer, char[])}
  • *
  • {@link #copyLarge(Reader, Writer, long, long, char[])}
  • * - * 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. @@ -132,6 +123,142 @@ 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 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 (ScratchBytes scratch = ScratchBytes.get()) {
    +     *     // use the buffer
    +     *     byte[] bytes = scratch.array();
    +     *     // ...
    +     * }
    +     * }
    + */ + static final class ScratchBytes implements AutoCloseable { + + /** + * Wraps an internal byte array. [0] boolean in use. [1] byte[] buffer. + */ + 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. + * + * @return the internal byte array buffer. + */ + static ScratchBytes get() { + final Object[] holder = LOCAL.get(); + // If already in use, return a new array + if ((boolean) holder[0]) { + return new ScratchBytes(byteArray()); + } + holder[0] = true; + return INSTANCE; + } + + /** + * The buffer, or null if using the thread-local buffer. + */ + private final byte[] buffer; + + private ScratchBytes(final byte[] buffer) { + this.buffer = buffer; + } + + byte[] array() { + return buffer != null ? buffer : (byte[]) LOCAL.get()[1]; + } + + /** + * If the buffer is the internal array, clear and release it for reuse. + */ + @Override + public void close() { + if (buffer == null) { + final Object[] holder = LOCAL.get(); + Arrays.fill((byte[]) holder[1], (byte) 0); + holder[0] = false; + } + } + } + + /** + * 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, charArray() }); + + private static final ScratchChars INSTANCE = new ScratchChars(null); + + /** + * Gets the internal char array buffer. + * + * @return the internal char array buffer. + */ + 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 INSTANCE; + } + + /** + * The buffer, or null if using the thread-local buffer. + */ + private final char[] buffer; + + private ScratchChars(final char[] buffer) { + this.buffer = buffer; + } + + char[] array() { + return buffer != null ? buffer : (char[]) LOCAL.get()[1]; + } + + /** + * If the buffer is the internal array, clear and release it for reuse. + */ + @Override + public void close() { + if (buffer == null) { + final Object[] holder = LOCAL.get(); + Arrays.fill((char[]) holder[1], (char) 0); + holder[0] = false; + } + } + } + /** * CR char '{@value}'. * @@ -162,12 +289,13 @@ public class IOUtils { /** * 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; @@ -201,26 +329,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. *

    @@ -232,8 +340,7 @@ public class IOUtils { 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. @@ -245,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 @@ -264,16 +369,14 @@ 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 + * @return the given OutputStream or a new {@link BufferedOutputStream} for the given OutputStream. * @throws NullPointerException if the input parameter is null. * @since 2.5 */ @@ -282,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 @@ -301,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. @@ -319,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 @@ -333,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. @@ -346,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 @@ -370,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. @@ -394,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. @@ -408,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) {
    @@ -438,13 +534,14 @@ 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) - * @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 @@ -455,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);
    @@ -485,13 +586,14 @@ 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) - * @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 @@ -500,21 +602,31 @@ 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, %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) {
    @@ -522,13 +634,14 @@ public static void checkFromIndexSize(final char[] array, final int off, final i
          *     }
          *     // perform write...
          * }
    -     * 
    + *
    + *
    * - * @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 */ @@ -536,40 +649,40 @@ public static void checkFromIndexSize(final String str, final int off, final int checkFromIndexSize(off, len, Objects.requireNonNull(str, "str").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, %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) - * @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 */ @@ -589,13 +702,12 @@ static void checkFromToIndex(final int fromIndex, final int toIndex, final int l *
  • Removes the current thread's value for thread-local variables.
  • *
  • Sets static scratch arrays to 0s.
  • * + * * @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); + ScratchBytes.LOCAL.remove(); + ScratchChars.LOCAL.remove(); } /** @@ -626,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 */ @@ -664,18 +776,17 @@ 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); } /** * 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 {
    @@ -691,6 +802,7 @@ private static void closeQ(final Closeable closeable) {
          * 

    * Closing all streams: *

    + * *
          * try {
          *     return IOUtils.copy(inputStream, outputStream);
    @@ -708,7 +820,7 @@ 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);
         }
     
         /**
    @@ -716,17 +828,14 @@ public static void closeQuietly(final Closeable closeable) {
          * 

    * 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 {
    @@ -740,8 +849,8 @@ public static void closeQuietly(final Closeable closeable) {
          * }
          * 
    *

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

          * try {
          *     return IOUtils.copy(inputStream, outputStream);
    @@ -752,6 +861,7 @@ public static void closeQuietly(final Closeable closeable) {
          * 

    * 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 @@ -767,7 +877,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) { @@ -785,24 +895,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. @@ -834,20 +944,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 {
    @@ -868,24 +977,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. @@ -901,23 +1010,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. @@ -934,23 +1042,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. @@ -967,23 +1075,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. @@ -1016,23 +1124,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. @@ -1045,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 closeQuietlySuppress(final Closeable closeable, final T throwable) { + closeQuietly(closeable, (Consumer) throwable::addSuppressed); + return throwable; + } + /** * Consumes bytes from a {@link InputStream} and ignores them. *

    @@ -1054,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 { @@ -1070,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 { @@ -1078,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 { @@ -1107,10 +1244,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; } } @@ -1127,7 +1261,7 @@ 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 { @@ -1137,39 +1271,38 @@ public static boolean contentEquals(final Reader input1, final Reader input2) th if (input1 == null || input2 == null) { return false; } - - // reuse one - final char[] array1 = 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 (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] array1 = scratch.array(); + 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; + } + 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; } } } @@ -1198,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 @@ -1229,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 { @@ -1248,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 { @@ -1268,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 {@link 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. @@ -1291,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. @@ -1313,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. @@ -1342,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: @@ -1352,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. @@ -1373,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. @@ -1397,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. @@ -1421,7 +1537,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 {@link Charset#defaultCharset() default charset}, + * 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}. @@ -1438,7 +1554,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 { @@ -1478,7 +1594,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. @@ -1502,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. @@ -1536,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 { @@ -1559,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 { @@ -1574,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; @@ -1629,58 +1736,53 @@ 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. * @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 { + try (ScratchBytes scratch = ScratchBytes.get()) { + return copyLarge(input, output, inputOffset, length, scratch.array()); + } } /** - * 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); } @@ -1708,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}. @@ -1723,22 +1824,23 @@ 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()); + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + return copyLarge(reader, writer, scratch.array()); + } } /** * 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. * @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 { @@ -1770,7 +1872,9 @@ 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()); + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + return copyLarge(reader, writer, inputOffset, length, scratch.array()); + } } /** @@ -1817,84 +1921,18 @@ 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; } } - /** - * 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. * @@ -1940,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. @@ -1975,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. @@ -2013,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);
          * }
          * 
    * @@ -2046,15 +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 IOException if a read error occurs. + * @throws NullPointerException if {@code input} or {@code buffer} is null. + * @throws IOException if a read error occurs. * @since 2.2 */ public static int read(final InputStream input, final byte[] buffer) throws IOException { @@ -2064,50 +2096,26 @@ 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 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 - */ - 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 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 IllegalArgumentException if length is negative. - * @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 */ - 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); - } + 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) { 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; } @@ -2119,12 +2127,11 @@ static int read(final IOTriFunction input, fi /** * 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. @@ -2144,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. @@ -2162,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. @@ -2172,15 +2177,13 @@ 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 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 { - if (length < 0) { - throw new IllegalArgumentException("Length must not be negative: " + length); - } + 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) { final int location = length - remaining; @@ -2196,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 IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. - * @throws EOFException if the number of bytes read was incorrect. + * @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 { @@ -2214,21 +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 IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. - * @throws EOFException if the number of bytes read was incorrect. + * @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); @@ -2238,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. @@ -2259,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. @@ -2280,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 IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. - * @throws EOFException if the number of characters read was incorrect. + * @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 { @@ -2298,21 +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 IOException if there is a problem reading the file. - * @throws IllegalArgumentException if length is negative. - * @throws EOFException if the number of characters read was incorrect. + * @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); @@ -2334,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 {@link 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. @@ -2346,7 +2348,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 { @@ -2354,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. @@ -2373,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. @@ -2397,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. @@ -2437,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. @@ -2454,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. @@ -2471,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. @@ -2501,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. @@ -2543,7 +2538,9 @@ 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); + try (ScratchBytes scratch = ScratchBytes.get()) { + return skip(input, skip, scratch::array); + } } /** @@ -2563,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. @@ -2595,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. @@ -2625,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. @@ -2650,14 +2642,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; - 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; + 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(chars, 0, (int) Math.min(remain, chars.length)); + if (n < 0) { // EOF + break; + } + remain -= n; } - remain -= n; } return toSkip - remain; } @@ -2665,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. @@ -2683,7 +2675,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); } @@ -2725,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. @@ -2745,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. @@ -2819,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. @@ -2833,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) @@ -2849,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 @@ -2871,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}. @@ -2891,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. @@ -2914,25 +2899,26 @@ 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(); } /** * 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}. @@ -2946,7 +2932,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); } @@ -2955,14 +2941,15 @@ 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 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 { 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; @@ -2974,17 +2961,15 @@ static byte[] toByteArray(final IOTriFunction offset += read; } if (offset != size) { - throw new IOException("Unexpected read size, current: " + offset + ", expected: " + size); + throw new EOFException(String.format("Expected read size: %,d, actual: %,d", size, offset)); } return data; } /** - * Gets the contents of a {@link Reader} as a {@code byte[]} - * using the virtual machine's {@link 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. @@ -2999,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. @@ -3021,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. @@ -3045,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 {@link 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()}. *

    @@ -3096,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 { @@ -3106,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 {@link 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. @@ -3118,7 +3095,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 { @@ -3126,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. @@ -3174,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. @@ -3191,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 {@link 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. @@ -3205,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 @@ -3218,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. @@ -3236,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 {@link 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. @@ -3250,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 @@ -3263,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. @@ -3281,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 {@link 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. @@ -3296,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. @@ -3313,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 {@link 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. @@ -3332,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. @@ -3354,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. @@ -3399,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. @@ -3426,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. @@ -3443,7 +3390,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. @@ -3459,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. @@ -3472,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. @@ -3484,7 +3431,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. @@ -3500,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. @@ -3513,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. @@ -3533,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 {@link 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. @@ -3561,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. @@ -3584,7 +3526,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)}. @@ -3605,7 +3547,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. @@ -3616,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()); } @@ -3643,7 +3584,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)}. @@ -3657,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)); } @@ -3692,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()); } @@ -3710,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); } @@ -3720,7 +3658,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)}. @@ -3734,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. @@ -3755,34 +3692,31 @@ 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}. + * 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. * @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) - 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. @@ -3799,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. @@ -3838,49 +3769,45 @@ 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 + * @throws IOException if an I/O error occurs. * @since 1.1 * @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)); } @@ -3889,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. @@ -3897,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()); @@ -3905,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; @@ -3955,7 +3879,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. @@ -3963,7 +3887,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 { @@ -4009,7 +3933,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. @@ -4051,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 */ @@ -4076,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/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java index 293847e7a72..fd07e9325c9 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) { @@ -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() { @@ -135,16 +135,16 @@ public boolean hasNext() { } } } catch (final IOException ioe) { - IOUtils.closeQuietly(this, ioe::addSuppressed); - throw new IllegalStateException(ioe); + throw new IllegalStateException(IOUtils.closeQuietlySuppress(this, ioe)); } } /** * 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; @@ -153,8 +153,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() { @@ -164,8 +164,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 @@ -181,7 +181,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..f9fe24957c5 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. */ @@ -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; @@ -104,6 +104,7 @@ public void run() { thread.interrupt(); } catch (final InterruptedException ignored) { // timeout not reached + Thread.currentThread().interrupt(); } } } 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/build/AbstractOrigin.java b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java index d84aefdb79a..341c442a657 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() { @@ -1090,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 */ @@ -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 { @@ -1162,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. @@ -1174,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. @@ -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(); } @@ -1224,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/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/channels/ByteArraySeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java index 4135a815e83..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[]) @@ -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/main/java/org/apache/commons/io/channels/CloseShieldChannel.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java index a9a462da73b..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 @@ -40,11 +63,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 (CloseShieldChannelHandler.isSupported(iface) && out.add(iface)) { + collectChannelInterfaces(iface, out); + } } + currentType = currentType.getSuperclass(); } return out; } @@ -53,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..fdafd544f07 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,41 @@ 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); + } + /** * Tests whether the given method is allowed to be called after the shield is closed. * @@ -42,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/main/java/org/apache/commons/io/channels/FileChannels.java b/src/main/java/org/apache/commons/io/channels/FileChannels.java index 30a80e8ab6b..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; } } @@ -135,7 +132,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/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/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..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 { @@ -88,7 +89,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 +98,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 +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/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/doc-files/leaf.svg b/src/main/java/org/apache/commons/io/doc-files/leaf.svg new file mode 100644 index 00000000000..71de588c648 --- /dev/null +++ b/src/main/java/org/apache/commons/io/doc-files/leaf.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + \ No newline at end of file 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 00000000000..02a758f0ed8 Binary files /dev/null and b/src/main/java/org/apache/commons/io/doc-files/logo.png differ 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..3be7a325315 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) { @@ -251,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) { @@ -265,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 055bbe06a0b..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. * @@ -378,7 +387,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 +402,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 +419,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...) */ @@ -499,7 +508,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 +527,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 +549,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} @@ -603,7 +612,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 +780,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 +953,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 +1145,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 +1249,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 +1310,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. @@ -1412,7 +1421,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) { @@ -1425,7 +1434,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 +1836,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 +1966,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/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) { 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..f7ec25a1f3e 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); @@ -129,6 +129,7 @@ public boolean accept(final File file, final String name) { /** * {@inheritDoc} + * * @since 2.9.0 */ @Override @@ -187,7 +188,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..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,13 +39,14 @@ public class DelegateFileFilter extends AbstractFileFilter implements Serializab /** The File filter */ private final transient FileFilter fileFilter; + /** The Filename filter */ private final transient FilenameFilter fileNameFilter; /** * 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 +57,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 +68,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 +82,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 +97,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 5e37676ac9c..74715ef6158 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,12 +148,12 @@ 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...)} + * @deprecated Use {@link #and(IOFileFilter...)} */ @Deprecated public static IOFileFilter andFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { @@ -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() { @@ -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) { @@ -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}. */ @@ -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 @@ -495,8 +499,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 +510,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 +525,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 +542,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 +553,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 +564,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 +577,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 +589,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,12 +602,12 @@ 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...)} + * @deprecated Use {@link #or(IOFileFilter...)} */ @Deprecated public static IOFileFilter orFileFilter(final IOFileFilter filter1, final IOFileFilter filter2) { @@ -613,8 +617,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 +628,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 +641,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 +653,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 +667,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 +682,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 +693,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 +706,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 +719,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/MagicNumberFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java index 79aa55d68c1..3f28a7661cd 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. @@ -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/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..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 */ @@ -87,9 +88,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 +178,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/IOIterable.java b/src/main/java/org/apache/commons/io/function/IOIterable.java index 238040d1d65..dd656dff7dd 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 { @@ -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 42cc235fc39..85727a6e431 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; @@ -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/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/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/BoundedReader.java b/src/main/java/org/apache/commons/io/input/BoundedReader.java index 5c1c255c0fe..e3eefe3b57b 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,33 +78,26 @@ 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 public void mark(final int readAheadLimit) throws IOException { this.readAheadLimit = readAheadLimit - charsRead; - markedAt = charsRead; - target.mark(readAheadLimit); } /** * 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 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++; @@ -114,13 +107,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 +133,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..aefd00e597e 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 @@ -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(); @@ -269,7 +266,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/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/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/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/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/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.
    • *
    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..9d53d007651 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. @@ -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 @@ -110,7 +111,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 +123,8 @@ 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 +138,8 @@ 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 +148,8 @@ 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 +167,9 @@ 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 +187,11 @@ 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 +209,9 @@ 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 +230,8 @@ 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 @@ -236,6 +246,7 @@ public boolean ready() throws IOException { /** * Invokes the delegate's {@code reset()} method. + * * @throws IOException if an I/O error occurs. */ @Override @@ -249,8 +260,9 @@ 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/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. 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..152cd42a586 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; @@ -63,6 +62,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 +92,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 +110,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) { @@ -203,7 +208,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. @@ -215,7 +220,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. @@ -228,7 +233,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. @@ -239,7 +244,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; @@ -287,21 +292,21 @@ public void close() throws IOException { } finally { stateChangeLock.unlock(); } - if (shutdownExecutorService) { try { - executorService.shutdownNow(); - executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); + shutdownAwait(); } catch (final InterruptedException e) { - final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); - iio.initCause(e); - throw iio; + Thread.currentThread().interrupt(); + throw Input.toInterruptedIOException(e); } finally { if (isSafeToCloseUnderlyingInputStream) { super.close(); } } } + if (isSafeToCloseUnderlyingInputStream) { + super.close(); + } } private void closeUnderlyingInputStreamIfNecessary() { @@ -346,7 +351,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(); @@ -459,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 { @@ -532,7 +541,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; @@ -550,9 +559,8 @@ private void waitForAsyncReadComplete() throws IOException { asyncReadComplete.await(); } } catch (final InterruptedException e) { - final InterruptedIOException iio = new InterruptedIOException(e.getMessage()); - iio.initCause(e); - throw iio; + Thread.currentThread().interrupt(); + throw Input.toInterruptedIOException(e); } finally { try { isWaiting.set(false); 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..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. @@ -225,11 +226,11 @@ 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 + * @deprecated Use {@link ReaderInputStream#builder()} instead. */ @Deprecated public ReaderInputStream(final Reader reader) { @@ -244,7 +245,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 +263,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 +285,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 +304,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 +326,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 +343,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 +373,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 +416,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 +437,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 +449,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 949ff8cbd8e..da5688b5155 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; } } @@ -354,9 +354,9 @@ 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 + * @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 4d9fe9c4751..d8ef0db0818 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) { @@ -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(); @@ -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 { @@ -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) { 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 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..e07cdc3eadb 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. @@ -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; } @@ -271,7 +288,8 @@ private void throttle() throws InterruptedIOException { try { TimeUnit.MILLISECONDS.sleep(sleepMillis); } catch (final InterruptedException e) { - throw new InterruptedIOException("Thread aborted"); + Thread.currentThread().interrupt(); + throw Input.toInterruptedIOException(e); } } } 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..be80d0d4eb1 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; @@ -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,7 +113,8 @@ 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 7f5102e8218..3d8a667c815 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. *

    @@ -278,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; @@ -298,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; @@ -315,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 { @@ -361,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") @@ -372,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")); @@ -485,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. @@ -589,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. @@ -662,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. */ @@ -696,12 +695,13 @@ 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) @@ -774,10 +774,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 { @@ -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); } @@ -851,8 +847,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 { @@ -899,10 +895,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 { @@ -922,11 +918,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) @@ -947,10 +943,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..ab3a65b9416 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) { @@ -148,8 +148,8 @@ public void run() { } try { ThreadUtils.sleep(Duration.ofMillis(intervalMillis)); - } catch (final InterruptedException ignored) { - // ignore + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); } } } @@ -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) { @@ -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(); } @@ -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..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 */ @@ -84,7 +85,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 +108,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 +117,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 +146,7 @@ public FileTime getLastModifiedFileTime() { /** * Gets the length. * - * @return the length + * @return the length. */ public long getLength() { return length; @@ -154,7 +155,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 +164,7 @@ public int getLevel() { /** * Gets the file name. * - * @return the file name + * @return the file name. */ public String getName() { return name; @@ -172,7 +173,7 @@ public String getName() { /** * Gets the parent entry. * - * @return the parent entry + * @return the parent entry. */ public FileEntry getParent() { return parent; @@ -181,7 +182,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 +192,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 +205,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 +225,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 +254,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 +263,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 +273,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 +306,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 +315,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 6b095474fb2..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() { @@ -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)); @@ -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() @@ -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..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. * @@ -61,7 +62,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/FileWriterWithEncoding.java b/src/main/java/org/apache/commons/io/output/FileWriterWithEncoding.java index 42d378cc0a5..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,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.closeQuietlySuppress(outputStream, ex); if (!fileExistedAlready) { FileUtils.deleteQuietly(file); } 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/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..ae7f8e8f536 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. @@ -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/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/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 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..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())) { @@ -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()}. 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 6141cc59b1c..8e945578efc 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 @@ -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/main/javadoc/overview.html b/src/main/javadoc/overview.html index 7fa4bd1f700..7de36f6ede9 100644 --- a/src/main/javadoc/overview.html +++ b/src/main/javadoc/overview.html @@ -17,16 +17,18 @@ --> -

    -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. -

    + 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/media/commons-logo-component-100.xcf b/src/media/commons-logo-component-100.xcf new file mode 100644 index 00000000000..d767311a12d Binary files /dev/null and b/src/media/commons-logo-component-100.xcf differ diff --git a/src/media/commons-logo-component.xcf b/src/media/commons-logo-component.xcf new file mode 100644 index 00000000000..a7dcdd43c1e Binary files /dev/null and b/src/media/commons-logo-component.xcf differ diff --git a/src/media/logo-large.xcf b/src/media/logo-large.xcf deleted file mode 100644 index caa37f4d095..00000000000 Binary files a/src/media/logo-large.xcf and /dev/null differ diff --git a/src/media/logo.png b/src/media/logo.png index 396ba49f82f..02a758f0ed8 100644 Binary files a/src/media/logo.png and b/src/media/logo.png differ diff --git a/src/media/logo.xcf b/src/media/logo.xcf deleted file mode 100644 index 72619d28ccf..00000000000 Binary files a/src/media/logo.xcf and /dev/null differ diff --git a/src/site/resources/images/leaf.svg b/src/site/resources/images/leaf.svg new file mode 100644 index 00000000000..71de588c648 --- /dev/null +++ b/src/site/resources/images/leaf.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/resources/images/logo.png b/src/site/resources/images/logo.png index 396ba49f82f..02a758f0ed8 100644 Binary files a/src/site/resources/images/logo.png and b/src/site/resources/images/logo.png differ 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 ac5ab0a77ed..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 - http://www.cs.umass.edu/~verts/cs32/endian.html + https://www.cs.umass.edu/~verts/cs32/endian.html

    diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 567d2653265..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.20.0-bin.tar.gzsha512pgpcommons-io-2.22.0-bin.tar.gzsha512pgp
    commons-io-2.20.0-bin.zipsha512pgpcommons-io-2.22.0-bin.zipsha512pgp
    - - - + + + - - - + + +
    commons-io-2.20.0-src.tar.gzsha512pgpcommons-io-2.22.0-src.tar.gzsha512pgp
    commons-io-2.20.0-src.zipsha512pgpcommons-io-2.22.0-src.zipsha512pgp
    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:

    • 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 57316a32677..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 { 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 +203,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 +213,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 diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java index 33771fe4554..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(); } @@ -90,32 +95,30 @@ 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) { - fileCleaningTracker.q = new ReferenceQueue<>(); + if (fileCleaningTracker.reaper != null) { + fileCleaningTracker.reaper.interrupt(); + } + fileCleaningTracker.refQueue = new ReferenceQueue<>(); fileCleaningTracker.trackers.clear(); fileCleaningTracker.deleteFailures.clear(); fileCleaningTracker.exitWhenFinished = false; 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 +134,7 @@ void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(testFile.getParentFile()); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -142,8 +145,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 +161,7 @@ void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(testPath.getParent()); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -180,7 +182,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 +202,7 @@ void testFileCleanerDirectoryFileSource() throws Exception { obj = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(testFile.exists()); // not deleted, as dir not empty @@ -220,7 +222,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 +269,7 @@ void testFileCleanerExitWhenFinished1() throws Exception { testFile = null; raf = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount(), "10-Track Count"); @@ -281,20 +283,20 @@ 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; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount()); @@ -309,6 +311,7 @@ void testFileCleanerExitWhenFinished2() throws Exception { } assertTrue(fileCleaningTracker.exitWhenFinished); assertFalse(fileCleaningTracker.reaper.isAlive()); + assertFalse(Files.exists(Paths.get(path))); } @Test @@ -318,7 +321,7 @@ void testFileCleanerExitWhenFinishedFirst() throws Exception { assertTrue(fileCleaningTracker.exitWhenFinished); assertNull(fileCleaningTracker.reaper); - waitUntilTrackCount(); + waitUntilTrackCount0(); assertEquals(0, fileCleaningTracker.getTrackCount()); assertTrue(fileCleaningTracker.exitWhenFinished); @@ -341,12 +344,13 @@ void testFileCleanerFile() throws Exception { testFile = null; raf = null; - waitUntilTrackCount(); + waitUntilTrackCount0(); pauseForDeleteToComplete(new File(path)); assertEquals(0, fileCleaningTracker.getTrackCount()); assertFalse(new File(path).exists(), showFailures()); } + @Test void testFileCleanerNull() { assertThrows(NullPointerException.class, () -> fileCleaningTracker.track((File) null, new Object())); @@ -355,7 +359,8 @@ 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,18 +370,17 @@ 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) { } 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)"); } - } -} + } diff --git a/src/test/java/org/apache/commons/io/FileDeleteStrategyTest.java b/src/test/java/org/apache/commons/io/FileDeleteStrategyTest.java index ffdd2f559d4..1371afda7da 100644 --- a/src/test/java/org/apache/commons/io/FileDeleteStrategyTest.java +++ b/src/test/java/org/apache/commons/io/FileDeleteStrategyTest.java @@ -29,6 +29,7 @@ import org.apache.commons.io.test.TestUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; + /** * Tests {@link FileDeleteStrategy}. */ 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/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java index 4f6efa0f946..91d351efeaa 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; @@ -169,9 +170,15 @@ List list(final File startDirectory) throws IOException { */ private static final ListDirectoryWalker LIST_WALKER = new ListDirectoryWalker(); + 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); + } + } private File testFile1; private File testFile2; private long testFile1Size; + private long testFile2Size; private void assertContentMatchesAfterCopyURLToFileFor(final String resourceName, final File destination) throws IOException { @@ -659,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()); @@ -1735,21 +1742,25 @@ 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"); } } @@ -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"); } } 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/FilenameUtilsTest.java b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java index 0441c6ac2e6..3049b9ae098 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; @@ -349,20 +350,38 @@ 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")); } + /** + * 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")); + 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 void testGetName() { assertNull(FilenameUtils.getName(null)); diff --git a/src/test/java/org/apache/commons/io/IOCaseTest.java b/src/test/java/org/apache/commons/io/IOCaseTest.java index 97a990f6369..54073da8096 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; @@ -29,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; /** @@ -296,34 +299,49 @@ 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; + 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 + // 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 + try (ScratchBytes scratch = IOUtils.ScratchBytes.get()) { + final byte[] array3 = scratch.array(); + assert0(array3); + assertSame(array, 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; + 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 + // 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 + try (ScratchChars scratch = IOUtils.ScratchChars.get()) { + final char[] array3 = scratch.array(); + assert0(array3); + assertSame(array, 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..4aed328a0df --- /dev/null +++ b/src/test/java/org/apache/commons/io/IOUtilsConcurrentTest.java @@ -0,0 +1,219 @@ +/* + * 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(final Reader reader, final 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(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()); + 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(final 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(final 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(); + } + } +} diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 02574946bf8..d9d073357b5 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -14,12 +14,14 @@ * 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; 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; @@ -73,11 +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; @@ -87,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; @@ -138,6 +144,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++) { @@ -158,7 +229,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)); } @@ -352,37 +425,9 @@ 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) { + 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))); @@ -392,7 +437,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(); } }); @@ -400,39 +445,15 @@ 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(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))); @@ -442,7 +463,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(); } }); @@ -450,6 +471,12 @@ void testCheckFromToIndexInvalidCases(int from, int to, int arrayLength) { } } + @ParameterizedTest + @MethodSource + void testCheckFromToIndexValidCases(final int from, final int to, final int arrayLength) { + assertDoesNotThrow(() -> IOUtils.checkFromToIndex(from, to, arrayLength)); + } + @Test void testClose() { assertDoesNotThrow(() -> IOUtils.close((Closeable) null)); @@ -553,9 +580,11 @@ 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()), e -> b.set(true))); + assertTrue(b.get()); } - @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" @Test void testCloseQuietly_Selector() { Selector selector = null; @@ -565,9 +594,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() { @@ -577,7 +606,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 @@ -586,7 +616,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; @@ -597,12 +626,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 @@ -620,7 +652,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 @@ -635,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)); @@ -665,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()"); } @@ -681,13 +724,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()"); } @@ -750,9 +790,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)); @@ -770,14 +808,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 { { @@ -911,12 +958,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); } @@ -931,7 +975,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(); @@ -949,11 +992,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); } @@ -968,19 +1009,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); @@ -995,18 +1033,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); @@ -1021,18 +1056,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); @@ -1047,18 +1079,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); @@ -1074,15 +1103,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 @@ -1094,12 +1120,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 @@ -1111,12 +1135,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 @@ -1128,12 +1150,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 @@ -1160,24 +1180,28 @@ 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); } } + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + 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)); + } + @Test void testRead_ReadableByteChannel() throws Exception { final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); @@ -1189,7 +1213,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); } @@ -1199,11 +1223,8 @@ void testRead_ReadableByteChannel() throws Exception { 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); } @@ -1213,11 +1234,11 @@ 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)); 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); } @@ -1230,6 +1251,13 @@ void testReadFully_InputStream_Offset() throws Exception { IOUtils.closeQuietly(stream); } + @ParameterizedTest + @MethodSource("invalidRead_InputStream_Offset_ArgumentsProvider") + 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)); + } + @Test void testReadFully_ReadableByteChannel() throws Exception { final ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE); @@ -1246,7 +1274,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); } @@ -1260,8 +1288,8 @@ 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(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); } @@ -1376,16 +1404,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); @@ -1437,8 +1465,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); @@ -1447,8 +1475,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); @@ -1467,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 @@ -1507,18 +1533,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 @@ -1595,13 +1621,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)); } } @@ -1610,11 +1634,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)); } } @@ -1624,11 +1647,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)); } } @@ -1637,11 +1659,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)); } } @@ -1650,10 +1671,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); } @@ -1665,8 +1686,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)); } } @@ -1678,7 +1699,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: @@ -1687,7 +1707,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); } @@ -1729,6 +1748,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 { @@ -1739,10 +1774,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()); } } @@ -1775,22 +1808,26 @@ 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)) { - 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\""); + final IOException exc = assertThrows(IOException.class, () -> IOUtils.toByteArray(fin, testFile.length() + 1)); + assertTrue(exc.getMessage().startsWith("Expected read size"), exc.getMessage()); } } @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"); - 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\""); + final IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () -> IOUtils.toByteArray(fin, (long) Integer.MAX_VALUE + 1)); + assertTrue(exc.getMessage().startsWith("size > Integer.MAX_VALUE"), exc.getMessage()); } } @@ -1827,7 +1864,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); } @@ -1910,7 +1946,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 { @@ -1931,7 +1967,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/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); } } 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..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,20 +161,6 @@ void testShouldThrowExceptionOnWritingToClosedChannel() { assertThrows(ClosedChannelException.class, () -> c.write(ByteBuffer.allocate(1))); } - @Test - void testShouldThrowExceptionWhenSettingIncorrectPosition() { - try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - assertThrows(IllegalArgumentException.class, () -> c.position(Integer.MAX_VALUE + 1L)); - } - } - - @Test - void testShouldThrowExceptionWhenTruncatingToIncorrectSize() { - try (ByteArraySeekableByteChannel c = new ByteArraySeekableByteChannel()) { - assertThrows(IllegalArgumentException.class, () -> c.truncate(Integer.MAX_VALUE + 1L)); - } - } - @Test void testShouldTruncateContentsProperly() throws ClosedChannelException { try (ByteArraySeekableByteChannel c = ByteArraySeekableByteChannel.wrap(testData)) { @@ -244,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. */ 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 { 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..4676e64c060 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,22 +33,27 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import java.nio.channels.AsynchronousByteChannel; +import java.io.IOException; 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; 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.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; import org.junit.jupiter.params.provider.MethodSource; @@ -56,17 +62,17 @@ */ class CloseShieldChannelTest { - static Stream> testedInterfaces() { + /** + * JRE {@link Channel} interfaces. + */ + static Stream> channelInterfaces() { // @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, @@ -75,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); @@ -85,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); @@ -97,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 @@ -122,7 +135,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); @@ -149,7 +162,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); @@ -189,7 +202,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); @@ -256,7 +269,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"); @@ -266,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); 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); 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/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"); 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/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 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..16639dfe245 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,8 @@ 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()) { @@ -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(); @@ -338,7 +338,8 @@ 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()) { 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..1a2520ba4bb 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,38 @@ * 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.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 {@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 +71,39 @@ public void setUpInputStreams() throws IOException { ReadAheadInputStream.builder().setPath(InputPath).setOpenOptions(StandardOpenOption.READ).get() }; } + @Test + @Timeout(value = 30, 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(); + // 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(); + } + } + } + } 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..937f59755b0 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); + final Thread thread = new Thread(tailer, "commons-io-tailer-testBufferBreak"); 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(); } @@ -346,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); @@ -369,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 @@ -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"); @@ -400,13 +400,14 @@ 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")) { lines = listener.getLines(); } // System.out.println("Elapsed: " + (System.currentTimeMillis() - start)); + assertFalse(lines.isEmpty()); listener.clear(); } } @@ -424,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))) { @@ -457,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); } @@ -469,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); } @@ -481,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); } @@ -493,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); } @@ -505,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); } @@ -517,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); } @@ -529,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); } @@ -586,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"); @@ -648,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"); @@ -659,7 +660,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"); } } @@ -672,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"); @@ -697,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"); @@ -723,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/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()); + } + } + } 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..1566dbc06ef 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; @@ -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"); } 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)}. * 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..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 @@ -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. @@ -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); 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_2_22_0.java b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java new file mode 100644 index 00000000000..1a3ac4929da --- /dev/null +++ b/src/test/java/org/apache/commons/io/jmh/IOUtilsContentEqualsReadersBenchmark_2_22_0.java @@ -0,0 +1,254 @@ +/* + * 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.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 97% 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 d7282d8ea98..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; @@ -203,7 +202,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 +214,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 +226,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)); 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" : { + } + } +] + + 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..c8f035fff09 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; @@ -260,7 +260,7 @@ public static void sleepQuietly(final long millis) { try { sleep(millis); } catch (final InterruptedException ignored) { - // ignore InterruptedException. + Thread.currentThread().interrupt(); } } 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) { 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