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..968056fcdff 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -42,6 +42,7 @@ jobs:
security-events: write
strategy:
+ max-parallel: 20
fail-fast: false
matrix:
language: [ 'java' ]
@@ -50,10 +51,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@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
@@ -62,7 +63,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@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -73,7 +74,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@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -87,4 +88,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # 3.29.5
+ uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index 1e043924237..f0d8ca94e32 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@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 7d0f0892434..ee9557cf46a 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -37,9 +37,10 @@ jobs:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
+ max-parallel: 20
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 +49,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 +61,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@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5
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..1da94b8148f 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
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@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
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
[](https://github.com/apache/commons-io/actions/workflows/maven.yml)
[](https://search.maven.org/artifact/commons-io/commons-io)
-[](https://javadoc.io/doc/commons-io/commons-io/2.20.0)
+[](https://javadoc.io/doc/commons-io/commons-io/2.22.0)
[](https://github.com/apache/commons-io/actions/workflows/codeql-analysis.yml)
[](https://api.securityscorecards.dev/projects/github.com/apache/commons-io)
@@ -69,7 +69,7 @@ Alternatively, you can pull it from the central Maven repositories:
| Charset | + *Description | + *
|---|---|
| {@code US-ASCII} | + *Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set. | + *
| {@code ISO-8859-1} | + *ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. | + *
| {@code UTF-8} | + *Eight-bit Unicode Transformation Format. | + *
| {@code UTF-16BE} | + *Sixteen-bit Unicode Transformation Format, big-endian byte order. | + *
| {@code UTF-16LE} | + *Sixteen-bit Unicode Transformation Format, little-endian byte order. | + *
| {@code UTF-16} | + *Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either order + * accepted on input, big-endian used on output.) | + *
* 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 @@ ** 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..b6cb2ebd83a 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,14 +112,15 @@ 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);
- return ((data[offset + 0] & 0xff) << 0) +
+ return
+ ((data[offset + 0] & 0xff) << 0) +
((data[offset + 1] & 0xff) << 8) +
((data[offset + 2] & 0xff) << 16) +
((data[offset + 3] & 0xff) << 24);
@@ -127,25 +129,29 @@ 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);
final int value2 = read(input);
final int value3 = read(input);
final int value4 = read(input);
- return ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16) + ((value4 & 0xff) << 24);
+ return
+ ((value1 & 0xff) << 0) +
+ ((value2 & 0xff) << 8) +
+ ((value3 & 0xff) << 16) +
+ ((value4 & 0xff) << 24);
}
/**
* 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 +163,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,41 +178,47 @@ 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);
- return (short) (((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8));
+ return (short) (
+ ((data[offset + 0] & 0xff) << 0) +
+ ((data[offset + 1] & 0xff) << 8)
+ );
}
/**
* 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));
+ return (short) (
+ ((read(input) & 0xff) << 0) +
+ ((read(input) & 0xff) << 8)
+ );
}
/**
* 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);
final long low = ((data[offset + 0] & 0xff) << 0) +
- ((data[offset + 1] & 0xff) << 8) +
- ((data[offset + 2] & 0xff) << 16);
+ ((data[offset + 1] & 0xff) << 8) +
+ ((data[offset + 2] & 0xff) << 16);
final long high = data[offset + 3] & 0xff;
return (high << 24) + (0xffffffffL & low);
}
@@ -214,16 +226,18 @@ 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);
final int value2 = read(input);
final int value3 = read(input);
final int value4 = read(input);
- final long low = ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16);
+ final long low = ((value1 & 0xff) << 0) +
+ ((value2 & 0xff) << 8) +
+ ((value3 & 0xff) << 16);
final long high = value4 & 0xff;
return (high << 24) + (0xffffffffL & low);
}
@@ -232,28 +246,30 @@ 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);
- return ((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8);
+ return ((data[offset + 0] & 0xff) << 0) +
+ ((data[offset + 1] & 0xff) << 8);
}
/**
* 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);
final int value2 = read(input);
- return ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8);
+ return ((value1 & 0xff) << 0) +
+ ((value2 & 0xff) << 8);
}
/**
@@ -263,8 +279,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 +289,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 +299,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 +313,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,21 +331,23 @@ 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) +
- ((value >> 8 & 0xff) << 0));
+ return (short) (
+ ((value >> 0 & 0xff) << 8) +
+ ((value >> 8 & 0xff) << 0)
+ );
}
/**
* 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 +358,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 +370,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 +381,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 +393,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 +404,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 +420,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 +434,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 +454,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 +472,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 +486,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..be2746b66be 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);
}
@@ -65,16 +66,18 @@ private final class Reaper extends Thread {
@Override
public void run() {
// thread exits when exitWhenFinished is true and there are no more tracked objects
- while (!exitWhenFinished || !trackers.isEmpty()) {
+ 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
*
* 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..11d3673f213 100644
--- a/src/main/java/org/apache/commons/io/FileSystem.java
+++ b/src/main/java/org/apache/commons/io/FileSystem.java
@@ -32,11 +32,10 @@
import java.util.Objects;
/**
- * Abstracts an OS' file system details, currently supporting the single use case of converting a file name String to a
- * legal file name with {@link #toLegalFileName(String, char)}.
+ * Enumerates file system details for operating systems, currently supporting the single use case of converting a file name String to a legal file name with
+ * {@link #toLegalFileName(String, char)}.
*
- * The starting point of any operation is {@link #getCurrent()} which gets you the enum for the file system that matches
- * the OS hosting the running JVM.
+ * The starting point of any operation is {@link #getCurrent()} which gets you the enum for the file system that matches the OS hosting the running JVM.
*
*
* @since 2.7
@@ -118,6 +117,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 +266,7 @@ final boolean isWithinLimit(final CharSequence value, final int limit, final Cha
/**
* Gets the current file system.
*
- * @return the current file system
+ * @return the current file system.
*/
private static FileSystem current() {
if (IS_OS_LINUX) {
@@ -284,7 +284,7 @@ private static FileSystem current() {
/**
* Gets the current file system.
*
- * @return the current file system
+ * @return the current file system.
*/
public static FileSystem getCurrent() {
return CURRENT;
@@ -294,8 +294,8 @@ public static FileSystem getCurrent() {
* Decides if the operating system matches.
*
* @param osNamePrefix
- * the prefix for the 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 +309,8 @@ private static boolean getOsMatchesName(final String osNamePrefix) {
*
*
* @param property
- * the system property name
- * @return the system property value or {@code null} if a security problem occurs
+ * the system property name.
+ * @return the system property value or {@code null} if a security problem occurs.
*/
private static String getSystemProperty(final String property) {
try {
@@ -345,10 +345,10 @@ private static int indexOfFirstDot(final CharSequence cs) {
*
*
* @param osName
- * the actual OS name
+ * the actual OS name.
* @param osNamePrefix
- * the prefix for the expected OS name
- * @return true if matches, or false if not or can't determine
+ * the prefix for the expected OS name.
+ * @return true if matches, or false if not or can't determine.
*/
private static boolean isOsNameMatch(final String osName, final String osNamePrefix) {
if (osName == null) {
diff --git a/src/main/java/org/apache/commons/io/FileSystemUtils.java b/src/main/java/org/apache/commons/io/FileSystemUtils.java
index 4c0af0d3671..7455dca8d09 100644
--- a/src/main/java/org/apache/commons/io/FileSystemUtils.java
+++ b/src/main/java/org/apache/commons/io/FileSystemUtils.java
@@ -53,12 +53,12 @@ public class FileSystemUtils {
* FileSystemUtils.freeSpace("/volume"); // *nix
*
*
- * @param path the path to get free space for, not null, not empty on Unix
- * @return the amount of free drive space on the drive or volume
+ * @param path the path to get free space for, not null, not empty on Unix.
+ * @return the amount of free drive space on the drive or volume.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
* @since 1.1, enhanced OS support in 1.2 and 1.3
- * @deprecated Use freeSpaceKb(String) Deprecated from 1.3, may be removed in 2.0
+ * @deprecated Use freeSpaceKb(String) Deprecated from 1.3, may be removed in 2.0.
*/
@Deprecated
public static long freeSpace(final String path) throws IOException {
@@ -75,7 +75,7 @@ public static long freeSpace(final String path) throws IOException {
* freeSpaceKb(FileUtils.current().getAbsolutePath())
*
*
- * @return the amount of free drive space on the drive or volume in kilobytes
+ * @return the amount of free drive space on the drive or volume in kilobytes.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
* @since 2.0
@@ -97,7 +97,7 @@ public static long freeSpaceKb() throws IOException {
*
*
* @param timeout ignored.
- * @return the amount of free drive space on the drive or volume in kilobytes
+ * @return the amount of free drive space on the drive or volume in kilobytes.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
* @since 2.0
@@ -116,8 +116,8 @@ public static long freeSpaceKb(final long timeout) throws IOException {
* FileSystemUtils.freeSpaceKb("/volume"); // *nix
*
*
- * @param path the path to get free space for, not null, not empty on Unix
- * @return the amount of free drive space on the drive or volume in kilobytes
+ * @param path the path to get free space for, not null, not empty on Unix.
+ * @return the amount of free drive space on the drive or volume in kilobytes.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
* @since 1.2, enhanced OS support in 1.3
@@ -136,9 +136,9 @@ public static long freeSpaceKb(final String path) throws IOException {
* FileSystemUtils.freeSpaceKb("/volume"); // *nix
*
*
- * @param path the path to get free space for, not null, not empty on Unix
+ * @param path the path to get free space for, not null, not empty on Unix.
* @param timeout ignored.
- * @return the amount of free drive space on the drive or volume in kilobytes
+ * @return the amount of free drive space on the drive or volume in kilobytes.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
* @since 2.0
@@ -157,8 +157,8 @@ public static long freeSpaceKb(final String path, final long timeout) throws IOE
* FileSystemUtils.freeSpace("/volume"); // *nix
*
*
- * @param pathStr the path to get free space for, not null, not empty on Unix
- * @return the amount of free drive space on the drive or volume
+ * @param pathStr the path to get free space for, not null, not empty on Unix.
+ * @return the amount of free drive space on the drive or volume.
* @throws IOException if an I/O error occurs.
* @throws IllegalArgumentException if the path is invalid.
*/
diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java
index 203fe84bfc5..11afd3f5d62 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:
*
* * 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+ * WARNING: This method reads the Java system property {@code java.io.tmpdir}, which may or may not have a trailing file separator. This can affect code + * that uses String processing to manipulate pathnames rather than the standard library 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() { @@ -1565,7 +1564,7 @@ public static String getTempDirectoryPath() { } /** - * Gets a {@link File} representing the user's home directory. + * Gets a {@link File} representing the user's home directory based on the Java system property {@code user.home}. * * @return the user's home directory. * @since 2.0 @@ -1575,7 +1574,7 @@ public static File getUserDirectory() { } /** - * Gets the path to the user's home directory. + * Gets the path to the user's home directory based on the Java system property {@code user.home}. * * @return the path to the user's home directory. * @since 2.0 @@ -1589,7 +1588,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 +1631,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 +1655,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 +1669,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 +1699,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 +1716,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 +1734,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 +1750,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 +1794,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 +1809,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 +1820,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 +1849,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 +1874,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 +1889,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 +1920,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 +1938,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 +1955,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 +1970,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 +1985,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 +2028,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 +2038,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 +2064,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 +2289,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 +2692,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 +2754,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 +2803,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 +3211,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 +3225,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 +3270,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 +3284,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 +3303,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 +3315,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 +3331,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 +3347,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 +3367,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 +3381,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 +3397,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 +3412,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 +3430,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 +3446,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 +3465,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 +3482,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 +3500,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 +3513,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 +3531,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 +3546,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 +3564,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 +3578,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..3c8ca2f8373 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
* 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
- * 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..9a4d168fc3a 100644 --- a/src/main/java/org/apache/commons/io/IOCase.java +++ b/src/main/java/org/apache/commons/io/IOCase.java @@ -21,7 +21,7 @@ import java.util.stream.Stream; /** - * Enumeration of IO case sensitivity. + * Enumerates IO case sensitivity types. *
* Different filing systems have different rules for case-sensitivity.
* Windows is case-insensitive, Unix is case-sensitive.
@@ -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()
@@ -95,7 +95,7 @@ public static boolean isCaseSensitive(final IOCase ioCase) {
/**
* Returns the given value if not-null, the defaultValue if null.
*
- * @param value the value to test.
+ * @param value the value to test, may be null.
* @param defaultValue the default value.
* @return the given value if not-null, the defaultValue if null.
* @since 2.12.0
@@ -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
- * 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 @@ *
- * 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+ * 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@@ -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: + *
*+ * 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: + *
*+ * 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: + *
*+ * 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: + *
*+ * 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
* - * 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,17 @@ 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 {
@@ -741,7 +853,8 @@ public static void closeQuietly(final Closeable closeable) {
*
*
* Closing all streams:
- *
+ *
+ *
*
* try {
* return IOUtils.copy(inputStream, outputStream);
@@ -752,6 +865,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 +881,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 +899,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 +948,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 +981,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 +1014,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 +1046,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 +1079,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 +1128,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 +1157,37 @@ 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.
+ * } catch (Exception e) {
+ * // Handle exception.
+ * throw IOUtils.closeQuietlySuppress(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, throwable::addSuppressed);
+ return throwable;
+ }
+
/**
* Consumes bytes from a {@link InputStream} and ignores them.
*
@@ -1054,7 +1197,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 +1213,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 +1221,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 +1247,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 +1264,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 +1274,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 +1334,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 +1363,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 +1381,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 +1400,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 +1421,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 +1441,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 +1467,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 +1476,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 +1496,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 +1517,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 +1540,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 +1557,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 +1597,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 +1621,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 +1652,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 +1675,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 +1690,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 +1739,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);
}
@@ -1698,7 +1803,7 @@ public static long copyLarge(final InputStream input, final OutputStream output,
output.write(buffer, 0, read);
totalRead += read;
if (length > 0) { // only adjust length if not reading to the end
- // Note the cast must work because buffer.length is an integer
+ // Note the cast must work because bufferLength = buffer.length is an integer
bytesToRead = (int) Math.min(length - totalRead, bufferLength);
}
}
@@ -1708,8 +1813,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 +1827,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 +1875,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 +1924,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 +1981,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 +2014,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 +2050,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 +2081,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 +2099,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 +2130,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 +2154,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 +2171,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 +2180,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 +2202,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 +2220,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 +2244,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 +2265,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 +2286,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 +2304,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 +2340,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 +2351,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 +2359,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 +2376,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 +2397,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 +2435,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 +2452,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 +2469,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 +2499,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 +2541,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 +2563,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 +2595,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 +2623,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 +2645,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 +2662,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 +2678,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 +2720,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 +2740,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.
@@ -2780,7 +2773,9 @@ public static void skipFully(final Reader reader, final long toSkip) throws IOEx
* It has network timeout associated.
*
*
- * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].
+ * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].
+ *
+ *
* This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
@@ -2804,7 +2799,9 @@ public static InputStream toBufferedInputStream(final InputStream input) throws
* It has network timeout associated.
*
*
- * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].
+ * It can be used in favor of {@link #toByteArray(InputStream)}, since it avoids unnecessary allocation and copy of byte[].
+ *
+ *
* This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
@@ -2819,8 +2816,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 +2829,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 +2844,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 +2865,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 +2885,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 +2906,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 +2939,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 +2948,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 +2968,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 +2991,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 +3011,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 +3032,7 @@ public static byte[] toByteArray(final Reader reader, final String charsetName)
}
/**
- * Gets the contents of a {@link String} as a {@code byte[]}
- * using the virtual machine's {@link Charset#defaultCharset() default charset}.
+ * 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 +3082,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 +3092,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 +3102,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 +3110,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 +3152,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 +3168,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 +3182,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 +3194,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 +3210,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 +3223,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 +3235,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 +3251,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 +3265,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 +3280,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 +3297,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 +3317,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 +3356,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 +3381,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 +3397,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 +3413,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 +3426,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 +3438,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 +3454,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 +3467,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 +3487,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 +3512,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 +3533,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 +3554,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 +3565,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 +3591,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 +3605,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 +3639,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 +3656,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 +3665,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 +3679,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 +3699,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 +3740,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 +3776,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 +3823,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 +3831,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 +3839,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 +3886,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 +3894,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 +3940,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 +3982,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 +4006,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..92a8bc7c035 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,17 +77,12 @@ 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) {
- Objects.requireNonNull(reader, "reader");
- if (reader instanceof BufferedReader) {
- bufferedReader = (BufferedReader) reader;
- } else {
- bufferedReader = new BufferedReader(reader);
- }
+ bufferedReader = IOUtils.buffer(Objects.requireNonNull(reader, "reader"));
}
/**
@@ -111,8 +106,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 +130,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 +148,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 +159,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 +176,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..e64f4ae732d 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractOrigin.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractOrigin.java
@@ -31,6 +31,7 @@
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
+import java.net.URLConnection;
import java.nio.channels.Channel;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
@@ -43,8 +44,10 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
+import java.time.Duration;
import java.util.Arrays;
import java.util.Objects;
+import java.util.stream.Stream;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IORandomAccessFile;
@@ -366,6 +369,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 +441,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 +569,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 +697,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 +903,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);
@@ -952,6 +964,80 @@ public Reader getReader(final Charset charset) throws IOException {
*/
public static class URIOrigin extends AbstractOrigin {
+ /**
+ * Options for connect and read from a URI.
+ *
+ * @since 2.22.0
+ */
+ public static final class URIOpenOption implements OpenOption {
+
+ /**
+ * Builds URIOpenOption.
+ */
+ public static class Builder extends AbstractSupplier {
+
+ private Duration connectTimeout;
+ private Duration readTimeout;
+
+ /**
+ * Constructs a new instance.
+ */
+ public Builder() {
+ // empty
+ }
+
+ @Override
+ public URIOpenOption get() {
+ return new URIOpenOption(this);
+ }
+
+ /**
+ * Sets the connect timeout duration.
+ *
+ * @param connectTimeout the connect timeout duration.
+ * @return {@code this instance}.
+ */
+ public Builder setConnectTimeout(final Duration connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ return asThis();
+ }
+
+ /**
+ * Sets the read timeout duration.
+ *
+ * @param readTimeout the read timeout duration.
+ * @return {@code this instance}.
+ */
+ public Builder setReadTimeout(final Duration readTimeout) {
+ this.readTimeout = readTimeout;
+ return asThis();
+ }
+ }
+
+ /**
+ * Creates a new builder.
+ *
+ * @return a new builder.
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private final Duration connectTimeout;
+
+ private final Duration readTimeout;
+
+ private URIOpenOption(final Builder builder) {
+ connectTimeout = builder.connectTimeout;
+ readTimeout = builder.readTimeout;
+ }
+
+ @Override
+ public String toString() {
+ return "URIOpenOption [connectTimeout=" + connectTimeout + ", readTimeout=" + readTimeout + "]";
+ }
+ }
+
private static final String SCHEME_HTTPS = "https";
private static final String SCHEME_HTTP = "http";
@@ -959,17 +1045,23 @@ 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);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see URIOpenOption
+ */
@Override
protected Channel getChannel(final OpenOption... options) throws IOException {
final URI uri = get();
final String scheme = uri.getScheme();
if (SCHEME_HTTP.equalsIgnoreCase(scheme) || SCHEME_HTTPS.equalsIgnoreCase(scheme)) {
- return Channels.newChannel(uri.toURL().openStream());
+ return Channels.newChannel(getInputStream(uri, options));
}
return Files.newByteChannel(getPath(), options);
}
@@ -979,20 +1071,52 @@ public File getFile() {
return getPath().toFile();
}
+ /**
+ * {@inheritDoc}
+ *
+ * Set timeouts with a {@link URIOpenOption}.
+ *
+ *
+ * @see URIOpenOption
+ * @see URLConnection#setConnectTimeout(int)
+ * @see URLConnection#setReadTimeout(int)
+ */
@Override
public InputStream getInputStream(final OpenOption... options) throws IOException {
final URI uri = get();
final String scheme = uri.getScheme();
if (SCHEME_HTTP.equalsIgnoreCase(scheme) || SCHEME_HTTPS.equalsIgnoreCase(scheme)) {
- return uri.toURL().openStream();
+ return getInputStream(uri, options);
}
return Files.newInputStream(getPath(), options);
}
+ private InputStream getInputStream(final URI uri, final OpenOption... options) throws IOException {
+ final URLConnection connection = uri.toURL().openConnection();
+ if (options != null) {
+ Stream.of(options).forEach(option -> {
+ if (option instanceof URIOpenOption) {
+ final URIOpenOption connOption = (URIOpenOption) option;
+ if (connOption.connectTimeout != null) {
+ connection.setConnectTimeout(toMillis(connOption.connectTimeout));
+ }
+ if (connOption.readTimeout != null) {
+ connection.setReadTimeout(toMillis(connOption.readTimeout));
+ }
+ }
+ });
+ }
+ return connection.getInputStream();
+ }
+
@Override
public Path getPath() {
return Paths.get(get());
}
+
+ private int toMillis(final Duration duration) {
+ return Math.toIntExact(duration.toMillis());
+ }
}
/**
@@ -1007,6 +1131,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 +1182,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 +1216,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 +1239,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 +1258,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 +1290,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 +1302,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 +1345,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 +1357,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..37986693b48 100644
--- a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
+++ b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java
@@ -122,6 +122,20 @@ public int getBufferSizeDefault() {
return bufferSizeDefault;
}
+ /**
+ * Gets a byte array from the origin.
+ *
+ * @return A byte array.
+ * @throws IllegalStateException if the {@code origin} is {@code null}.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a byte array.
+ * @throws IOException if an I/O error occurs.
+ * @see AbstractOrigin#getByteArray()
+ * @since 2.22.0
+ */
+ public byte[] getByteArray() throws IOException {
+ return checkOrigin().getByteArray();
+ }
+
/**
* Gets a Channel from the origin with OpenOption[].
*
@@ -142,7 +156,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 +188,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 +201,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.
@@ -202,7 +216,7 @@ public InputStream getInputStream() throws IOException {
/**
* Gets the OpenOption array.
*
- * @return the OpenOption array.
+ * @return the OpenOption array, this is not a defensive copy, modify at your own risk.
*/
public OpenOption[] getOpenOptions() {
return openOptions;
@@ -211,7 +225,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 +240,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 +253,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 +266,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.
@@ -285,7 +299,7 @@ public Writer getWriter() throws IOException {
* Subclasses may ignore this setting.
*
*
- * @param bufferSize the buffer size.
+ * @param bufferSize the buffer size, 0 resets to the default from {@link #getBufferSizeDefault()}.
* @return {@code this} instance.
*/
public B setBufferSize(final int bufferSize) {
@@ -299,7 +313,7 @@ public B setBufferSize(final int bufferSize) {
* Subclasses may ignore this setting.
*
*
- * @param bufferSize the buffer size, null resets to the default.
+ * @param bufferSize the buffer size, null resets to the default from {@link #getBufferSizeDefault()}.
* @return {@code this} instance.
*/
public B setBufferSize(final Integer bufferSize) {
@@ -325,11 +339,11 @@ public B setBufferSizeChecker(final IntUnaryOperator bufferSizeChecker) {
* Subclasses may ignore this setting.
*
*
- * @param bufferSizeDefault the buffer size, null resets to the default.
+ * @param bufferSizeDefault the buffer size, 0 resets to the default {@link IOUtils#DEFAULT_BUFFER_SIZE}.
* @return {@code this} instance.
*/
protected B setBufferSizeDefault(final int bufferSizeDefault) {
- this.bufferSizeDefault = bufferSizeDefault;
+ this.bufferSizeDefault = checkBufferSize(bufferSizeDefault > 0 ? bufferSizeDefault : IOUtils.DEFAULT_BUFFER_SIZE);
return asThis();
}
@@ -388,7 +402,7 @@ protected B setCharsetDefault(final Charset defaultCharset) {
}
/**
- * Sets the OpenOption[].
+ * Sets the OpenOption array.
*
* Normally used with InputStream, OutputStream, and Writer.
*
@@ -396,7 +410,7 @@ protected B setCharsetDefault(final Charset defaultCharset) {
* Subclasses may ignore this setting.
*
*
- * @param openOptions the OpenOption[] name, null resets to the default.
+ * @param openOptions the OpenOption[] name, null resets to the default, a defensive copy is made.
* @return {@code this} instance.
* @since 2.13.0
* @see #setInputStream(InputStream)
@@ -404,7 +418,7 @@ protected B setCharsetDefault(final Charset defaultCharset) {
* @see #setWriter(Writer)
*/
public B setOpenOptions(final OpenOption... openOptions) {
- this.openOptions = openOptions != null ? openOptions : DEFAULT_OPEN_OPTIONS;
+ this.openOptions = openOptions != null ? openOptions.clone() : DEFAULT_OPEN_OPTIONS;
return asThis();
}
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..57c38124875 100644
--- a/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/ByteArraySeekableByteChannel.java
@@ -24,12 +24,16 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
+import java.nio.channels.NonWritableChannelException;
import java.nio.channels.SeekableByteChannel;
+import java.nio.file.OpenOption;
+import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.build.AbstractStreamBuilder;
/**
* A {@link SeekableByteChannel} implementation backed by a byte array.
@@ -38,25 +42,79 @@
* and it's not possible to {@link #position(long) set the position} or {@link #truncate(long) truncate} to a value bigger than that. The raw internal buffer is
* accessed via {@link ByteArraySeekableByteChannel#array()}.
*
+ *
+ * Building a read-only channel from an existing byte array is supported with:
+ *
+ * {@code
+ * try (ByteArraySeekableByteChannel channel = ByteArraySeekableByteChannel.builder()
+ * .setByteArray(...)
+ * .setOpenOptions(StandardOpenOption.READ)
+ * .get()) {
+ * // read from channel
+ * }
+ * }
*
* @since 2.21.0
*/
public class ByteArraySeekableByteChannel implements SeekableByteChannel {
+ /**
+ * Builds for {@link ByteArraySeekableByteChannel}.
+ *
+ * Building a read-only channel from an existing byte array is supported with:
+ *
+ * {@code
+ * try (ByteArraySeekableByteChannel channel = ByteArraySeekableByteChannel.builder()
+ * .setByteArray(...)
+ * .setOpenOptions(StandardOpenOption.READ)
+ * .get()) {
+ * // read from channel
+ * }
+ * }
+ *
+ * @since 2.22.0
+ */
+ public static class Builder extends AbstractStreamBuilder {
+
+ /**
+ * Constructs a new builder for {@link ByteArraySeekableByteChannel}.
+ */
+ public Builder() {
+ setByteArray(IOUtils.EMPTY_BYTE_ARRAY);
+ }
+
+ @Override
+ public ByteArraySeekableByteChannel get() throws IOException {
+ return new ByteArraySeekableByteChannel(this);
+ }
+ }
+
private static final int RESIZE_LIMIT = Integer.MAX_VALUE >> 1;
+ /**
+ * Constructs a new builder for {@link ByteArraySeekableByteChannel}.
+ *
+ * @return a new builder for {@link ByteArraySeekableByteChannel}.
+ * @since 2.22.0
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
/**
* Constructs a new channel backed directly by the given byte array.
*
- * The channel initially contains the full contents of the array, with its
- * size set to {@code bytes.length} and its position set to {@code 0}.
+ *
+ * The channel initially contains the full contents of the array, with its size set to {@code bytes.length} and its position set to {@code 0}.
+ *
*
- * Reads and writes operate on the shared array.
- * If a write operation extends beyond the current capacity, the channel will
- * automatically allocate a larger backing array and copy the existing contents.
+ *
+ * Reads and writes operate on the shared array. If a write operation extends beyond the current capacity, the channel will 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[])
@@ -65,11 +123,11 @@ public static ByteArraySeekableByteChannel wrap(final byte[] bytes) {
Objects.requireNonNull(bytes, "bytes");
return new ByteArraySeekableByteChannel(bytes);
}
-
private byte[] data;
private volatile boolean closed;
- private int position;
+ private long position;
private int size;
+ private final boolean isWritable;
private final ReentrantLock lock = new ReentrantLock();
/**
@@ -84,10 +142,19 @@ public ByteArraySeekableByteChannel() {
this(IOUtils.DEFAULT_BUFFER_SIZE);
}
+ private ByteArraySeekableByteChannel(final Builder builder) throws IOException {
+ this.data = builder.getByteArray();
+ this.size = data.length;
+ final OpenOption[] openOptions = builder.getOpenOptions();
+ Arrays.sort(openOptions);
+ this.isWritable = openOptions.length == 0 || Arrays.binarySearch(openOptions, StandardOpenOption.WRITE) >= 0
+ || Arrays.binarySearch(openOptions, StandardOpenOption.APPEND) >= 0;
+ }
+
private ByteArraySeekableByteChannel(final byte[] data) {
this.data = data;
- this.position = 0;
this.size = data.length;
+ this.isWritable = true;
}
/**
@@ -104,8 +171,7 @@ public ByteArraySeekableByteChannel(final int size) {
throw new IllegalArgumentException("Size must be non-negative");
}
this.data = new byte[size];
- this.position = 0;
- this.size = 0;
+ this.isWritable = true;
}
/**
@@ -126,11 +192,16 @@ 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));
+ }
+ }
+
+ private void checkWritable() {
+ if (!isWritable) {
+ throw new NonWritableChannelException();
}
- return (int) newSize;
}
@Override
@@ -166,10 +237,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 +252,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 +312,15 @@ public byte[] toByteArray() {
@Override
public SeekableByteChannel truncate(final long newSize) throws ClosedChannelException {
checkOpen();
- final int intSize = checkRange(newSize, "truncate()");
+ checkWritable();
+ 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 +331,30 @@ public SeekableByteChannel truncate(final long newSize) throws ClosedChannelExce
@Override
public int write(final ByteBuffer b) throws IOException {
checkOpen();
+ checkWritable();
+ //
+ 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..987e8427c7c 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;
@@ -28,8 +37,24 @@
* 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 +65,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 +82,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..822c6b6186b 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,44 @@
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;
+/**
+ * An {@link InvocationHandler} supporting the implementation of {@link CloseShieldChannel}.
+ */
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 +72,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.
*
@@ -123,7 +157,7 @@ private Object invokeObjectMethod(final Object proxy, final Method method, final
return false;
}
default:
- // Not possible, all non-final Object methods are handled above
+ // Not possible, all non-final Object methods are handled above.
return null;
}
}
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/channels/FilterByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java
new file mode 100644
index 00000000000..bcce45486b5
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/channels/FilterByteChannel.java
@@ -0,0 +1,125 @@
+/*
+ * 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.channels;
+
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.io.input.ProxyReader;
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.io.output.ProxyWriter;
+
+/**
+ * A {@link ByteChannel} filter which delegates to the wrapped {@link ByteChannel}.
+ *
+ * A {@code FilterByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterByteChannel} itself simply overrides methods of {@code ByteChannel} with versions that pass all requests to
+ * the wrapped channel. Subclasses of {@code FilterByteChannel} may of course override any methods declared or inherited by {@code FilterByteChannel}, and may
+ * also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterByteChannel#FilterByteChannel(ByteChannel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
+ *
+ * @param the {@link ByteChannel} type.
+ * @see FilterInputStream
+ * @see FilterOutputStream
+ * @see FilterReader
+ * @see FilterWritableByteChannel
+ * @see ProxyInputStream
+ * @see ProxyOutputStream
+ * @see ProxyReader
+ * @see ProxyWriter
+ * @since 2.22.0
+ */
+public class FilterByteChannel extends FilterChannel implements ByteChannel {
+
+ /**
+ * Builds instances of {@link FilterByteChannel} for subclasses.
+ *
+ * @param The {@link FilterByteChannel} type.
+ * @param The {@link ByteChannel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder, C extends ByteChannel, B extends AbstractBuilder>
+ extends FilterChannel.AbstractBuilder {
+
+ /**
+ * Constructs a new builder for {@link FilterByteChannel}.
+ */
+ protected AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ public static class Builder extends AbstractBuilder, ByteChannel, Builder> {
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterByteChannel get() throws IOException {
+ return new FilterByteChannel<>(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forByteChannel() {
+ return new Builder();
+ }
+
+ FilterByteChannel(final AbstractBuilder, ?, ?> builder) throws IOException {
+ super(builder);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param byteChannel The channel to wrap.
+ */
+ public FilterByteChannel(final C byteChannel) {
+ super(byteChannel);
+ }
+
+ @Override
+ public int read(final ByteBuffer dst) throws IOException {
+ return channel.read(dst);
+ }
+
+ @Override
+ public int write(final ByteBuffer src) throws IOException {
+ return channel.write(src);
+ }
+}
diff --git a/src/main/java/org/apache/commons/io/channels/FilterChannel.java b/src/main/java/org/apache/commons/io/channels/FilterChannel.java
new file mode 100644
index 00000000000..e76dd962082
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/channels/FilterChannel.java
@@ -0,0 +1,146 @@
+/*
+ * 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.channels;
+
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.nio.channels.Channel;
+
+import org.apache.commons.io.build.AbstractStreamBuilder;
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.io.input.ProxyReader;
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.io.output.ProxyWriter;
+
+/**
+ * A {@link Channel} filter which delegates to the wrapped {@link Channel}.
+ *
+ * A {@code FilterChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterChannel} itself simply overrides methods of {@code Channel} with versions that pass all requests to the
+ * wrapped channel. Subclasses of {@code FilterChannel} may of course override any methods declared or inherited by {@code FilterChannel}, and may also provide
+ * additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterChannel#FilterChannel(Channel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
+ *
+ * @param the {@link Channel} type.
+ * @see FilterInputStream
+ * @see FilterOutputStream
+ * @see FilterReader
+ * @see FilterWritableByteChannel
+ * @see ProxyInputStream
+ * @see ProxyOutputStream
+ * @see ProxyReader
+ * @see ProxyWriter
+ * @since 2.22.0
+ */
+public class FilterChannel implements Channel {
+
+ /**
+ * Builds instances of {@link FilterChannel} for subclasses.
+ *
+ * @param The {@link FilterChannel} type.
+ * @param The {@link Channel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder, C extends Channel, B extends AbstractBuilder>
+ extends AbstractStreamBuilder> {
+
+ /**
+ * Constructs instance for subclasses.
+ */
+ protected AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterChannel}.
+ */
+ public static class Builder extends AbstractBuilder, Channel, Builder> {
+
+ /**
+ * Builds instances of {@link FilterChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterChannel get() throws IOException {
+ return new FilterChannel<>(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forChannel() {
+ return new Builder();
+ }
+
+ final C channel;
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param builder The source builder.
+ * @throws IOException if an I/O error occurs.
+ */
+ @SuppressWarnings("unchecked")
+ FilterChannel(final AbstractBuilder, ?, ?> builder) throws IOException {
+ channel = (C) builder.getChannel(Channel.class);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterChannel(final C channel) {
+ this.channel = channel;
+ }
+
+ @Override
+ public void close() throws IOException {
+ channel.close();
+ }
+
+ @Override
+ public boolean isOpen() {
+ return channel.isOpen();
+ }
+
+ /**
+ * Unwraps this instance by returning the underlying {@link Channel} of type {@code C}.
+ *
+ * Use with caution.
+ *
+ *
+ * @return the underlying channel of type {@code C}.
+ */
+ public C unwrap() {
+ return channel;
+ }
+}
diff --git a/src/test/java/org/apache/commons/io/channels/FileChannelProxy.java b/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
similarity index 57%
rename from src/test/java/org/apache/commons/io/channels/FileChannelProxy.java
rename to src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
index ce7c0daddf7..c37d30dbf23 100644
--- a/src/test/java/org/apache/commons/io/channels/FileChannelProxy.java
+++ b/src/main/java/org/apache/commons/io/channels/FilterFileChannel.java
@@ -20,20 +20,90 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
+import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
+import java.util.Objects;
+
+import org.apache.commons.io.build.AbstractStreamBuilder;
/**
- * Proxies a FileChannel.
+ * Filters a {@link FileChannel}.
+ *
+ * A {@code FilterFileChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or providing
+ * additional functionality. The class {@code FilterFileChannel} itself simply overrides methods of {@code FileChannel} with versions that pass all requests to
+ * the wrapped channel. Subclasses of {@code FilterFileChannel} may of course override any methods declared or inherited by {@code FilterFileChannel}, and may
+ * also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterFileChannel#FilterFileChannel(FileChannel) channel constructor} and more advanced instances through the
+ * {@link Builder}.
+ *
+ *
+ * @since 2.22.0
*/
-class FileChannelProxy extends FileChannel {
+public class FilterFileChannel extends FileChannel {
+
+ /**
+ * Builds instances of {@link FilterFileChannel} for subclasses.
+ *
+ * @param The {@link FilterFileChannel} type.
+ * @param The {@link Channel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder>
+ extends AbstractStreamBuilder> {
+
+ /**
+ * Constructs instance for subclasses.
+ */
+ protected AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterFileChannel}.
+ */
+ public static class Builder extends AbstractBuilder {
- FileChannel fileChannel;
+ /**
+ * Builds instances of {@link FilterChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterFileChannel get() throws IOException {
+ return new FilterFileChannel(this);
+ }
+ }
- FileChannelProxy(final FileChannel fileChannel) {
- this.fileChannel = fileChannel;
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forFilterFileChannel() {
+ return new Builder();
+ }
+
+ final FileChannel fileChannel;
+
+ private FilterFileChannel(final Builder builder) throws IOException {
+ this.fileChannel = builder.getChannel(FileChannel.class);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param fileChannel the file channel to wrap.
+ */
+ public FilterFileChannel(final FileChannel fileChannel) {
+ this.fileChannel = Objects.requireNonNull(fileChannel, "fileChannel");
}
@Override
@@ -121,6 +191,18 @@ public FileLock tryLock(final long position, final long size, final boolean shar
return fileChannel.tryLock(position, size, shared);
}
+ /**
+ * Unwraps this instance by returning the underlying {@link FileChannel}.
+ *
+ * Use with caution.
+ *
+ *
+ * @return the underlying {@link FileChannel}.
+ */
+ public FileChannel unwrap() {
+ return fileChannel;
+ }
+
@Override
public int write(final ByteBuffer src) throws IOException {
return fileChannel.write(src);
diff --git a/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java
new file mode 100644
index 00000000000..377d3b1d043
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/channels/FilterReadableByteChannel.java
@@ -0,0 +1,120 @@
+/*
+ * 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.channels;
+
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.io.input.ProxyReader;
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.io.output.ProxyWriter;
+
+/**
+ * A {@link ReadableByteChannel} filter which delegates to the wrapped {@link ReadableByteChannel}.
+ *
+ * A {@code FilterReadableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterReadableByteChannel} itself simply overrides methods of {@code ReadableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterReadableByteChannel} may of course override any methods declared or inherited by
+ * {@code FilterReadableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterReadableByteChannel#FilterReadableByteChannel(ReadableByteChannel) channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
+ *
+ * @param the {@link ReadableByteChannel} type.
+ * @see FilterInputStream
+ * @see FilterOutputStream
+ * @see FilterReader
+ * @see FilterWritableByteChannel
+ * @see ProxyInputStream
+ * @see ProxyOutputStream
+ * @see ProxyReader
+ * @see ProxyWriter
+ * @since 2.22.0
+ */
+public class FilterReadableByteChannel extends FilterChannel implements ReadableByteChannel {
+
+ /**
+ * Builds instances of {@link FilterReadableByteChannel} for subclasses.
+ *
+ * @param The {@link FilterReadableByteChannel} type.
+ * @param The {@link ReadableByteChannel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder, C extends ReadableByteChannel, B extends AbstractBuilder>
+ extends FilterChannel.AbstractBuilder {
+
+ /**
+ * Constructs a new builder for {@link FilterReadableByteChannel}.
+ */
+ public AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ public static class Builder extends AbstractBuilder, ReadableByteChannel, Builder> {
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterReadableByteChannel get() throws IOException {
+ return new FilterReadableByteChannel<>(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forReadableByteChannel() {
+ return new Builder();
+ }
+
+ FilterReadableByteChannel(final Builder builder) throws IOException {
+ super(builder);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterReadableByteChannel(final C channel) {
+ super(channel);
+ }
+
+ @Override
+ public int read(final ByteBuffer dst) throws IOException {
+ return channel.read(dst);
+ }
+}
diff --git a/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java
new file mode 100644
index 00000000000..11fbadc2c15
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/channels/FilterSeekableByteChannel.java
@@ -0,0 +1,134 @@
+/*
+ * 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.channels;
+
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.nio.channels.SeekableByteChannel;
+
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.io.input.ProxyReader;
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.io.output.ProxyWriter;
+
+/**
+ * A {@link SeekableByteChannel} filter which delegates to the wrapped {@link SeekableByteChannel}.
+ *
+ * A {@code FilterSeekableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterSeekableByteChannel} itself simply overrides methods of {@code SeekableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterSeekableByteChannel} may of course override any methods declared or inherited by
+ * {@code FilterSeekableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterSeekableByteChannel#FilterSeekableByteChannel(SeekableByteChannel) Channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
+ *
+ * @param the {@link SeekableByteChannel} type.
+ * @see FilterInputStream
+ * @see FilterOutputStream
+ * @see FilterReader
+ * @see FilterWritableByteChannel
+ * @see ProxyInputStream
+ * @see ProxyOutputStream
+ * @see ProxyReader
+ * @see ProxyWriter
+ * @since 2.22.0
+ */
+public class FilterSeekableByteChannel extends FilterByteChannel implements SeekableByteChannel {
+
+ /**
+ * Builds instances of {@link FilterSeekableByteChannel} for subclasses.
+ *
+ * @param The {@link FilterSeekableByteChannel} type.
+ * @param The {@link SeekableByteChannel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder, C extends SeekableByteChannel, B extends AbstractBuilder>
+ extends FilterByteChannel.AbstractBuilder {
+
+ /**
+ * Constructs a new builder for {@link FilterSeekableByteChannel}.
+ */
+ public AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterSeekableByteChannel}.
+ */
+ public static class Builder extends AbstractBuilder, SeekableByteChannel, Builder> {
+
+ /**
+ * Builds instances of {@link FilterSeekableByteChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterSeekableByteChannel get() throws IOException {
+ return new FilterSeekableByteChannel<>(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forSeekableByteChannel() {
+ return new Builder();
+ }
+
+ FilterSeekableByteChannel(final Builder builder) throws IOException {
+ super(builder);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterSeekableByteChannel(final C channel) {
+ super(channel);
+ }
+
+ @Override
+ public long position() throws IOException {
+ return channel.position();
+ }
+
+ @Override
+ public SeekableByteChannel position(final long newPosition) throws IOException {
+ return channel.position(newPosition);
+ }
+
+ @Override
+ public long size() throws IOException {
+ return channel.size();
+ }
+
+ @Override
+ public SeekableByteChannel truncate(final long size) throws IOException {
+ return channel.truncate(size);
+ }
+}
diff --git a/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java b/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java
new file mode 100644
index 00000000000..f07e8988c91
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/channels/FilterWritableByteChannel.java
@@ -0,0 +1,120 @@
+/*
+ * 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.channels;
+
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+import org.apache.commons.io.input.ProxyInputStream;
+import org.apache.commons.io.input.ProxyReader;
+import org.apache.commons.io.output.ProxyOutputStream;
+import org.apache.commons.io.output.ProxyWriter;
+
+/**
+ * A {@link WritableByteChannel} filter which delegates to the wrapped {@link WritableByteChannel}.
+ *
+ * A {@code FilterWritableByteChannel} wraps some other channel, which it uses as its basic source of data, possibly transforming the data along the way or
+ * providing additional functionality. The class {@code FilterWritableByteChannel} itself simply overrides methods of {@code WritableByteChannel} with versions
+ * that pass all requests to the wrapped channel. Subclasses of {@code FilterWritableByteChannel} may of course override any methods declared or inherited by
+ * {@code WritableByteChannel}, and may also provide additional fields and methods.
+ *
+ *
+ * You construct s simple instance with the {@link FilterWritableByteChannel#FilterWritableByteChannel(WritableByteChannel) Channel constructor} and more
+ * advanced instances through the {@link Builder}.
+ *
+ *
+ * @param the {@link WritableByteChannel} type.
+ * @see FilterInputStream
+ * @see FilterOutputStream
+ * @see FilterReader
+ * @see FilterWritableByteChannel
+ * @see ProxyInputStream
+ * @see ProxyOutputStream
+ * @see ProxyReader
+ * @see ProxyWriter
+ * @since 2.22.0
+ */
+public class FilterWritableByteChannel extends FilterChannel implements WritableByteChannel {
+
+ /**
+ * Builds instances of {@link FilterWritableByteChannel} for subclasses.
+ *
+ * @param The {@link FilterWritableByteChannel} type.
+ * @param The {@link WritableByteChannel} type wrapped by the FilterChannel.
+ * @param The builder type.
+ */
+ public abstract static class AbstractBuilder, C extends WritableByteChannel, B extends AbstractBuilder>
+ extends FilterChannel.AbstractBuilder {
+
+ /**
+ * Constructs a new builder for {@link FilterWritableByteChannel}.
+ */
+ public AbstractBuilder() {
+ // empty
+ }
+ }
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ public static class Builder extends AbstractBuilder, WritableByteChannel, Builder> {
+
+ /**
+ * Builds instances of {@link FilterByteChannel}.
+ */
+ protected Builder() {
+ // empty
+ }
+
+ @Override
+ public FilterWritableByteChannel get() throws IOException {
+ return new FilterWritableByteChannel<>(this);
+ }
+ }
+
+ /**
+ * Creates a new {@link Builder}.
+ *
+ * @return a new {@link Builder}.
+ */
+ public static Builder forWritableByteChannel() {
+ return new Builder();
+ }
+
+ FilterWritableByteChannel(final Builder builder) throws IOException {
+ super(builder);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param channel The channel to wrap.
+ */
+ public FilterWritableByteChannel(final C channel) {
+ super(channel);
+ }
+
+ @Override
+ public int write(final ByteBuffer src) throws IOException {
+ return channel.write(src);
+ }
+}
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 super Path> 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 super Path> 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/CountingPathVisitor.java b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
index ab02ad073e2..3f445010e26 100644
--- a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java
@@ -28,7 +28,6 @@
import org.apache.commons.io.file.Counters.PathCounters;
import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.SymbolicLinkFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.commons.io.function.IOBiFunction;
@@ -152,7 +151,7 @@ static UnaryOperator defaultDirectoryTransformer() {
}
static IOFileFilter defaultFileFilter() {
- return new SymbolicLinkFileFilter(FileVisitResult.TERMINATE, FileVisitResult.CONTINUE);
+ return TrueFileFilter.INSTANCE;
}
static PathCounters defaultPathCounters() {
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..305af952a49 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -137,9 +137,15 @@ private static boolean equalsIgnoreFileSystem(final Path path1, final Path path2
return extractKey(separator1, string1).equals(extractKey(separator2, string2));
}
+ /**
+ * Replaces the file separator in a path string with a string that is not legal in a path on Windows, Linux, and macOS.
+ *
+ * @param separator the file separator.
+ * @param string a path.
+ * @return a key.
+ */
static String extractKey(final String separator, final String string) {
- // Replace the file separator in a path string with a string that is not legal in a path on Windows, Linux, and macOS.
- return string.replaceAll("\\" + separator, ">");
+ return string.replace(separator, ">");
}
final boolean equals;
@@ -200,32 +206,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 +246,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.
*
@@ -266,7 +281,10 @@ private static AccumulatorPathVisitor accumulate(final Path directory, final int
}
/**
- * Cleans a directory by only deleting files, including in subdirectories, but without deleting the directories.
+ * Cleans a directory by only deleting files, including in subdirectories, without deleting directories.
+ *
+ * This leaves a directory empty of files but the directory and any subdirectories remain.
+ *
*
* @param directory directory to clean.
* @return The visitation path counters.
@@ -277,7 +295,10 @@ public static PathCounters cleanDirectory(final Path directory) throws IOExcepti
}
/**
- * Cleans a directory by only deleting files, including in subdirectories, but without deleting the directories.
+ * Cleans a directory by only deleting files, including in subdirectories, without deleting directories.
+ *
+ * This leaves a directory empty of files but the directory and any subdirectories remain.
+ *
*
* @param directory directory to clean.
* @param deleteOptions How to handle deletion.
@@ -378,7 +399,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 +414,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 +431,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 +520,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 +539,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 +561,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 +624,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 +792,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 +965,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 +1157,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 +1261,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 +1322,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 +1433,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 +1446,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 +1848,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 +1978,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..0465b77b41b 100644
--- a/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java
+++ b/src/main/java/org/apache/commons/io/file/StandardDeleteOption.java
@@ -22,7 +22,7 @@
import org.apache.commons.io.IOUtils;
/**
- * Defines the standard delete options.
+ * Enumerates the standard delete options.
*
* @since 2.8.0
*/
@@ -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..5b9a142f70c 100644
--- a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
@@ -17,7 +17,6 @@
package org.apache.commons.io.filefilter;
import java.io.File;
-import java.io.FileFilter;
import java.io.Serializable;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
@@ -29,7 +28,7 @@
import java.util.stream.Stream;
/**
- * A {@link FileFilter} providing conditional AND logic across a list of
+ * A {@link ConditionalFileFilter} providing conditional AND logic across a list of
* file filters. This filter returns {@code true} if all filters in the
* list return {@code true}. Otherwise, it returns {@code false}.
* Checking of the file filter list stops when the first filter returns
@@ -90,9 +89,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 +128,7 @@ public boolean accept(final File file, final String name) {
/**
* {@inheritDoc}
+ *
* @since 2.9.0
*/
@Override
@@ -187,7 +187,7 @@ public void setFileFilters(final List fileFilters) {
/**
* Builds a String representation of this file filter.
*
- * @return a String representation
+ * @return a String representation.
*/
@Override
public String toString() {
diff --git a/src/main/java/org/apache/commons/io/filefilter/CanExecuteFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/CanExecuteFileFilter.java
index 3941a9d74a8..8f262806119 100644
--- a/src/main/java/org/apache/commons/io/filefilter/CanExecuteFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/CanExecuteFileFilter.java
@@ -24,7 +24,7 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@link File}s that can be executed.
+ * This filter accepts {@link File}s that are executable.
*
* Example, showing how to print out a list of the
* current directory's executable files:
diff --git a/src/main/java/org/apache/commons/io/filefilter/CanReadFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/CanReadFileFilter.java
index da376e0f4f5..58d2ad7a50c 100644
--- a/src/main/java/org/apache/commons/io/filefilter/CanReadFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/CanReadFileFilter.java
@@ -24,7 +24,7 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@link File}s that can be read.
+ * This filter accepts {@link File}s that are readable.
*
* Example, showing how to print out a list of the current directory's readable files:
*
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..db209b4a50e 100644
--- a/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/CanWriteFileFilter.java
@@ -24,7 +24,7 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@link File}s that can be written to.
+ * This filter accepts {@link File}s that are writable.
*
* Example, showing how to print out a list of the current directory's writable files:
*
@@ -54,6 +54,7 @@
* Serialization is deprecated and will be removed in 3.0.
*
*
+ * @see Files#isWritable(Path)
* @since 1.3
*/
public class CanWriteFileFilter extends AbstractFileFilter implements Serializable {
@@ -75,7 +76,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 +87,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- * 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* Implementations may not have anything to unwrap and that behavior is undefined for now. *
+ * * @return the underlying Iterable. */ Iterable* Implementations may not have anything to unwrap and that behavior is undefined for now. *
+ * * @return the underlying Iterator. */ Iterator- * This class detects these bytes and, if required, can automatically skip them and return the subsequent byte as the - * first byte in the stream. + * This class detects these bytes and, if required, can automatically skip them and return the subsequent byte as the first byte in the stream. *
** The {@link ByteOrderMark} implementation has the following predefined BOMs: @@ -60,10 +60,7 @@ * *
* boolean include = true;
- * BOMInputStream bomIn = BOMInputStream.builder()
- * .setInputStream(in)
- * .setInclude(include)
- * .get();
+ * BOMInputStream bomIn = BOMInputStream.builder().setInputStream(in).setInclude(include).get();
* if (bomIn.hasBOM()) {
* // has a UTF-8 BOM
* }
@@ -72,10 +69,8 @@
* Example 3 - Detecting Multiple BOMs
*
*
- * BOMInputStream bomIn = BOMInputStream.builder()
- * .setInputStream(in)
- * .setByteOrderMarks(ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE)
- * .get();
+ * BOMInputStream bomIn = BOMInputStream.builder().setInputStream(in)
+ * .setByteOrderMarks(ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE).get();
* if (bomIn.hasBOM() == false) {
* // No BOM found
* } else if (bomIn.hasBOM(ByteOrderMark.UTF_16LE)) {
@@ -134,14 +129,13 @@ 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];
}
private ByteOrderMark[] byteOrderMarks = DEFAULT;
-
private boolean include;
/**
@@ -200,14 +194,13 @@ 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) {
this.include = include;
return this;
}
-
}
/**
@@ -229,65 +222,68 @@ public static Builder builder() {
* BOMs are sorted from longest to shortest.
*/
private final List bomList;
-
- private ByteOrderMark byteOrderMark;
+ private final ByteOrderMark byteOrderMark;
private int fbIndex;
private int[] firstBytes;
private final boolean include;
private boolean markedAtStart;
private int markFbIndex;
+ /**
+ * Constructs a new instance.
+ *
+ * @param builder The builder.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
+ */
private BOMInputStream(final Builder builder) throws IOException {
super(builder);
if (IOUtils.length(builder.byteOrderMarks) == 0) {
throw new IllegalArgumentException("No ByteOrderMark specified.");
}
this.include = builder.include;
- final List list = Arrays.asList(builder.byteOrderMarks);
+ final List bomList = Arrays.asList(builder.byteOrderMarks);
// Sort the BOMs to match the longest BOM first because some BOMs have the same starting two bytes.
- list.sort(ByteOrderMarkLengthComparator);
- this.bomList = list;
+ bomList.sort(ByteOrderMarkLengthComparator);
+ this.bomList = bomList;
+ this.byteOrderMark = readBom();
}
/**
* Constructs a new BOM InputStream that excludes a {@link ByteOrderMark#UTF_8} BOM.
*
- * @param delegate
- * the InputStream to delegate to
- * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}
+ * @param delegate the InputStream to delegate to.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
+ * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}.
*/
@Deprecated
- public BOMInputStream(final InputStream delegate) {
+ public BOMInputStream(final InputStream delegate) throws IOException {
this(delegate, false, Builder.DEFAULT);
}
/**
* Constructs a new BOM InputStream that detects a {@link ByteOrderMark#UTF_8} and optionally includes it.
*
- * @param delegate
- * the InputStream to delegate to
- * @param include
- * true to include the UTF-8 BOM or false to exclude it
- * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}
+ * @param delegate the InputStream to delegate to.
+ * @param include true to include the UTF-8 BOM or false to exclude it.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
+ * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}.
*/
@Deprecated
- public BOMInputStream(final InputStream delegate, final boolean include) {
+ public BOMInputStream(final InputStream delegate, final boolean include) throws IOException {
this(delegate, include, Builder.DEFAULT);
}
/**
* Constructs a new BOM InputStream that detects the specified BOMs and optionally includes them.
*
- * @param delegate
- * the InputStream to delegate to
- * @param include
- * true to include the specified BOMs or false to exclude them
- * @param boms
- * The BOMs to detect and optionally exclude
- * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}
+ * @param delegate the InputStream to delegate to.
+ * @param include true to include the specified BOMs or false to exclude them.
+ * @param boms The BOMs to detect and optionally exclude.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
+ * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}.
*/
@Deprecated
- public BOMInputStream(final InputStream delegate, final boolean include, final ByteOrderMark... boms) {
+ public BOMInputStream(final InputStream delegate, final boolean include, final ByteOrderMark... boms) throws IOException {
super(delegate);
if (IOUtils.length(boms) == 0) {
throw new IllegalArgumentException("No BOMs specified");
@@ -297,19 +293,19 @@ public BOMInputStream(final InputStream delegate, final boolean include, final B
// Sort the BOMs to match the longest BOM first because some BOMs have the same starting two bytes.
list.sort(ByteOrderMarkLengthComparator);
this.bomList = list;
+ this.byteOrderMark = readBom();
}
/**
* Constructs a new BOM InputStream that excludes the specified BOMs.
*
- * @param delegate
- * the InputStream to delegate to
- * @param boms
- * The BOMs to detect and exclude
+ * @param delegate the InputStream to delegate to.
+ * @param boms The BOMs to detect and exclude.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
* @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}
*/
@Deprecated
- public BOMInputStream(final InputStream delegate, final ByteOrderMark... boms) {
+ public BOMInputStream(final InputStream delegate, final ByteOrderMark... boms) throws IOException {
this(delegate, false, boms);
}
@@ -326,34 +322,26 @@ private ByteOrderMark find() {
* Gets the ByteOrderMark (Byte Order Mark).
*
* @return The BOM or null if none matched.
- * @throws IOException
- * if an error reading the first bytes of the stream occurs.
*/
- public ByteOrderMark getBOM() throws IOException {
- if (firstBytes == null) {
- byteOrderMark = readBom();
- }
+ public ByteOrderMark getBOM() {
return byteOrderMark;
}
/**
* Gets the BOM charset Name - {@link ByteOrderMark#getCharsetName()}.
*
- * @return The BOM charset Name or null if no BOM found
- * @throws IOException
- * if an error reading the first bytes of the stream occurs
+ * @return The BOM charset Name or null if no BOM found.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
*/
public String getBOMCharsetName() throws IOException {
- getBOM();
return byteOrderMark == null ? null : byteOrderMark.getCharsetName();
}
/**
* 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
- * @throws IOException
- * if an error reading the first bytes of the stream occurs
+ * @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.
*/
public boolean hasBOM() throws IOException {
return getBOM() != null;
@@ -362,13 +350,10 @@ 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
- * @throws IllegalArgumentException
- * 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
+ * @param bom 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.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
*/
public boolean hasBOM(final ByteOrderMark bom) throws IOException {
if (!bomList.contains(bom)) {
@@ -378,10 +363,9 @@ public boolean hasBOM(final ByteOrderMark bom) throws IOException {
}
/**
- * Invokes the delegate's {@code mark(int)} method.
+ * Invokes the delegate's {@link InputStream#mark(int)} method.
*
- * @param readLimit
- * read ahead limit
+ * @param readLimit read ahead limit.
*/
@Override
public synchronized void mark(final int readLimit) {
@@ -393,9 +377,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
+ * @param bom The BOM.
+ * @return true if the bytes match the BOM, otherwise false.
*/
private boolean matches(final ByteOrderMark bom) {
return bom.matches(firstBytes);
@@ -404,9 +387,8 @@ 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
- * @throws IOException
- * if an I/O error occurs
+ * @return the byte read (excluding BOM) or -1 if the end of stream.
+ * @throws IOException if an I/O error occurs.
*/
@Override
public int read() throws IOException {
@@ -416,15 +398,12 @@ public int read() throws IOException {
}
/**
- * Invokes the delegate's {@code read(byte[])} method, detecting and optionally skipping BOM.
+ * Invokes the delegate's {@link InputStream#read(byte[])} method, detecting and optionally skipping BOM.
*
- * @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
- * @throws NullPointerException
- * if the buffer is {@code null}
- * @throws IOException
- * if an I/O error occurs
+ * @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.
+ * @throws NullPointerException if the buffer is {@code null}
+ * @throws IOException if an I/O error occurs.
*/
@Override
public int read(final byte[] buf) throws IOException {
@@ -432,21 +411,15 @@ public int read(final byte[] buf) throws IOException {
}
/**
- * Invokes the delegate's {@code read(byte[], int, int)} method, detecting and optionally skipping BOM.
+ * Invokes the delegate's {@link InputStream#read(byte[], int, int)} method, detecting and optionally skipping BOM.
*
- * @param buf
- * the buffer to read the bytes into
- * @param off
- * 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
- * @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
+ * @param buf the buffer to read the bytes into.
+ * @param off 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.
+ * @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.
*/
@Override
public int read(final byte[] buf, int off, int len) throws IOException {
@@ -469,6 +442,12 @@ public int read(final byte[] buf, int off, int len) throws IOException {
return secondCount < 0 ? firstCount > 0 ? firstCount : EOF : firstCount + secondCount;
}
+ /**
+ * Reads the byte order mark.
+ *
+ * @return the byte order mark.
+ * @throws IOException if an error reading the first bytes of the stream occurs.
+ */
private ByteOrderMark readBom() throws IOException {
int fbLength = 0;
// BOMs are sorted from longest to shortest
@@ -501,18 +480,16 @@ 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();
return fbIndex < firstBytes.length ? firstBytes[fbIndex++] : EOF;
}
/**
- * Invokes the delegate's {@code reset()} method.
+ * Invokes the delegate's {@link InputStream#reset()} method.
*
- * @throws IOException
- * if an I/O error occurs
+ * @throws IOException if an I/O error occurs.
*/
@Override
public synchronized void reset() throws IOException {
@@ -524,13 +501,11 @@ public synchronized void reset() throws IOException {
}
/**
- * Invokes the delegate's {@code skip(long)} method, detecting and optionally skipping BOM.
+ * Invokes the delegate's {@link InputStream#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
- * @throws IOException
- * if an I/O error occurs
+ * @param n 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.
*/
@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..5ba0dfe6b18 100644
--- a/src/main/java/org/apache/commons/io/input/BoundedReader.java
+++ b/src/main/java/org/apache/commons/io/input/BoundedReader.java
@@ -36,12 +36,10 @@
*
* @since 2.5
*/
-public class BoundedReader extends Reader {
+public class BoundedReader extends ProxyReader {
private static final int INVALID = -1;
- private final Reader target;
-
private int charsRead;
private int markedAt = INVALID;
@@ -53,24 +51,14 @@ 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;
+ super(target);
this.maxCharsFromTargetReader = maxCharsFromTargetReader;
}
- /**
- * Closes the target
- *
- * @throws IOException If an I/O error occurs while calling the underlying reader's close method
- */
- @Override
- public void close() throws IOException {
- target.close();
- }
-
/**
* marks the target stream
*
@@ -78,49 +66,42 @@ 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);
+ super.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++;
- return target.read();
+ return super.read();
}
/**
* 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,12 +121,18 @@ 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
public void reset() throws IOException {
charsRead = markedAt;
- target.reset();
+ super.reset();
+ }
+
+ @Override
+ public long skip(final long n) throws IOException {
+ charsRead += n;
+ return super.skip(n);
}
}
diff --git a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
index bc491637dee..cd2e2fce9c3 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
@@ -106,7 +106,7 @@ public void close() throws IOException {
/**
* Gets the Throwable to throw. Package-private for testing.
*
- * @return the Throwable to throw.
+ * @return the Throwable to throw.
*/
Throwable getThrowable() {
return exceptionSupplier.get();
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..b58c6a891ac 100644
--- a/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java
@@ -16,8 +16,11 @@
*/
package org.apache.commons.io.input;
+import java.io.IOException;
import java.io.InputStream;
+import org.apache.commons.io.function.IOUnaryOperator;
+
/**
* Proxy stream that prevents the underlying input stream from being closed.
*
@@ -30,6 +33,50 @@
*/
public class CloseShieldInputStream extends ProxyInputStream {
+ /**
+ * Constructs a new builder for {@link CloseShieldInputStream}.
+ *
+ * @since 2.22.0
+ */
+ public static class Builder extends AbstractBuilder {
+
+ private IOUnaryOperator onClose = is -> ClosedInputStream.INSTANCE;
+
+ /**
+ * Constructs a new instance.
+ */
+ public Builder() {
+ // empty
+ }
+
+ @Override
+ public CloseShieldInputStream get() throws IOException {
+ return new CloseShieldInputStream(this);
+ }
+
+ /**
+ * Sets the {@code onClose} function. By default, replaces the underlying input stream when {@link #close()} is called.
+ *
+ * @param onClose the onClose function.
+ * @return {@code this} instance.
+ */
+ public Builder setOnClose(final IOUnaryOperator onClose) {
+ this.onClose = onClose;
+ return asThis();
+ }
+
+ }
+
+ /**
+ * Constructs a new builder for {@link CloseShieldInputStream}.
+ *
+ * @return the new builder.
+ * @since 2.22.0
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
/**
* Constructs a proxy that only shields {@link System#in} from closing.
*
@@ -44,18 +91,25 @@ 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) {
return new CloseShieldInputStream(inputStream);
}
+ private final IOUnaryOperator onClose;
+
+ private CloseShieldInputStream(final Builder builder) throws IOException {
+ super(builder.getInputStream());
+ this.onClose = builder.onClose;
+ }
+
/**
* 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.
@@ -63,16 +117,21 @@ public static CloseShieldInputStream wrap(final InputStream inputStream) {
@Deprecated
public CloseShieldInputStream(final InputStream inputStream) {
super(inputStream);
+ this.onClose = builder().onClose;
}
/**
- * Replaces the underlying input stream with a {@link ClosedInputStream}
- * sentinel. The original input stream will remain open, but this proxy will
- * appear closed.
+ * Applies the {@code onClose} function to the underlying input stream, replacing it with the result.
+ *
+ * By default, replaces the underlying input stream with a {@link ClosedInputStream} sentinel. The original input stream will remain open, but this proxy
+ * will appear closed.
+ *
+ *
+ * @throws IOException Thrown by the {@code onClose} function.
*/
@Override
- public void close() {
- in = ClosedInputStream.INSTANCE;
+ public void close() throws IOException {
+ in = onClose.apply(in);
}
}
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..b5b626a42c6 100644
--- a/src/main/java/org/apache/commons/io/input/Input.java
+++ b/src/main/java/org/apache/commons/io/input/Input.java
@@ -18,14 +18,15 @@
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.
+ * Throws an {@link IOException} on false input.
*
* @param isOpen whether an input is open or not.
* @throws IOException if {@code isOpen} is false indicating an input is closed.
@@ -36,4 +37,21 @@ static void checkOpen(final boolean isOpen) throws IOException {
}
}
+ /**
+ * Converts an {@link InterruptedException} to an {@link 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..fdff24eac0e 100644
--- a/src/main/java/org/apache/commons/io/input/ProxyInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/ProxyInputStream.java
@@ -27,7 +27,7 @@
import org.apache.commons.io.function.IOIntConsumer;
/**
- * A proxy stream which acts as a {@link FilterInputStream}, by passing all method calls on to the proxied stream, not changing which methods are called.
+ * An input stream proxy which delegates to the wrapped input stream.
*
* It is an alternative base class to {@link FilterInputStream} to increase reusability, because {@link FilterInputStream} changes the methods being called,
* such as read(byte[]) to read(byte[], int, int).
@@ -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
*
+ * Use with caution. + *
* * @param in The input stream to set in {@link java.io.FilterInputStream#in}. * @return {@code this} instance. @@ -389,7 +392,7 @@ public long skip(final long n) throws IOException { /** * Unwraps this instance by returning the underlying {@link InputStream}. *- * Use with caution; useful to query the underlying {@link InputStream}. + * Use with caution. *
* * @return the underlying {@link InputStream}. 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..b450891ef27 100644 --- a/src/main/java/org/apache/commons/io/input/ProxyReader.java +++ b/src/main/java/org/apache/commons/io/input/ProxyReader.java @@ -26,9 +26,7 @@ import org.apache.commons.io.IOUtils; /** - * A Proxy stream which acts as expected, that is it passes the method - * calls on to the proxied stream and doesn't change which methods are - * being called. + * A reader proxy which delegates to the wrapped reader. ** It is an alternative base class to FilterReader * to increase reusability, because FilterReader changes the @@ -40,7 +38,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' @@ -55,13 +53,15 @@ public ProxyReader(final Reader delegate) { * Subclasses can override this method to add common post-processing * functionality without having to override all the read methods. * The default implementation does nothing. + *
** Note this method is not called from {@link #skip(long)} or * {@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. @@ -78,13 +78,15 @@ protected void afterRead(final int n) throws IOException { * Subclasses can override this method to add common pre-processing * functionality without having to override all the read methods. * The default implementation does nothing. + * ** Note this method is not called from {@link #skip(long)} or * {@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 +96,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 +113,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 +125,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 +140,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 +150,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 +169,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 +189,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 +211,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 +232,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 +248,7 @@ public boolean ready() throws IOException { /** * Invokes the delegate's {@code reset()} method. + * * @throws IOException if an I/O error occurs. */ @Override @@ -247,10 +260,27 @@ public synchronized void reset() throws IOException { } } + /** + * Sets the underlying reader. + *+ * Use with caution. + *
+ * + * @param in The input stream to set in {@code java.io.Reader#in}. + * @return {@code this} instance. + * @since 2.22.0 + */ + public ProxyReader setReference(final Reader in) { + this.in = in; + return this; + } + + /** * 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 @@ -263,4 +293,17 @@ public long skip(final long ln) throws IOException { } } + /** + * Unwraps this instance by returning the underlying {@link Reader}. + *+ * Use with caution. + *
+ * + * @return the underlying {@link Reader}. + * @since 2.22.0 + */ + public Reader unwrap() { + return in; + } + } 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() { *+ * 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..7e7379e9216 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,17 +263,11 @@ 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) { - // @formatter:off - this(reader, - Charsets.toCharset(charset).newEncoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE), - bufferSize); - // @formatter:on + this(reader, newEncoder(charset), bufferSize); } /** @@ -284,9 +279,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 +298,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 +320,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 +337,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 +367,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 +410,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 +431,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 +443,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..43ad4da1040 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+ * 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..88f31b7854f 100644 --- a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java @@ -28,37 +28,16 @@ * * @since 2.5 */ -public class UnixLineEndingInputStream extends InputStream { - - private boolean atEos; - - private boolean atSlashCr; - - private boolean atSlashLf; - - private final InputStream in; - - private final boolean lineFeedAtEndOfFile; +public class UnixLineEndingInputStream extends AbstractLineEndingInputStream { /** * 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 - */ - public UnixLineEndingInputStream(final InputStream inputStream, final boolean ensureLineFeedAtEndOfFile) { - this.in = inputStream; - this.lineFeedAtEndOfFile = ensureLineFeedAtEndOfFile; - } - - /** - * Closes the stream. Also closes the underlying stream. - * @throws IOException If an I/O error occurs. + * @param inputStream The input stream to wrap. + * @param lineFeedAtEos true to ensure that the file ends with LF. */ - @Override - public void close() throws IOException { - super.close(); - in.close(); + public UnixLineEndingInputStream(final InputStream inputStream, final boolean lineFeedAtEos) { + super(inputStream, lineFeedAtEos); } /** @@ -68,7 +47,7 @@ public void close() throws IOException { * @return The next char to output to the stream. */ private int handleEos(final boolean previousWasSlashCr) { - if (previousWasSlashCr || !lineFeedAtEndOfFile) { + if (previousWasSlashCr || !lineFeedAtEos) { return EOF; } if (!atSlashLf) { @@ -78,14 +57,6 @@ private int handleEos(final boolean previousWasSlashCr) { return EOF; } - /** - * {@inheritDoc} - */ - @Override - public synchronized void mark(final int readLimit) { - throw UnsupportedOperationExceptions.mark(); - } - /** * {@inheritDoc} */ @@ -95,7 +66,7 @@ public synchronized int read() throws IOException { if (atEos) { return handleEos(previousWasSlashR); } - final int target = readWithUpdate(); + final int target = readUpdate(); if (atEos) { return handleEos(previousWasSlashR); } @@ -112,10 +83,11 @@ 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 { + private int readUpdate() throws IOException { final int target = this.in.read(); atEos = target == EOF; if (atEos) { 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..96c47e7b9af 100644 --- a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java @@ -92,10 +92,6 @@ public Builder() { // empty } - private byte[] checkOriginByteArray() throws IOException { - return checkOrigin().getByteArray(); - } - /** * Builds a new {@link UnsynchronizedByteArrayInputStream}. *@@ -207,13 +203,13 @@ private static int requireNonNegative(final int value, final String name) { private int markedOffset; private UnsynchronizedByteArrayInputStream(final Builder builder) throws IOException { - this(builder.checkOriginByteArray(), builder.offset, builder.length); + this(builder.getByteArray(), builder.offset, builder.length); } /** * 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 +220,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 +233,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/WindowsLineEndingInputStream.java b/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java index b09deec0d3e..24285adb6d3 100644 --- a/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java @@ -28,20 +28,10 @@ * * @since 2.5 */ -public class WindowsLineEndingInputStream extends InputStream { - - private boolean atEos; - - private boolean atSlashCr; - - private boolean atSlashLf; - - private final InputStream in; +public class WindowsLineEndingInputStream extends AbstractLineEndingInputStream { private boolean injectSlashLf; - private final boolean lineFeedAtEos; - /** * Constructs an input stream that filters another stream. * @@ -49,19 +39,7 @@ public class WindowsLineEndingInputStream extends InputStream { * @param lineFeedAtEos true to ensure that the stream ends with CRLF. */ public WindowsLineEndingInputStream(final InputStream in, final boolean lineFeedAtEos) { - this.in = in; - this.lineFeedAtEos = lineFeedAtEos; - } - - /** - * Closes the stream. Also closes the underlying stream. - * - * @throws IOException If an I/O error occurs. - */ - @Override - public void close() throws IOException { - super.close(); - in.close(); + super(in, lineFeedAtEos); } /** @@ -85,14 +63,6 @@ private int handleEos() { return EOF; } - /** - * {@inheritDoc} - */ - @Override - public synchronized void mark(final int readLimit) { - throw UnsupportedOperationExceptions.mark(); - } - /** * {@inheritDoc} */ 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..3b667ef1655 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. @@ -498,7 +497,7 @@ public XmlStreamReader(final InputStream inputStream, final boolean lenient, fin final BOMInputStream bom = new BOMInputStream(new BufferedInputStream(Objects.requireNonNull(inputStream, "inputStream"), IOUtils.DEFAULT_BUFFER_SIZE), false, BOMS); final BOMInputStream pis = new BOMInputStream(bom, true, XML_GUESS_BYTES); - this.encoding = processHttpStream(bom, pis, lenient); + this.encoding = toEncoding(bom, pis, lenient); this.reader = new InputStreamReader(pis, encoding); } @@ -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. @@ -603,7 +602,7 @@ public XmlStreamReader(final InputStream inputStream, final String httpContentTy final BOMInputStream bom = new BOMInputStream(new BufferedInputStream(Objects.requireNonNull(inputStream, "inputStream"), IOUtils.DEFAULT_BUFFER_SIZE), false, BOMS); final BOMInputStream pis = new BOMInputStream(bom, true, XML_GUESS_BYTES); - this.encoding = processHttpStream(bom, pis, lenient, httpContentType); + this.encoding = toEncoding(bom, pis, lenient, httpContentType); this.reader = new InputStreamReader(pis, encoding); } @@ -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. */ @@ -687,51 +686,168 @@ public XmlStreamReader(final URLConnection urlConnection, final String defaultEn .get(); // @formatter:on if (urlConnection instanceof HttpURLConnection || contentType != null) { - this.encoding = processHttpStream(bomInput, piInput, lenient, contentType); + this.encoding = toEncoding(bomInput, piInput, lenient, contentType); } else { - this.encoding = processHttpStream(bomInput, piInput, lenient); + this.encoding = toEncoding(bomInput, piInput, lenient); } this.reader = new InputStreamReader(piInput, encoding); } /** - * Calculates the HTTP encoding. - * @param bomEnc BOM encoding - * @param xmlGuessEnc XML Guess encoding - * @param xmlEnc XML encoding + * Closes the XmlStreamReader stream. + * + * @throws IOException thrown if there was a problem closing the stream. + */ + @Override + public void close() throws IOException { + reader.close(); + } + + /** + * Gets the default encoding to use if none is set in HTTP content-type, XML prolog and the rules based on content-type are not adequate. + *+ * If it is {@code null} the content-type based rules are used. + *
+ * + * @return the default encoding to use. + */ + public String getDefaultEncoding() { + return defaultEncoding; + } + + /** + * Gets the charset encoding of the XmlStreamReader. + * + * @return charset encoding. + */ + public String getEncoding() { + return encoding; + } + + /** + * 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. + * @throws IOException if an I/O error occurs. + */ + @Override + public int read(final char[] buf, final int offset, final int len) throws IOException { + return reader.read(buf, offset, len); + } + + /** + * Process the raw stream. + * + * @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. + * @throws IOException thrown if there is a problem reading the stream. + */ + private String toEncoding(final BOMInputStream bomInput, final BOMInputStream piInput, final boolean lenient) throws IOException { + final String bomEnc = bomInput.getBOMCharsetName(); + final String xmlGuessEnc = piInput.getBOMCharsetName(); + final String xmlEnc = getXmlProlog(piInput, xmlGuessEnc); + try { + return toRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); + } catch (final XmlStreamReaderException ex) { + if (lenient) { + return toEncodingLenient(null, ex); + } + throw ex; + } + } + + /** + * Processes an HTTP stream. + * + * @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 HTTP encoding + * @param httpContentType The HTTP content type. + * @return the encoding to be used. * @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) + private String toEncoding(final BOMInputStream bomInput, final BOMInputStream piInput, final boolean lenient, final String httpContentType) throws IOException { + final String bomEnc = bomInput.getBOMCharsetName(); + final String xmlGuessEnc = piInput.getBOMCharsetName(); + final String xmlEnc = getXmlProlog(piInput, xmlGuessEnc); + try { + return toHttpEncoding(bomEnc, xmlGuessEnc, xmlEnc, lenient, httpContentType); + } catch (final XmlStreamReaderException ex) { + if (lenient) { + return toEncodingLenient(httpContentType, ex); + } + throw ex; + } + } + /** + * Detects the encoding in lenient mode. + * + * @param httpContentType content-type header to use for the resolution of the charset encoding. + * @param ex The thrown exception. + * @return the encoding. + * @throws IOException thrown if there is a problem reading the stream. + */ + private String toEncodingLenient(String httpContentType, XmlStreamReaderException ex) throws IOException { + if (httpContentType != null && httpContentType.startsWith("text/html")) { + httpContentType = httpContentType.substring("text/html".length()); + httpContentType = "text/xml" + httpContentType; + try { + return toHttpEncoding(ex.getBomEncoding(), ex.getXmlGuessEncoding(), ex.getXmlEncoding(), true, httpContentType); + } catch (final XmlStreamReaderException ex2) { + ex = ex2; + } + } + String encoding = ex.getXmlEncoding(); + if (encoding == null) { + encoding = ex.getContentTypeEncoding(); + } + if (encoding == null) { + encoding = defaultEncoding == null ? UTF_8 : defaultEncoding; + } + return encoding; + } + + /** + * Calculates the HTTP 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. + * @throws IOException thrown if there is a problem reading the stream. + */ + String toHttpEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final boolean lenient, final String httpContentType) + throws IOException { // Lenient and has XML encoding if (lenient && xmlEnc != null) { return xmlEnc; } - // Determine mime/encoding content types from HTTP Content Type final String cTMime = getContentTypeMime(httpContentType); final String cTEnc = getContentTypeEncoding(httpContentType); final boolean appXml = isAppXml(cTMime); final boolean textXml = isTextXml(cTMime); - // Mime type NOT "application/xml" or "text/xml" if (!appXml && !textXml) { final String msg = MessageFormat.format(HTTP_EX_3, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); } - // No content type encoding if (cTEnc == null) { if (appXml) { - return calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); + return toRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); } return defaultEncoding == null ? US_ASCII : defaultEncoding; } - // UTF-16BE or UTF-16LE content type encoding if (cTEnc.equals(UTF_16BE) || cTEnc.equals(UTF_16LE)) { if (bomEnc != null) { @@ -740,7 +856,6 @@ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, fina } return cTEnc; } - // UTF-16 content type encoding if (cTEnc.equals(UTF_16)) { if (bomEnc != null && bomEnc.startsWith(UTF_16)) { @@ -749,7 +864,6 @@ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, fina final String msg = MessageFormat.format(HTTP_EX_2, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); } - // UTF-32BE or UTF-132E content type encoding if (cTEnc.equals(UTF_32BE) || cTEnc.equals(UTF_32LE)) { if (bomEnc != null) { @@ -758,7 +872,6 @@ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, fina } return cTEnc; } - // UTF-32 content type encoding if (cTEnc.equals(UTF_32)) { if (bomEnc != null && bomEnc.startsWith(UTF_32)) { @@ -767,20 +880,19 @@ String calculateHttpEncoding(final String bomEnc, final String xmlGuessEnc, fina final String msg = MessageFormat.format(HTTP_EX_2, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); throw new XmlStreamReaderException(msg, cTMime, cTEnc, bomEnc, xmlGuessEnc, xmlEnc); } - return cTEnc; } /** * 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 { + String toRawEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc) throws IOException { // BOM is Null if (bomEnc == null) { @@ -795,11 +907,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); } @@ -837,125 +945,4 @@ String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, final throw new XmlStreamReaderException(msg, bomEnc, xmlGuessEnc, xmlEnc); } - /** - * Closes the XmlStreamReader stream. - * - * @throws IOException thrown if there was a problem closing the stream. - */ - @Override - public void close() throws IOException { - reader.close(); - } - - /** - * 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 - * @throws IOException thrown if there is a problem reading the stream. - */ - private String doLenientDetection(String httpContentType, XmlStreamReaderException ex) throws IOException { - if (httpContentType != null && httpContentType.startsWith("text/html")) { - httpContentType = httpContentType.substring("text/html".length()); - httpContentType = "text/xml" + httpContentType; - try { - return calculateHttpEncoding(ex.getBomEncoding(), ex.getXmlGuessEncoding(), ex.getXmlEncoding(), true, httpContentType); - } catch (final XmlStreamReaderException ex2) { - ex = ex2; - } - } - String encoding = ex.getXmlEncoding(); - if (encoding == null) { - encoding = ex.getContentTypeEncoding(); - } - if (encoding == null) { - encoding = defaultEncoding == null ? UTF_8 : defaultEncoding; - } - return encoding; - } - - /** - * Gets the default encoding to use if none is set in HTTP content-type, XML prolog and the rules based on content-type are not adequate. - *- * If it is {@code null} the content-type based rules are used. - *
- * - * @return the default encoding to use. - */ - public String getDefaultEncoding() { - return defaultEncoding; - } - - /** - * Gets the charset encoding of the XmlStreamReader. - * - * @return charset encoding. - */ - public String getEncoding() { - return encoding; - } - - /** - * Process the raw stream. - * - * @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 - * @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 { - final String bomEnc = bomInput.getBOMCharsetName(); - final String xmlGuessEnc = piInput.getBOMCharsetName(); - final String xmlEnc = getXmlProlog(piInput, xmlGuessEnc); - try { - return calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc); - } catch (final XmlStreamReaderException ex) { - if (lenient) { - return doLenientDetection(null, ex); - } - throw ex; - } - } - - /** - * Processes an HTTP stream. - * - * @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 - * @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) - throws IOException { - final String bomEnc = bomInput.getBOMCharsetName(); - final String xmlGuessEnc = piInput.getBOMCharsetName(); - final String xmlEnc = getXmlProlog(piInput, xmlGuessEnc); - try { - return calculateHttpEncoding(bomEnc, xmlGuessEnc, xmlEnc, lenient, httpContentType); - } catch (final XmlStreamReaderException ex) { - if (lenient) { - return doLenientDetection(httpContentType, ex); - } - throw ex; - } - } - - /** - * 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 - * @throws IOException if an I/O error occurs. - */ - @Override - public int read(final char[] buf, final int offset, final int len) throws IOException { - return reader.read(buf, offset, len); - } - } 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* 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..90b65d28801 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