You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/09/26 14:59:03 UTC
[commons-io] 02/03: Sort members.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git
commit 73c3f9878622204982962cfb492a74c563e8903c
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Sep 26 10:38:00 2021 -0400
Sort members.
---
.../java/org/apache/commons/io/ByteOrderMark.java | 64 +--
.../org/apache/commons/io/ByteOrderParser.java | 12 +-
src/main/java/org/apache/commons/io/Charsets.java | 76 ++--
src/main/java/org/apache/commons/io/CopyUtils.java | 82 ++--
.../org/apache/commons/io/DirectoryWalker.java | 372 ++++++++---------
.../java/org/apache/commons/io/EndianUtils.java | 462 ++++++++++-----------
.../java/org/apache/commons/io/FileCleaner.java | 104 ++---
.../org/apache/commons/io/FileCleaningTracker.java | 294 ++++++-------
.../org/apache/commons/io/FileExistsException.java | 16 +-
.../org/apache/commons/io/FileSystemUtils.java | 272 ++++++------
.../java/org/apache/commons/io/FilenameUtils.java | 32 +-
src/main/java/org/apache/commons/io/HexDump.java | 52 +--
src/main/java/org/apache/commons/io/IOCase.java | 160 +++----
.../org/apache/commons/io/IOIndexedException.java | 26 +-
.../java/org/apache/commons/io/LineIterator.java | 58 +--
.../java/org/apache/commons/io/StreamIterator.java | 22 +-
.../org/apache/commons/io/TaggedIOException.java | 18 +-
.../java/org/apache/commons/io/ThreadMonitor.java | 48 +--
.../java/org/apache/commons/io/file/Counters.java | 16 +-
.../java/org/apache/commons/io/file/PathUtils.java | 8 +-
.../commons/io/filefilter/AndFileFilter.java | 22 +-
.../commons/io/filefilter/FalseFileFilter.java | 20 +-
.../commons/io/filefilter/FileFilterUtils.java | 54 +--
.../commons/io/filefilter/TrueFileFilter.java | 12 +-
.../commons/io/filefilter/WildcardFilter.java | 32 +-
.../org/apache/commons/io/function/IOFunction.java | 176 ++++----
.../commons/io/input/AutoCloseInputStream.java | 28 +-
.../apache/commons/io/input/BOMInputStream.java | 152 +++----
.../commons/io/input/BoundedInputStream.java | 164 ++++----
.../org/apache/commons/io/input/BoundedReader.java | 24 +-
.../apache/commons/io/input/BrokenInputStream.java | 26 +-
.../commons/io/input/CharSequenceInputStream.java | 166 ++++----
.../commons/io/input/CharSequenceReader.java | 48 +--
.../org/apache/commons/io/input/ClosedReader.java | 10 +-
.../commons/io/input/CountingInputStream.java | 82 ++--
.../input/MessageDigestCalculatingInputStream.java | 32 +-
.../apache/commons/io/input/NullInputStream.java | 120 +++---
.../org/apache/commons/io/input/NullReader.java | 114 ++---
.../apache/commons/io/input/ProxyInputStream.java | 216 +++++-----
.../org/apache/commons/io/input/ProxyReader.java | 206 ++++-----
.../apache/commons/io/input/ReaderInputStream.java | 146 +++----
.../apache/commons/io/input/TaggedInputStream.java | 22 +-
.../org/apache/commons/io/input/TaggedReader.java | 22 +-
.../apache/commons/io/input/TailerListener.java | 26 +-
.../commons/io/input/TailerListenerAdapter.java | 40 +-
.../apache/commons/io/input/TeeInputStream.java | 16 +-
.../commons/io/input/TimestampedObserver.java | 18 +-
.../io/input/UnixLineEndingInputStream.java | 78 ++--
.../input/UnsynchronizedByteArrayInputStream.java | 34 +-
.../io/input/WindowsLineEndingInputStream.java | 82 ++--
.../commons/io/input/XmlStreamReaderException.java | 40 +-
.../io/input/buffer/CircularBufferInputStream.java | 30 +-
.../io/input/buffer/CircularByteBuffer.java | 254 +++++------
.../io/input/buffer/PeekableInputStream.java | 14 +-
.../commons/io/monitor/FileAlterationListener.java | 30 +-
.../io/monitor/FileAlterationListenerAdaptor.java | 30 +-
.../commons/io/monitor/FileAlterationMonitor.java | 78 ++--
.../commons/io/monitor/FileAlterationObserver.java | 202 ++++-----
.../org/apache/commons/io/monitor/FileEntry.java | 234 +++++------
.../io/output/AbstractByteArrayOutputStream.java | 382 ++++++++---------
.../commons/io/output/AppendableOutputStream.java | 18 +-
.../commons/io/output/BrokenOutputStream.java | 20 +-
.../org/apache/commons/io/output/BrokenWriter.java | 24 +-
.../commons/io/output/ByteArrayOutputStream.java | 144 +++----
.../commons/io/output/ChunkedOutputStream.java | 18 +-
.../apache/commons/io/output/ChunkedWriter.java | 16 +-
.../commons/io/output/ClosedOutputStream.java | 10 +-
.../commons/io/output/CountingOutputStream.java | 56 +--
.../apache/commons/io/output/NullOutputStream.java | 38 +-
.../org/apache/commons/io/output/NullWriter.java | 42 +-
.../commons/io/output/ProxyOutputStream.java | 136 +++---
.../org/apache/commons/io/output/ProxyWriter.java | 190 ++++-----
.../commons/io/output/StringBuilderWriter.java | 38 +-
.../commons/io/output/TaggedOutputStream.java | 22 +-
.../org/apache/commons/io/output/TaggedWriter.java | 22 +-
.../apache/commons/io/output/TeeOutputStream.java | 66 +--
.../io/output/UncheckedFilterOutputStream.java | 8 +-
.../UnsynchronizedByteArrayOutputStream.java | 124 +++---
.../commons/io/output/WriterOutputStream.java | 230 +++++-----
.../apache/commons/io/output/XmlStreamWriter.java | 88 ++--
.../io/serialization/RegexpClassNameMatcher.java | 18 +-
.../serialization/ValidatingObjectInputStream.java | 150 +++----
82 files changed, 3577 insertions(+), 3577 deletions(-)
diff --git a/src/main/java/org/apache/commons/io/ByteOrderMark.java b/src/main/java/org/apache/commons/io/ByteOrderMark.java
index d2fbbfd..75da194 100644
--- a/src/main/java/org/apache/commons/io/ByteOrderMark.java
+++ b/src/main/java/org/apache/commons/io/ByteOrderMark.java
@@ -88,21 +88,27 @@ public class ByteOrderMark implements Serializable {
}
/**
- * Gets the name of the {@link java.nio.charset.Charset} the BOM represents.
- *
- * @return the character set name
- */
- public String getCharsetName() {
- return charsetName;
- }
-
- /**
- * Gets the length of the BOM's bytes.
+ * Indicates if this BOM's bytes equals another.
*
- * @return the length of the BOM's bytes
+ * @param obj The object to compare to
+ * @return true if the bom's bytes are equal, otherwise
+ * false
*/
- public int length() {
- return bytes.length;
+ @Override
+ public boolean equals(final Object obj) {
+ if (!(obj instanceof ByteOrderMark)) {
+ return false;
+ }
+ final ByteOrderMark bom = (ByteOrderMark)obj;
+ if (bytes.length != bom.length()) {
+ return false;
+ }
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != bom.get(i)) {
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -129,27 +135,12 @@ public class ByteOrderMark implements Serializable {
}
/**
- * Indicates if this BOM's bytes equals another.
+ * Gets the name of the {@link java.nio.charset.Charset} the BOM represents.
*
- * @param obj The object to compare to
- * @return true if the bom's bytes are equal, otherwise
- * false
+ * @return the character set name
*/
- @Override
- public boolean equals(final Object obj) {
- if (!(obj instanceof ByteOrderMark)) {
- return false;
- }
- final ByteOrderMark bom = (ByteOrderMark)obj;
- if (bytes.length != bom.length()) {
- return false;
- }
- for (int i = 0; i < bytes.length; i++) {
- if (bytes[i] != bom.get(i)) {
- return false;
- }
- }
- return true;
+ public String getCharsetName() {
+ return charsetName;
}
/**
@@ -168,6 +159,15 @@ public class ByteOrderMark implements Serializable {
}
/**
+ * Gets the length of the BOM's bytes.
+ *
+ * @return the length of the BOM's bytes
+ */
+ public int length() {
+ return bytes.length;
+ }
+
+ /**
* Converts this instance to a String representation of the BOM.
*
* @return the length of the BOM's bytes
diff --git a/src/main/java/org/apache/commons/io/ByteOrderParser.java b/src/main/java/org/apache/commons/io/ByteOrderParser.java
index a0124c0..bcf1e5c 100644
--- a/src/main/java/org/apache/commons/io/ByteOrderParser.java
+++ b/src/main/java/org/apache/commons/io/ByteOrderParser.java
@@ -27,12 +27,6 @@ import java.nio.ByteOrder;
public final class ByteOrderParser {
/**
- * ByteOrderUtils is a static utility class, so prevent construction with a private constructor.
- */
- private ByteOrderParser() {
- }
-
- /**
* Parses the String argument as a {@link ByteOrder}.
* <p>
* Returns {@code ByteOrder.LITTLE_ENDIAN} if the given value is {@code "LITTLE_ENDIAN"}.
@@ -63,4 +57,10 @@ public final class ByteOrderParser {
", " + ByteOrder.BIG_ENDIAN);
}
+ /**
+ * ByteOrderUtils is a static utility class, so prevent construction with a private constructor.
+ */
+ private ByteOrderParser() {
+ }
+
}
diff --git a/src/main/java/org/apache/commons/io/Charsets.java b/src/main/java/org/apache/commons/io/Charsets.java
index ce9b347..d2ba98e 100644
--- a/src/main/java/org/apache/commons/io/Charsets.java
+++ b/src/main/java/org/apache/commons/io/Charsets.java
@@ -74,44 +74,6 @@ public class Charsets {
}
/**
- * Constructs a sorted map from canonical charset names to charset objects required of every implementation of the
- * Java platform.
- * <p>
- * From the Java documentation <a href="https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html">
- * Standard charsets</a>:
- * </p>
- *
- * @return An immutable, case-insensitive map from canonical charset names to charset objects.
- * @see Charset#availableCharsets()
- * @since 2.5
- */
- public static SortedMap<String, Charset> requiredCharsets() {
- return STANDARD_CHARSET_MAP;
- }
-
- /**
- * Returns the given Charset or the default Charset if the given Charset is null.
- *
- * @param charset
- * A charset or null.
- * @return the given Charset or the default Charset if the given Charset is null
- */
- public static Charset toCharset(final Charset charset) {
- return charset == null ? Charset.defaultCharset() : charset;
- }
-
- /**
- * Returns a Charset for the named charset. If the name is null, return the default Charset.
- *
- * @param charsetName The name of the requested charset, may be null.
- * @return a Charset for the named charset.
- * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
- */
- public static Charset toCharset(final String charsetName) throws UnsupportedCharsetException {
- return charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName);
- }
-
- /**
* CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.
* <p>
* Every implementation of the Java platform is required to support this character encoding.
@@ -193,4 +155,42 @@ public class Charsets {
*/
@Deprecated
public static final Charset UTF_8 = StandardCharsets.UTF_8;
+
+ /**
+ * Constructs a sorted map from canonical charset names to charset objects required of every implementation of the
+ * Java platform.
+ * <p>
+ * From the Java documentation <a href="https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html">
+ * Standard charsets</a>:
+ * </p>
+ *
+ * @return An immutable, case-insensitive map from canonical charset names to charset objects.
+ * @see Charset#availableCharsets()
+ * @since 2.5
+ */
+ public static SortedMap<String, Charset> requiredCharsets() {
+ return STANDARD_CHARSET_MAP;
+ }
+
+ /**
+ * Returns the given Charset or the default Charset if the given Charset is null.
+ *
+ * @param charset
+ * A charset or null.
+ * @return the given Charset or the default Charset if the given Charset is null
+ */
+ public static Charset toCharset(final Charset charset) {
+ return charset == null ? Charset.defaultCharset() : charset;
+ }
+
+ /**
+ * Returns a Charset for the named charset. If the name is null, return the default Charset.
+ *
+ * @param charsetName The name of the requested charset, may be null.
+ * @return a Charset for the named charset.
+ * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
+ */
+ public static Charset toCharset(final String charsetName) throws UnsupportedCharsetException {
+ return charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName);
+ }
}
diff --git a/src/main/java/org/apache/commons/io/CopyUtils.java b/src/main/java/org/apache/commons/io/CopyUtils.java
index 0e1ab2f..b90789c 100644
--- a/src/main/java/org/apache/commons/io/CopyUtils.java
+++ b/src/main/java/org/apache/commons/io/CopyUtils.java
@@ -114,11 +114,6 @@ import java.nio.charset.Charset;
public class CopyUtils {
/**
- * Instances should NOT be constructed in standard programming.
- */
- public CopyUtils() { }
-
- /**
* Copies bytes from a {@code byte[]} to an {@code OutputStream}.
* @param input the byte array to read from
* @param output the {@code OutputStream} to write to
@@ -177,35 +172,6 @@ public class CopyUtils {
return count;
}
- // ----------------------------------------------------------------
- // Reader -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copies chars from a {@code Reader} to a {@code Writer}.
- * @param input the {@code Reader} to read from
- * @param output the {@code 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.getCharArray();
- int count = 0;
- int n;
- while (EOF != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- // ----------------------------------------------------------------
- // InputStream -> Writer
- // ----------------------------------------------------------------
-
/**
* Copies and convert bytes from an {@code InputStream} to chars on a
* {@code Writer}.
@@ -225,6 +191,10 @@ public class CopyUtils {
copy(in, output);
}
+ // ----------------------------------------------------------------
+ // Reader -> Writer
+ // ----------------------------------------------------------------
+
/**
* Copies and convert bytes from an {@code InputStream} to chars on a
* {@code Writer}, using the specified encoding.
@@ -244,9 +214,8 @@ public class CopyUtils {
copy(in, output);
}
-
// ----------------------------------------------------------------
- // Reader -> OutputStream
+ // InputStream -> Writer
// ----------------------------------------------------------------
/**
@@ -294,11 +263,33 @@ public class CopyUtils {
out.flush();
}
+
// ----------------------------------------------------------------
- // String -> OutputStream
+ // Reader -> OutputStream
// ----------------------------------------------------------------
/**
+ * Copies chars from a {@code Reader} to a {@code Writer}.
+ * @param input the {@code Reader} to read from
+ * @param output the {@code 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.getCharArray();
+ int count = 0;
+ int n;
+ while (EOF != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
+
+ /**
* Serialize chars from a {@code String} to bytes on an
* {@code OutputStream}, and
* flush the {@code OutputStream}.
@@ -322,6 +313,10 @@ public class CopyUtils {
out.flush();
}
+ // ----------------------------------------------------------------
+ // String -> OutputStream
+ // ----------------------------------------------------------------
+
/**
* Serialize chars from a {@code String} to bytes on an
* {@code OutputStream}, and
@@ -347,10 +342,6 @@ public class CopyUtils {
out.flush();
}
- // ----------------------------------------------------------------
- // String -> Writer
- // ----------------------------------------------------------------
-
/**
* Copies chars from a {@code String} to a {@code Writer}.
* @param input the {@code String} to read from
@@ -362,4 +353,13 @@ public class CopyUtils {
output.write(input);
}
+ // ----------------------------------------------------------------
+ // String -> Writer
+ // ----------------------------------------------------------------
+
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public CopyUtils() { }
+
}
diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java
index 0aa9b92..ffc4fd9 100644
--- a/src/main/java/org/apache/commons/io/DirectoryWalker.java
+++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java
@@ -255,9 +255,68 @@ import org.apache.commons.io.filefilter.TrueFileFilter;
public abstract class DirectoryWalker<T> {
/**
+ * CancelException is thrown in DirectoryWalker to cancel the current
+ * processing.
+ */
+ public static class CancelException extends IOException {
+
+ /** Serialization id. */
+ private static final long serialVersionUID = 1347339620135041008L;
+
+ /** 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;
+
+ /**
+ * Constructs a {@code 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
+ */
+ public CancelException(final File file, final int depth) {
+ this("Operation Cancelled", file, depth);
+ }
+
+ /**
+ * Constructs a {@code CancelException} with
+ * 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
+ */
+ public CancelException(final String message, final File file, final int depth) {
+ super(message);
+ this.file = file;
+ this.depth = depth;
+ }
+
+ /**
+ * Returns the depth when the operation was cancelled.
+ *
+ * @return the depth when the operation was cancelled
+ */
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * Returns the file when the operation was cancelled.
+ *
+ * @return the file when the operation was cancelled
+ */
+ public File getFile() {
+ return file;
+ }
+ }
+ /**
* The file filter to use to filter files and directories.
*/
private final FileFilter filter;
+
/**
* The limit on the directory depth to walk.
*/
@@ -317,70 +376,6 @@ public abstract class DirectoryWalker<T> {
}
/**
- * Internal method that walks the directory hierarchy in a depth-first manner.
- * <p>
- * Users of this class do not need to call this method. This method will
- * be called automatically by another (public) method on the specific subclass.
- * </p>
- * <p>
- * Writers of subclasses should call this method to start the directory walk.
- * Once called, this method will emit events as it walks the hierarchy.
- * The event methods have the prefix {@code handle}.
- * </p>
- *
- * @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<T> results) throws IOException {
- Objects.requireNonNull(startDirectory, "startDirectory");
- try {
- handleStart(startDirectory, results);
- walk(startDirectory, 0, results);
- handleEnd(results);
- } catch(final CancelException cancel) {
- handleCancelled(startDirectory, results, cancel);
- }
- }
-
- /**
- * 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
- */
- private void walk(final File directory, final int depth, final Collection<T> results) throws IOException {
- checkIfCancelled(directory, depth, results);
- if (handleDirectory(directory, depth, results)) {
- handleDirectoryStart(directory, depth, results);
- final int childDepth = depth + 1;
- if (depthLimit < 0 || childDepth <= depthLimit) {
- checkIfCancelled(directory, depth, results);
- File[] childFiles = filter == null ? directory.listFiles() : directory.listFiles(filter);
- childFiles = filterDirectoryContents(directory, depth, childFiles);
- if (childFiles == null) {
- handleRestricted(directory, childDepth, results);
- } else {
- for (final File childFile : childFiles) {
- if (childFile.isDirectory()) {
- walk(childFile, childDepth, results);
- } else {
- checkIfCancelled(childFile, childDepth, results);
- handleFile(childFile, childDepth, results);
- checkIfCancelled(childFile, childDepth, results);
- }
- }
- }
- }
- handleDirectoryEnd(directory, depth, results);
- }
- checkIfCancelled(directory, depth, results);
- }
-
- /**
* Checks whether the walk has been cancelled by calling {@link #handleIsCancelled},
* throwing a {@code CancelException} if it has.
* <p>
@@ -403,48 +398,22 @@ public abstract class DirectoryWalker<T> {
}
/**
- * Overridable callback method invoked to determine if the entire walk
- * operation should be immediately cancelled.
- * <p>
- * This method should be implemented by those subclasses that want to
- * provide a public {@code cancel()} method available from another
- * thread. The design pattern for the subclass should be as follows:
- * </p>
- * <pre>
- * public class FooDirectoryWalker extends DirectoryWalker {
- * private volatile boolean cancelled = false;
- *
- * public void cancel() {
- * cancelled = true;
- * }
- * private void handleIsCancelled(File file, int depth, Collection results) {
- * return cancelled;
- * }
- * protected void handleCancelled(File startDirectory,
- * Collection results, CancelException cancel) {
- * // implement processing required when a cancellation occurs
- * }
- * }
- * </pre>
- * <p>
- * If this method returns true, then the directory walk is immediately
- * cancelled. The next callback method will be {@link #handleCancelled}.
- * </p>
+ * Overridable callback method invoked with the contents of each directory.
* <p>
- * This implementation returns false.
+ * This implementation returns the files unchanged
* </p>
*
- * @param file the file or directory being processed
+ * @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 if the walk has been cancelled
+ * @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
+ * @since 2.0
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected boolean handleIsCancelled(
- final File file, final int depth, final Collection<T> results) throws IOException {
- // do nothing - overridable by subclass
- return false; // not cancelled
+ protected File[] filterDirectoryContents(final File directory, final int depth, final File... files) throws
+ IOException {
+ return files;
}
/**
@@ -468,21 +437,6 @@ public abstract class DirectoryWalker<T> {
}
/**
- * Overridable callback method invoked at the start of processing.
- * <p>
- * This implementation does nothing.
- * </p>
- *
- * @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<T> results) throws IOException {
- // do nothing - overridable by subclass
- }
-
- /**
* Overridable callback method invoked to determine if a directory should be processed.
* <p>
* This method returns a boolean to indicate if the directory should be examined or not.
@@ -507,39 +461,51 @@ public abstract class DirectoryWalker<T> {
}
/**
- * Overridable callback method invoked at the start of processing each directory.
+ * Overridable callback method invoked at the end of processing each directory.
* <p>
* This implementation does nothing.
* </p>
*
- * @param directory the current directory being processed
+ * @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 handleDirectoryStart(final File directory, final int depth, final Collection<T> results) throws
+ protected void handleDirectoryEnd(final File directory, final int depth, final Collection<T> results) throws
IOException {
// do nothing - overridable by subclass
}
/**
- * Overridable callback method invoked with the contents of each directory.
+ * Overridable callback method invoked at the start of processing each directory.
* <p>
- * This implementation returns the files unchanged
+ * This implementation does nothing.
* </p>
*
* @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
+ * @param results the collection of result objects, may be updated
* @throws IOException if an I/O Error occurs
- * @since 2.0
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected File[] filterDirectoryContents(final File directory, final int depth, final File... files) throws
+ protected void handleDirectoryStart(final File directory, final int depth, final Collection<T> results) throws
IOException {
- return files;
+ // do nothing - overridable by subclass
+ }
+
+ /**
+ * Overridable callback method invoked at the end of processing.
+ * <p>
+ * This implementation does nothing.
+ * </p>
+ *
+ * @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<T> results) throws IOException {
+ // do nothing - overridable by subclass
}
/**
@@ -559,109 +525,143 @@ public abstract class DirectoryWalker<T> {
}
/**
- * Overridable callback method invoked for each restricted directory.
+ * Overridable callback method invoked to determine if the entire walk
+ * operation should be immediately cancelled.
* <p>
- * This implementation does nothing.
+ * This method should be implemented by those subclasses that want to
+ * provide a public {@code cancel()} method available from another
+ * thread. The design pattern for the subclass should be as follows:
* </p>
+ * <pre>
+ * public class FooDirectoryWalker extends DirectoryWalker {
+ * private volatile boolean cancelled = false;
*
- * @param directory the restricted directory
+ * public void cancel() {
+ * cancelled = true;
+ * }
+ * private void handleIsCancelled(File file, int depth, Collection results) {
+ * return cancelled;
+ * }
+ * protected void handleCancelled(File startDirectory,
+ * Collection results, CancelException cancel) {
+ * // implement processing required when a cancellation occurs
+ * }
+ * }
+ * </pre>
+ * <p>
+ * If this method returns true, then the directory walk is immediately
+ * cancelled. The next callback method will be {@link #handleCancelled}.
+ * </p>
+ * <p>
+ * This implementation returns false.
+ * </p>
+ *
+ * @param file the file or directory being processed
* @param depth the current directory level (starting directory = 0)
* @param results the collection of result objects, may be updated
+ * @return true if the walk has been cancelled
* @throws IOException if an I/O Error occurs
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleRestricted(final File directory, final int depth, final Collection<T> results) throws
- IOException {
+ protected boolean handleIsCancelled(
+ final File file, final int depth, final Collection<T> results) throws IOException {
// do nothing - overridable by subclass
+ return false; // not cancelled
}
/**
- * Overridable callback method invoked at the end of processing each directory.
+ * Overridable callback method invoked for each restricted directory.
* <p>
* This implementation does nothing.
* </p>
*
- * @param directory the directory being processed
+ * @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 handleDirectoryEnd(final File directory, final int depth, final Collection<T> results) throws
+ protected void handleRestricted(final File directory, final int depth, final Collection<T> results) throws
IOException {
// do nothing - overridable by subclass
}
/**
- * Overridable callback method invoked at the end of processing.
+ * Overridable callback method invoked at the start of processing.
* <p>
* This implementation does nothing.
* </p>
*
+ * @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 handleEnd(final Collection<T> results) throws IOException {
+ protected void handleStart(final File startDirectory, final Collection<T> results) throws IOException {
// do nothing - overridable by subclass
}
/**
- * CancelException is thrown in DirectoryWalker to cancel the current
- * processing.
+ * Internal method that walks the directory hierarchy in a depth-first manner.
+ * <p>
+ * Users of this class do not need to call this method. This method will
+ * be called automatically by another (public) method on the specific subclass.
+ * </p>
+ * <p>
+ * Writers of subclasses should call this method to start the directory walk.
+ * Once called, this method will emit events as it walks the hierarchy.
+ * The event methods have the prefix {@code handle}.
+ * </p>
+ *
+ * @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
*/
- public static class CancelException extends IOException {
-
- /** Serialization id. */
- private static final long serialVersionUID = 1347339620135041008L;
-
- /** 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;
-
- /**
- * Constructs a {@code 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
- */
- public CancelException(final File file, final int depth) {
- this("Operation Cancelled", file, depth);
- }
-
- /**
- * Constructs a {@code CancelException} with
- * 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
- */
- public CancelException(final String message, final File file, final int depth) {
- super(message);
- this.file = file;
- this.depth = depth;
- }
-
- /**
- * Returns the file when the operation was cancelled.
- *
- * @return the file when the operation was cancelled
- */
- public File getFile() {
- return file;
+ protected final void walk(final File startDirectory, final Collection<T> results) throws IOException {
+ Objects.requireNonNull(startDirectory, "startDirectory");
+ try {
+ handleStart(startDirectory, results);
+ walk(startDirectory, 0, results);
+ handleEnd(results);
+ } catch(final CancelException cancel) {
+ handleCancelled(startDirectory, results, cancel);
}
+ }
- /**
- * Returns the depth when the operation was cancelled.
- *
- * @return the depth when the operation was cancelled
- */
- public int getDepth() {
- return depth;
+ /**
+ * 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
+ */
+ private void walk(final File directory, final int depth, final Collection<T> results) throws IOException {
+ checkIfCancelled(directory, depth, results);
+ if (handleDirectory(directory, depth, results)) {
+ handleDirectoryStart(directory, depth, results);
+ final int childDepth = depth + 1;
+ if (depthLimit < 0 || childDepth <= depthLimit) {
+ checkIfCancelled(directory, depth, results);
+ File[] childFiles = filter == null ? directory.listFiles() : directory.listFiles(filter);
+ childFiles = filterDirectoryContents(directory, depth, childFiles);
+ if (childFiles == null) {
+ handleRestricted(directory, childDepth, results);
+ } else {
+ for (final File childFile : childFiles) {
+ if (childFile.isDirectory()) {
+ walk(childFile, childDepth, results);
+ } else {
+ checkIfCancelled(childFile, childDepth, results);
+ handleFile(childFile, childDepth, results);
+ checkIfCancelled(childFile, childDepth, results);
+ }
+ }
+ }
+ }
+ handleDirectoryEnd(directory, depth, results);
}
+ 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 849f86b..e2e8e12 100644
--- a/src/main/java/org/apache/commons/io/EndianUtils.java
+++ b/src/main/java/org/apache/commons/io/EndianUtils.java
@@ -40,136 +40,148 @@ import java.io.OutputStream;
public class EndianUtils {
/**
- * Instances should NOT be constructed in standard programming.
+ * Reads the next byte from the input stream.
+ * @param input the stream
+ * @return the byte
+ * @throws IOException if the end of file is reached
*/
- public EndianUtils() {
+ private static int read(final InputStream input) throws IOException {
+ final int value = input.read();
+
+ if (EOF == value) {
+ throw new EOFException("Unexpected EOF reached");
+ }
+
+ return value;
}
// ========================================== Swapping routines
/**
- * Converts a "short" value between endian systems.
- * @param value value to convert
- * @return the converted value
+ * Reads a "double" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
+ * @param data source byte array
+ * @param offset starting offset in the byte array
+ * @return the value read
*/
- public static short swapShort(final short value) {
- return (short) ( ( ( ( value >> 0 ) & 0xff ) << 8 ) +
- ( ( ( value >> 8 ) & 0xff ) << 0 ) );
+ public static double readSwappedDouble(final byte[] data, final int offset) {
+ return Double.longBitsToDouble( readSwappedLong( data, offset ) );
}
/**
- * Converts a "int" value between endian systems.
- * @param value value to convert
- * @return the converted value
+ * Reads a "double" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static int swapInteger(final int value) {
- return
- ( ( ( value >> 0 ) & 0xff ) << 24 ) +
- ( ( ( value >> 8 ) & 0xff ) << 16 ) +
- ( ( ( value >> 16 ) & 0xff ) << 8 ) +
- ( ( ( value >> 24 ) & 0xff ) << 0 );
+ public static double readSwappedDouble(final InputStream input) throws IOException {
+ return Double.longBitsToDouble(readSwappedLong(input));
}
/**
- * Converts a "long" value between endian systems.
- * @param value value to convert
- * @return the converted value
+ * Reads a "float" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
+ * @param data source byte array
+ * @param offset starting offset in the byte array
+ * @return the value read
*/
- public static long swapLong(final long value) {
- return
- ( ( ( value >> 0 ) & 0xff ) << 56 ) +
- ( ( ( value >> 8 ) & 0xff ) << 48 ) +
- ( ( ( value >> 16 ) & 0xff ) << 40 ) +
- ( ( ( value >> 24 ) & 0xff ) << 32 ) +
- ( ( ( value >> 32 ) & 0xff ) << 24 ) +
- ( ( ( value >> 40 ) & 0xff ) << 16 ) +
- ( ( ( value >> 48 ) & 0xff ) << 8 ) +
- ( ( ( value >> 56 ) & 0xff ) << 0 );
+ public static float readSwappedFloat(final byte[] data, final int offset) {
+ return Float.intBitsToFloat( readSwappedInteger( data, offset ) );
}
/**
- * Converts a "float" value between endian systems.
- * @param value value to convert
- * @return the converted value
+ * Reads a "float" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static float swapFloat(final float value) {
- return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) );
+ public static float readSwappedFloat(final InputStream input) throws IOException {
+ return Float.intBitsToFloat(readSwappedInteger(input));
}
/**
- * Converts a "double" value between endian systems.
- * @param value value to convert
- * @return the converted value
+ * Reads a "int" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
+ * @param data source byte array
+ * @param offset starting offset in the byte array
+ * @return the value read
*/
- public static double swapDouble(final double value) {
- return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) );
+ public static int readSwappedInteger(final byte[] data, final int offset) {
+ return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
+ ( ( data[ offset + 1 ] & 0xff ) << 8 ) +
+ ( ( data[ offset + 2 ] & 0xff ) << 16 ) +
+ ( ( data[ offset + 3 ] & 0xff ) << 24 ) );
}
// ========================================== Swapping read/write routines
/**
- * Writes a "short" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a "int" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedShort(final byte[] data, final int offset, final short value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
+ 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);
}
/**
- * Reads a "short" value from a byte array at a given offset. The value is
+ * Reads a "long" value from a byte array at a given offset. The value is
* converted to the opposed endian system while reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
- public static short readSwappedShort(final byte[] data, final int offset) {
- return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
+ public static long readSwappedLong(final byte[] data, final int offset) {
+ final long low = readSwappedInteger(data, offset);
+ final long high = readSwappedInteger(data, offset + 4);
+ return (high << 32) + (0xffffffffL & low);
}
/**
- * Reads an unsigned short (16-bit) value from a byte array at a given
- * offset. The value is converted to the opposed endian system while
- * reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * Reads a "long" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static int readSwappedUnsignedShort(final byte[] data, final int offset) {
- return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
+ public static long readSwappedLong(final InputStream input) throws IOException {
+ final byte[] bytes = new byte[8];
+ for (int i = 0; i < 8; i++) {
+ bytes[i] = (byte) read(input);
+ }
+ return readSwappedLong(bytes, 0);
}
/**
- * Writes a "int" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
+ * Reads a "short" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
+ * @param data source byte array
* @param offset starting offset in the byte array
- * @param value value to write
+ * @return the value read
*/
- public static void writeSwappedInteger(final byte[] data, final int offset, final int value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
- data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
- data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
+ public static short readSwappedShort(final byte[] data, final int offset) {
+ return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
+ ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
}
/**
- * Reads a "int" value from a byte array at a given offset. The value is
+ * Reads a "short" value from an InputStream. The value is
* converted to the opposed endian system while reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static int readSwappedInteger(final byte[] data, final int offset) {
- return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) +
- ( ( data[ offset + 2 ] & 0xff ) << 16 ) +
- ( ( data[ offset + 3 ] & 0xff ) << 24 ) );
+ public static short readSwappedShort(final InputStream input) throws IOException {
+ return (short) (((read(input) & 0xff) << 0) + ((read(input) & 0xff) << 8));
}
/**
@@ -191,56 +203,108 @@ public class EndianUtils {
}
/**
- * Writes a "long" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a unsigned integer (32-bit) from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedLong(final byte[] data, final int offset, final long value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
- data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
- data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
- data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff );
- data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff );
- data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff );
- data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff );
+ 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 high = value4 & 0xff;
+
+ return (high << 24) + (0xffffffffL & low);
}
/**
- * Reads a "long" value from a byte array at a given offset. The value is
- * converted to the opposed endian system while reading.
+ * Reads an unsigned short (16-bit) value from a byte array at a given
+ * offset. The value is converted to the opposed endian system while
+ * reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
- public static long readSwappedLong(final byte[] data, final int offset) {
- final long low = readSwappedInteger(data, offset);
- final long high = readSwappedInteger(data, offset + 4);
- return (high << 32) + (0xffffffffL & low);
+ public static int readSwappedUnsignedShort(final byte[] data, final int offset) {
+ return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
+ ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
}
/**
- * Writes a "float" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a unsigned short (16-bit) from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedFloat(final byte[] data, final int offset, final float value) {
- writeSwappedInteger( data, offset, Float.floatToIntBits( value ) );
+ 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));
}
/**
- * Reads a "float" value from a byte array at a given offset. The value is
- * converted to the opposed endian system while reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * Converts a "double" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
*/
- public static float readSwappedFloat(final byte[] data, final int offset) {
- return Float.intBitsToFloat( readSwappedInteger( data, offset ) );
+ public static double swapDouble(final double value) {
+ return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) );
+ }
+
+ /**
+ * Converts a "float" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
+ */
+ public static float swapFloat(final float value) {
+ return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) );
+ }
+
+ /**
+ * Converts a "int" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
+ */
+ public static int swapInteger(final int value) {
+ return
+ ( ( ( value >> 0 ) & 0xff ) << 24 ) +
+ ( ( ( value >> 8 ) & 0xff ) << 16 ) +
+ ( ( ( value >> 16 ) & 0xff ) << 8 ) +
+ ( ( ( value >> 24 ) & 0xff ) << 0 );
+ }
+
+ /**
+ * Converts a "long" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
+ */
+ public static long swapLong(final long value) {
+ return
+ ( ( ( value >> 0 ) & 0xff ) << 56 ) +
+ ( ( ( value >> 8 ) & 0xff ) << 48 ) +
+ ( ( ( value >> 16 ) & 0xff ) << 40 ) +
+ ( ( ( value >> 24 ) & 0xff ) << 32 ) +
+ ( ( ( value >> 32 ) & 0xff ) << 24 ) +
+ ( ( ( value >> 40 ) & 0xff ) << 16 ) +
+ ( ( ( value >> 48 ) & 0xff ) << 8 ) +
+ ( ( ( value >> 56 ) & 0xff ) << 0 );
+ }
+
+ /**
+ * Converts a "short" value between endian systems.
+ * @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 ) );
}
/**
@@ -255,51 +319,50 @@ public class EndianUtils {
}
/**
- * Reads a "double" value from a byte array at a given offset. The value is
- * converted to the opposed endian system while reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * Writes a "double" value to an OutputStream. The value is
+ * converted to the opposed endian system while writing.
+ * @param output target OutputStream
+ * @param value value to write
+ * @throws IOException in case of an I/O problem
*/
- public static double readSwappedDouble(final byte[] data, final int offset) {
- return Double.longBitsToDouble( readSwappedLong( data, offset ) );
+ public static void writeSwappedDouble(final OutputStream output, final double value) throws IOException {
+ writeSwappedLong(output, Double.doubleToLongBits(value));
}
/**
- * Writes a "short" value to an OutputStream. The value is
+ * Writes a "float" value to a byte array at a given offset. The value is
* converted to the opposed endian system while writing.
- * @param output target OutputStream
+ * @param data target byte array
+ * @param offset starting offset in the byte array
* @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));
- output.write((byte) ((value >> 8) & 0xff));
+ public static void writeSwappedFloat(final byte[] data, final int offset, final float value) {
+ writeSwappedInteger( data, offset, Float.floatToIntBits( value ) );
}
/**
- * Reads a "short" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
+ * Writes a "float" value to an OutputStream. The value is
+ * converted to the opposed endian system while writing.
+ * @param output target OutputStream
+ * @param value value to write
* @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));
+ public static void writeSwappedFloat(final OutputStream output, final float value) throws IOException {
+ writeSwappedInteger(output, Float.floatToIntBits(value));
}
/**
- * Reads a unsigned short (16-bit) from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Writes a "int" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
*/
- 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));
+ public static void writeSwappedInteger(final byte[] data, final int offset, final int value) {
+ data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
+ data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
+ data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
+ data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
}
/**
@@ -317,39 +380,21 @@ public class EndianUtils {
}
/**
- * Reads a "int" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @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);
- }
-
- /**
- * Reads a unsigned integer (32-bit) from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Writes a "long" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
*/
- 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 high = value4 & 0xff;
-
- return (high << 24) + (0xffffffffL & low);
+ public static void writeSwappedLong(final byte[] data, final int offset, final long value) {
+ data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
+ data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
+ data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
+ data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
+ data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff );
+ data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff );
+ data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff );
+ data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff );
}
/**
@@ -371,77 +416,32 @@ public class EndianUtils {
}
/**
- * Reads a "long" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @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];
- for (int i = 0; i < 8; i++) {
- bytes[i] = (byte) read(input);
- }
- return readSwappedLong(bytes, 0);
- }
-
- /**
- * Writes a "float" value to an OutputStream. The value is
+ * Writes a "short" value to a byte array at a given offset. The value is
* converted to the opposed endian system while writing.
- * @param output target OutputStream
+ * @param data target byte array
+ * @param offset starting offset in the byte array
* @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));
- }
-
- /**
- * Reads a "float" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @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));
+ public static void writeSwappedShort(final byte[] data, final int offset, final short value) {
+ data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
+ data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
}
/**
- * Writes a "double" value to an OutputStream. The value is
+ * Writes a "short" value to an OutputStream. The value is
* converted to the opposed endian system while writing.
* @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));
- }
-
- /**
- * Reads a "double" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @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));
+ public static void writeSwappedShort(final OutputStream output, final short value) throws IOException {
+ output.write((byte) ((value >> 0) & 0xff));
+ output.write((byte) ((value >> 8) & 0xff));
}
/**
- * Reads the next byte from the input stream.
- * @param input the stream
- * @return the byte
- * @throws IOException if the end of file is reached
+ * Instances should NOT be constructed in standard programming.
*/
- private static int read(final InputStream input) throws IOException {
- final int value = input.read();
-
- if (EOF == value) {
- throw new EOFException("Unexpected EOF reached");
- }
-
- return value;
+ public EndianUtils() {
}
}
diff --git a/src/main/java/org/apache/commons/io/FileCleaner.java b/src/main/java/org/apache/commons/io/FileCleaner.java
index 43c3cf2..634bffa 100644
--- a/src/main/java/org/apache/commons/io/FileCleaner.java
+++ b/src/main/java/org/apache/commons/io/FileCleaner.java
@@ -42,6 +42,58 @@ public class FileCleaner {
static final FileCleaningTracker theInstance = new FileCleaningTracker();
/**
+ * Call this method to cause the file cleaner thread to terminate when
+ * there are no more objects being tracked for deletion.
+ * <p>
+ * In a simple environment, you don't need this method as the file cleaner
+ * thread will simply exit when the JVM exits. In a more complex environment,
+ * with multiple class loaders (such as an application server), you should be
+ * aware that the file cleaner thread will continue running even if the class
+ * loader it was started from terminates. This can constitute a memory leak.
+ * <p>
+ * 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
+ * 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.
+ * <p>
+ * 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)}.
+ * One called, no new objects can be tracked by the file cleaner.
+ * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}.
+ */
+ @Deprecated
+ public static synchronized void exitWhenFinished() {
+ theInstance.exitWhenFinished();
+ }
+
+ /**
+ * Returns the singleton instance, which is used by the deprecated, static methods.
+ * This is mainly useful for code, which wants to support the new
+ * {@link FileCleaningTracker} class while maintain compatibility with the
+ * deprecated {@link FileCleaner}.
+ *
+ * @return the singleton instance
+ */
+ public static FileCleaningTracker getInstance() {
+ return theInstance;
+ }
+
+ /**
+ * Retrieve the number of files currently being tracked, and therefore
+ * awaiting deletion.
+ *
+ * @return the number of files being tracked
+ * @deprecated Use {@link FileCleaningTracker#getTrackCount()}.
+ */
+ @Deprecated
+ public static int getTrackCount() {
+ return theInstance.getTrackCount();
+ }
+
+ /**
* Track the specified file, using the provided marker, deleting the file
* when the marker instance is garbage collected.
* The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used.
@@ -102,56 +154,4 @@ public class FileCleaner {
public static void track(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) {
theInstance.track(path, marker, deleteStrategy);
}
-
- /**
- * Retrieve the number of files currently being tracked, and therefore
- * awaiting deletion.
- *
- * @return the number of files being tracked
- * @deprecated Use {@link FileCleaningTracker#getTrackCount()}.
- */
- @Deprecated
- public static int getTrackCount() {
- return theInstance.getTrackCount();
- }
-
- /**
- * Call this method to cause the file cleaner thread to terminate when
- * there are no more objects being tracked for deletion.
- * <p>
- * In a simple environment, you don't need this method as the file cleaner
- * thread will simply exit when the JVM exits. In a more complex environment,
- * with multiple class loaders (such as an application server), you should be
- * aware that the file cleaner thread will continue running even if the class
- * loader it was started from terminates. This can constitute a memory leak.
- * <p>
- * 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
- * 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.
- * <p>
- * 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)}.
- * One called, no new objects can be tracked by the file cleaner.
- * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}.
- */
- @Deprecated
- public static synchronized void exitWhenFinished() {
- theInstance.exitWhenFinished();
- }
-
- /**
- * Returns the singleton instance, which is used by the deprecated, static methods.
- * This is mainly useful for code, which wants to support the new
- * {@link FileCleaningTracker} class while maintain compatibility with the
- * deprecated {@link FileCleaner}.
- *
- * @return the singleton instance
- */
- public static FileCleaningTracker getInstance() {
- return theInstance;
- }
}
diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java
index 32bc50b..7016ef3 100644
--- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java
+++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java
@@ -46,6 +46,87 @@ public class FileCleaningTracker {
// Note: fields are package protected to allow use by test cases
/**
+ * The reaper thread.
+ */
+ private final class Reaper extends Thread {
+ /** Constructs a new Reaper */
+ Reaper() {
+ super("File Reaper");
+ setPriority(Thread.MAX_PRIORITY);
+ setDaemon(true);
+ }
+
+ /**
+ * Run the reaper thread that will delete files as their associated
+ * marker objects are reclaimed by the garbage collector.
+ */
+ @Override
+ public void run() {
+ // thread exits when exitWhenFinished is true and there are no more tracked objects
+ while (!exitWhenFinished || !trackers.isEmpty()) {
+ try {
+ // Wait for a tracker to remove.
+ final Tracker tracker = (Tracker) q.remove(); // cannot return null
+ trackers.remove(tracker);
+ if (!tracker.delete()) {
+ deleteFailures.add(tracker.getPath());
+ }
+ tracker.clear();
+ } catch (final InterruptedException e) {
+ continue;
+ }
+ }
+ }
+ }
+ /**
+ * Inner class which acts as the reference for a file pending deletion.
+ */
+ private static final class Tracker extends PhantomReference<Object> {
+
+ /**
+ * The full path to the file being tracked.
+ */
+ private final String path;
+ /**
+ * The strategy for deleting files.
+ */
+ private final FileDeleteStrategy deleteStrategy;
+
+ /**
+ * Constructs an instance of this class from the supplied parameters.
+ *
+ * @param path the full path to the file to be tracked, not null
+ * @param deleteStrategy the strategy to delete the file, null means normal
+ * @param marker the marker object used to track the file, not null
+ * @param queue the queue on to which the tracker will be pushed, not null
+ */
+ Tracker(final String path, final FileDeleteStrategy deleteStrategy, final Object marker,
+ final ReferenceQueue<? super Object> queue) {
+ super(marker, queue);
+ this.path = path;
+ this.deleteStrategy = deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy;
+ }
+
+ /**
+ * Deletes the file associated with this tracker instance.
+ *
+ * @return {@code true} if the file was deleted successfully;
+ * {@code false} otherwise.
+ */
+ public boolean delete() {
+ return deleteStrategy.deleteQuietly(new File(path));
+ }
+
+ /**
+ * Return the path.
+ *
+ * @return the path
+ */
+ public String getPath() {
+ return path;
+ }
+ }
+ /**
* Queue of {@code Tracker} instances being watched.
*/
ReferenceQueue<Object> q = new ReferenceQueue<>();
@@ -57,72 +138,18 @@ public class FileCleaningTracker {
* Collection of File paths that failed to delete.
*/
final List<String> deleteFailures = Collections.synchronizedList(new ArrayList<>());
+
/**
* Whether to terminate the thread when the tracking is complete.
*/
volatile boolean exitWhenFinished;
+
/**
* The thread that will clean up registered files.
*/
Thread reaper;
/**
- * Track the specified file, using the provided marker, deleting the file
- * 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
- */
- public void track(final File file, final Object marker) {
- track(file, marker, null);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * 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
- */
- public void track(final File file, final Object marker, final FileDeleteStrategy deleteStrategy) {
- Objects.requireNonNull(file, "file");
- addTracker(file.getPath(), marker, deleteStrategy);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * 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
- */
- public void track(final String path, final Object marker) {
- track(path, marker, null);
- }
-
- /**
- * Track the specified file, using the provided marker, deleting the file
- * 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
- */
- public void track(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) {
- Objects.requireNonNull(path, "path");
- addTracker(path, marker, deleteStrategy);
- }
-
- /**
* Adds a tracker to the list of trackers.
*
* @param path the full path to the file to be tracked, not null
@@ -143,26 +170,6 @@ public class FileCleaningTracker {
}
/**
- * Retrieve the number of files currently being tracked, and therefore
- * awaiting deletion.
- *
- * @return the number of files being tracked
- */
- public int getTrackCount() {
- return trackers.size();
- }
-
- /**
- * Return the file paths that failed to delete.
- *
- * @return the file paths that failed to delete
- * @since 2.0
- */
- public List<String> getDeleteFailures() {
- return deleteFailures;
- }
-
- /**
* Call this method to cause the file cleaner thread to terminate when
* there are no more objects being tracked for deletion.
* <p>
@@ -195,86 +202,79 @@ public class FileCleaningTracker {
}
/**
- * The reaper thread.
+ * Return the file paths that failed to delete.
+ *
+ * @return the file paths that failed to delete
+ * @since 2.0
*/
- private final class Reaper extends Thread {
- /** Constructs a new Reaper */
- Reaper() {
- super("File Reaper");
- setPriority(Thread.MAX_PRIORITY);
- setDaemon(true);
- }
-
- /**
- * Run the reaper thread that will delete files as their associated
- * marker objects are reclaimed by the garbage collector.
- */
- @Override
- public void run() {
- // thread exits when exitWhenFinished is true and there are no more tracked objects
- while (!exitWhenFinished || !trackers.isEmpty()) {
- try {
- // Wait for a tracker to remove.
- final Tracker tracker = (Tracker) q.remove(); // cannot return null
- trackers.remove(tracker);
- if (!tracker.delete()) {
- deleteFailures.add(tracker.getPath());
- }
- tracker.clear();
- } catch (final InterruptedException e) {
- continue;
- }
- }
- }
+ public List<String> getDeleteFailures() {
+ return deleteFailures;
}
/**
- * Inner class which acts as the reference for a file pending deletion.
+ * Retrieve the number of files currently being tracked, and therefore
+ * awaiting deletion.
+ *
+ * @return the number of files being tracked
*/
- private static final class Tracker extends PhantomReference<Object> {
+ public int getTrackCount() {
+ return trackers.size();
+ }
- /**
- * The full path to the file being tracked.
- */
- private final String path;
- /**
- * The strategy for deleting files.
- */
- private final FileDeleteStrategy deleteStrategy;
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * 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
+ */
+ public void track(final File file, final Object marker) {
+ track(file, marker, null);
+ }
- /**
- * Constructs an instance of this class from the supplied parameters.
- *
- * @param path the full path to the file to be tracked, not null
- * @param deleteStrategy the strategy to delete the file, null means normal
- * @param marker the marker object used to track the file, not null
- * @param queue the queue on to which the tracker will be pushed, not null
- */
- Tracker(final String path, final FileDeleteStrategy deleteStrategy, final Object marker,
- final ReferenceQueue<? super Object> queue) {
- super(marker, queue);
- this.path = path;
- this.deleteStrategy = deleteStrategy == null ? FileDeleteStrategy.NORMAL : deleteStrategy;
- }
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * 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
+ */
+ public void track(final File file, final Object marker, final FileDeleteStrategy deleteStrategy) {
+ Objects.requireNonNull(file, "file");
+ addTracker(file.getPath(), marker, deleteStrategy);
+ }
- /**
- * Return the path.
- *
- * @return the path
- */
- public String getPath() {
- return path;
- }
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * 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
+ */
+ public void track(final String path, final Object marker) {
+ track(path, marker, null);
+ }
- /**
- * Deletes the file associated with this tracker instance.
- *
- * @return {@code true} if the file was deleted successfully;
- * {@code false} otherwise.
- */
- public boolean delete() {
- return deleteStrategy.deleteQuietly(new File(path));
- }
+ /**
+ * Track the specified file, using the provided marker, deleting the file
+ * 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
+ */
+ 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/FileExistsException.java b/src/main/java/org/apache/commons/io/FileExistsException.java
index 56c348b..2264256 100644
--- a/src/main/java/org/apache/commons/io/FileExistsException.java
+++ b/src/main/java/org/apache/commons/io/FileExistsException.java
@@ -38,21 +38,21 @@ public class FileExistsException extends IOException {
}
/**
- * Constructs an instance with the specified message.
+ * Constructs an instance with the specified file.
*
- * @param message The error message
+ * @param file The file that exists
*/
- public FileExistsException(final String message) {
- super(message);
+ public FileExistsException(final File file) {
+ super("File " + file + " exists");
}
/**
- * Constructs an instance with the specified file.
+ * Constructs an instance with the specified message.
*
- * @param file The file that exists
+ * @param message The error message
*/
- public FileExistsException(final File file) {
- super("File " + file + " exists");
+ public FileExistsException(final String message) {
+ super(message);
}
}
diff --git a/src/main/java/org/apache/commons/io/FileSystemUtils.java b/src/main/java/org/apache/commons/io/FileSystemUtils.java
index e35c820..3d612cd 100644
--- a/src/main/java/org/apache/commons/io/FileSystemUtils.java
+++ b/src/main/java/org/apache/commons/io/FileSystemUtils.java
@@ -108,12 +108,6 @@ public class FileSystemUtils {
}
/**
- * Instances should NOT be constructed in standard programming.
- */
- public FileSystemUtils() {
- }
-
- /**
* Returns the free space on a drive or volume by invoking
* the command line.
* This method does not normalize the result, and typically returns
@@ -145,6 +139,45 @@ public class FileSystemUtils {
}
/**
+ * Returns the free space for the working directory
+ * in kibibytes (1024 bytes) by invoking the command line.
+ * <p>
+ * Identical to:
+ * <pre>
+ * freeSpaceKb(FileUtils.current().getAbsolutePath())
+ * </pre>
+ * @return the amount of free drive space on the drive or volume in kilobytes
+ * @throws IllegalStateException if an error occurred in initialisation
+ * @throws IOException if an error occurs when finding the free space
+ * @since 2.0
+ * @deprecated As of 2.6 deprecated without replacement. Please use {@link java.nio.file.FileStore#getUsableSpace()}.
+ */
+ @Deprecated
+ public static long freeSpaceKb() throws IOException {
+ return freeSpaceKb(-1);
+ }
+
+ /**
+ * Returns the free space for the working directory
+ * in kibibytes (1024 bytes) by invoking the command line.
+ * <p>
+ * Identical to:
+ * <pre>
+ * freeSpaceKb(FileUtils.current().getAbsolutePath())
+ * </pre>
+ * @param timeout The timeout amount in milliseconds or no timeout if the value
+ * is zero or less
+ * @return the amount of free drive space on the drive or volume in kilobytes
+ * @throws IllegalStateException if an error occurred in initialisation
+ * @throws IOException if an error occurs when finding the free space
+ * @since 2.0
+ * @deprecated As of 2.6 deprecated without replacement. Please use {@link java.nio.file.FileStore#getUsableSpace()}.
+ */
+ @Deprecated
+ public static long freeSpaceKb(final long timeout) throws IOException {
+ return freeSpaceKb(FileUtils.current().getAbsolutePath(), timeout);
+ }
+ /**
* Returns the free space on a drive or volume in kibibytes (1024 bytes)
* by invoking the command line.
* <pre>
@@ -173,6 +206,7 @@ public class FileSystemUtils {
public static long freeSpaceKb(final String path) throws IOException {
return freeSpaceKb(path, -1);
}
+
/**
* Returns the free space on a drive or volume in kibibytes (1024 bytes)
* by invoking the command line.
@@ -206,43 +240,9 @@ public class FileSystemUtils {
}
/**
- * Returns the free space for the working directory
- * in kibibytes (1024 bytes) by invoking the command line.
- * <p>
- * Identical to:
- * <pre>
- * freeSpaceKb(FileUtils.current().getAbsolutePath())
- * </pre>
- * @return the amount of free drive space on the drive or volume in kilobytes
- * @throws IllegalStateException if an error occurred in initialisation
- * @throws IOException if an error occurs when finding the free space
- * @since 2.0
- * @deprecated As of 2.6 deprecated without replacement. Please use {@link java.nio.file.FileStore#getUsableSpace()}.
- */
- @Deprecated
- public static long freeSpaceKb() throws IOException {
- return freeSpaceKb(-1);
- }
-
- /**
- * Returns the free space for the working directory
- * in kibibytes (1024 bytes) by invoking the command line.
- * <p>
- * Identical to:
- * <pre>
- * freeSpaceKb(FileUtils.current().getAbsolutePath())
- * </pre>
- * @param timeout The timeout amount in milliseconds or no timeout if the value
- * is zero or less
- * @return the amount of free drive space on the drive or volume in kilobytes
- * @throws IllegalStateException if an error occurred in initialisation
- * @throws IOException if an error occurs when finding the free space
- * @since 2.0
- * @deprecated As of 2.6 deprecated without replacement. Please use {@link java.nio.file.FileStore#getUsableSpace()}.
+ * Instances should NOT be constructed in standard programming.
*/
- @Deprecated
- public static long freeSpaceKb(final long timeout) throws IOException {
- return freeSpaceKb(FileUtils.current().getAbsolutePath(), timeout);
+ public FileSystemUtils() {
}
/**
@@ -285,6 +285,64 @@ public class FileSystemUtils {
}
/**
+ * Find free space on the *nix platform using the 'df' command.
+ *
+ * @param path the path to get free space for
+ * @param kb whether to normalize to kilobytes
+ * @param posix whether to use the POSIX standard format flag
+ * @param timeout The timeout amount in milliseconds or no timeout if the value
+ * is zero or less
+ * @return the amount of free drive space on the volume
+ * @throws IOException if an error occurs
+ */
+ long freeSpaceUnix(final String path, final boolean kb, final boolean posix, final Duration timeout)
+ throws IOException {
+ if (path.isEmpty()) {
+ throw new IllegalArgumentException("Path must not be empty");
+ }
+
+ // build and run the 'dir' command
+ String flags = "-";
+ if (kb) {
+ flags += "k";
+ }
+ if (posix) {
+ flags += "P";
+ }
+ final String[] cmdAttribs =
+ flags.length() > 1 ? new String[] {DF, flags, path} : new String[] {DF, path};
+
+ // perform the command, asking for up to 3 lines (header, interesting, overflow)
+ final List<String> lines = performCommand(cmdAttribs, 3, timeout);
+ if (lines.size() < 2) {
+ // unknown problem, throw exception
+ throw new IOException(
+ "Command line '" + DF + "' did not return info as expected " +
+ "for path '" + path + "'- response was " + lines);
+ }
+ final String line2 = lines.get(1); // the line we're interested in
+
+ // Now, we tokenize the string. The fourth element is what we want.
+ StringTokenizer tok = new StringTokenizer(line2, " ");
+ if (tok.countTokens() < 4) {
+ // could be long Filesystem, thus data on third line
+ if ((tok.countTokens() != 1) || (lines.size() < 3)) {
+ throw new IOException(
+ "Command line '" + DF + "' did not return data as expected " +
+ "for path '" + path + "'- check path is valid");
+ }
+ final String line3 = lines.get(2); // the line may be interested in
+ tok = new StringTokenizer(line3, " ");
+ } else {
+ tok.nextToken(); // Ignore Filesystem
+ }
+ tok.nextToken(); // Ignore 1K-blocks
+ tok.nextToken(); // Ignore Used
+ final String freeSpace = tok.nextToken();
+ return parseBytes(freeSpace, path);
+ }
+
+ /**
* Find free space on the Windows platform using the 'dir' command.
*
* @param path the path to get free space for, including the colon
@@ -325,6 +383,42 @@ public class FileSystemUtils {
}
/**
+ * Opens the process to the operating system.
+ *
+ * @param cmdAttribs the command line parameters
+ * @return the process
+ * @throws IOException if an error occurs
+ */
+ Process openProcess(final String[] cmdAttribs) throws IOException {
+ return Runtime.getRuntime().exec(cmdAttribs);
+ }
+
+ /**
+ * Parses the bytes from a string.
+ *
+ * @param freeSpace the free space string
+ * @param path the path
+ * @return the number of bytes
+ * @throws IOException if an error occurs
+ */
+ long parseBytes(final String freeSpace, final String path) throws IOException {
+ try {
+ final long bytes = Long.parseLong(freeSpace);
+ if (bytes < 0) {
+ throw new IOException(
+ "Command line '" + DF + "' did not find free space in response " +
+ "for path '" + path + "'- check path is valid");
+ }
+ return bytes;
+
+ } catch (final NumberFormatException ex) {
+ throw new IOException(
+ "Command line '" + DF + "' did not return numeric data as expected " +
+ "for path '" + path + "'- check path is valid", ex);
+ }
+ }
+
+ /**
* Parses the Windows dir response last line
*
* @param line the line to parse
@@ -377,89 +471,6 @@ public class FileSystemUtils {
}
/**
- * Find free space on the *nix platform using the 'df' command.
- *
- * @param path the path to get free space for
- * @param kb whether to normalize to kilobytes
- * @param posix whether to use the POSIX standard format flag
- * @param timeout The timeout amount in milliseconds or no timeout if the value
- * is zero or less
- * @return the amount of free drive space on the volume
- * @throws IOException if an error occurs
- */
- long freeSpaceUnix(final String path, final boolean kb, final boolean posix, final Duration timeout)
- throws IOException {
- if (path.isEmpty()) {
- throw new IllegalArgumentException("Path must not be empty");
- }
-
- // build and run the 'dir' command
- String flags = "-";
- if (kb) {
- flags += "k";
- }
- if (posix) {
- flags += "P";
- }
- final String[] cmdAttribs =
- flags.length() > 1 ? new String[] {DF, flags, path} : new String[] {DF, path};
-
- // perform the command, asking for up to 3 lines (header, interesting, overflow)
- final List<String> lines = performCommand(cmdAttribs, 3, timeout);
- if (lines.size() < 2) {
- // unknown problem, throw exception
- throw new IOException(
- "Command line '" + DF + "' did not return info as expected " +
- "for path '" + path + "'- response was " + lines);
- }
- final String line2 = lines.get(1); // the line we're interested in
-
- // Now, we tokenize the string. The fourth element is what we want.
- StringTokenizer tok = new StringTokenizer(line2, " ");
- if (tok.countTokens() < 4) {
- // could be long Filesystem, thus data on third line
- if ((tok.countTokens() != 1) || (lines.size() < 3)) {
- throw new IOException(
- "Command line '" + DF + "' did not return data as expected " +
- "for path '" + path + "'- check path is valid");
- }
- final String line3 = lines.get(2); // the line may be interested in
- tok = new StringTokenizer(line3, " ");
- } else {
- tok.nextToken(); // Ignore Filesystem
- }
- tok.nextToken(); // Ignore 1K-blocks
- tok.nextToken(); // Ignore Used
- final String freeSpace = tok.nextToken();
- return parseBytes(freeSpace, path);
- }
-
- /**
- * Parses the bytes from a string.
- *
- * @param freeSpace the free space string
- * @param path the path
- * @return the number of bytes
- * @throws IOException if an error occurs
- */
- long parseBytes(final String freeSpace, final String path) throws IOException {
- try {
- final long bytes = Long.parseLong(freeSpace);
- if (bytes < 0) {
- throw new IOException(
- "Command line '" + DF + "' did not find free space in response " +
- "for path '" + path + "'- check path is valid");
- }
- return bytes;
-
- } catch (final NumberFormatException ex) {
- throw new IOException(
- "Command line '" + DF + "' did not return numeric data as expected " +
- "for path '" + path + "'- check path is valid", ex);
- }
- }
-
- /**
* Performs an OS command.
*
* @param cmdAttribs the command line parameters
@@ -551,15 +562,4 @@ public class FileSystemUtils {
}
}
- /**
- * Opens the process to the operating system.
- *
- * @param cmdAttribs the command line parameters
- * @return the process
- * @throws IOException if an error occurs
- */
- Process openProcess(final String[] cmdAttribs) throws IOException {
- return Runtime.getRuntime().exec(cmdAttribs);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/FilenameUtils.java b/src/main/java/org/apache/commons/io/FilenameUtils.java
index 3b8888b..ad58b33 100644
--- a/src/main/java/org/apache/commons/io/FilenameUtils.java
+++ b/src/main/java/org/apache/commons/io/FilenameUtils.java
@@ -511,6 +511,22 @@ public class FilenameUtils {
}
/**
+ * Flips the Windows name separator to Linux and vice-versa.
+ *
+ * @param ch The Windows or Linux name separator.
+ * @return The Windows or Linux name separator.
+ */
+ static char flipSeparator(final char ch) {
+ if (ch == UNIX_NAME_SEPARATOR) {
+ return WINDOWS_NAME_SEPARATOR;
+ }
+ if (ch == WINDOWS_NAME_SEPARATOR) {
+ return UNIX_NAME_SEPARATOR;
+ }
+ throw new IllegalArgumentException(String.valueOf(ch));
+ }
+
+ /**
* Special handling for NTFS ADS: Don't accept colon in the fileName.
*
* @param fileName a file name
@@ -1175,22 +1191,6 @@ public class FilenameUtils {
}
/**
- * Flips the Windows name separator to Linux and vice-versa.
- *
- * @param ch The Windows or Linux name separator.
- * @return The Windows or Linux name separator.
- */
- static char flipSeparator(final char ch) {
- if (ch == UNIX_NAME_SEPARATOR) {
- return WINDOWS_NAME_SEPARATOR;
- }
- if (ch == WINDOWS_NAME_SEPARATOR) {
- return UNIX_NAME_SEPARATOR;
- }
- throw new IllegalArgumentException(String.valueOf(ch));
- }
-
- /**
* Determines if Windows file system is in use.
*
* @return true if the system is Windows
diff --git a/src/main/java/org/apache/commons/io/HexDump.java b/src/main/java/org/apache/commons/io/HexDump.java
index 86b49b6..bd6a812 100644
--- a/src/main/java/org/apache/commons/io/HexDump.java
+++ b/src/main/java/org/apache/commons/io/HexDump.java
@@ -32,11 +32,21 @@ import java.nio.charset.Charset;
public class HexDump {
/**
- * Instances should NOT be constructed in standard programming.
+ * The line-separator (initializes to "line.separator" system property.
*/
- public HexDump() {
- }
+ public static final String EOL =
+ System.getProperty("line.separator");
+ private static final char[] _hexcodes =
+ {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ private static final int[] _shifts =
+ {
+ 28, 24, 20, 16, 12, 8, 4, 0
+ };
/**
* Dump an array of bytes to an OutputStream. The output is formatted
* for human inspection, with a hexadecimal offset followed by the
@@ -113,21 +123,19 @@ public class HexDump {
display_offset += chars_read;
}
}
-
/**
- * The line-separator (initializes to "line.separator" system property.
+ * Dump a byte value into a StringBuilder.
+ *
+ * @param _cbuffer the StringBuilder to dump the value in
+ * @param value the byte value to be dumped
+ * @return StringBuilder containing the dumped value.
*/
- public static final String EOL =
- System.getProperty("line.separator");
- private static final char[] _hexcodes =
- {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'
- };
- private static final int[] _shifts =
- {
- 28, 24, 20, 16, 12, 8, 4, 0
- };
+ private static StringBuilder dump(final StringBuilder _cbuffer, final byte value) {
+ for (int j = 0; j < 2; j++) {
+ _cbuffer.append(_hexcodes[value >> _shifts[j + 6] & 15]);
+ }
+ return _cbuffer;
+ }
/**
* Dump a long value into a StringBuilder.
@@ -145,17 +153,9 @@ public class HexDump {
}
/**
- * Dump a byte value into a StringBuilder.
- *
- * @param _cbuffer the StringBuilder to dump the value in
- * @param value the byte value to be dumped
- * @return StringBuilder containing the dumped value.
+ * Instances should NOT be constructed in standard programming.
*/
- private static StringBuilder dump(final StringBuilder _cbuffer, final byte value) {
- for (int j = 0; j < 2; j++) {
- _cbuffer.append(_hexcodes[value >> _shifts[j + 6] & 15]);
- }
- return _cbuffer;
+ public HexDump() {
}
}
diff --git a/src/main/java/org/apache/commons/io/IOCase.java b/src/main/java/org/apache/commons/io/IOCase.java
index 6226ea5..201d5f3 100644
--- a/src/main/java/org/apache/commons/io/IOCase.java
+++ b/src/main/java/org/apache/commons/io/IOCase.java
@@ -64,6 +64,25 @@ public enum IOCase {
*/
SYSTEM("System", !FilenameUtils.isSystemWindows());
+ /** Serialization version. */
+ private static final long serialVersionUID = -6343169151696340687L;
+
+ /**
+ * Factory method to create an IOCase from a name.
+ *
+ * @param name the name to find
+ * @return the IOCase object
+ * @throws IllegalArgumentException if the name is invalid
+ */
+ public static IOCase forName(final String name) {
+ for (final IOCase ioCase : IOCase.values()) {
+ if (ioCase.getName().equals(name)) {
+ return ioCase;
+ }
+ }
+ throw new IllegalArgumentException("Invalid IOCase name: " + name);
+ }
+
/**
* Tests for cases sensitivity in a null-safe manner.
*
@@ -87,9 +106,6 @@ public enum IOCase {
return value != null ? value : defaultValue;
}
- /** Serialization version. */
- private static final long serialVersionUID = -6343169151696340687L;
-
/** The enumeration name. */
private final String name;
@@ -97,22 +113,6 @@ public enum IOCase {
private final transient boolean sensitive;
/**
- * Factory method to create an IOCase from a name.
- *
- * @param name the name to find
- * @return the IOCase object
- * @throws IllegalArgumentException if the name is invalid
- */
- public static IOCase forName(final String name) {
- for (final IOCase ioCase : IOCase.values()) {
- if (ioCase.getName().equals(name)) {
- return ioCase;
- }
- }
- throw new IllegalArgumentException("Invalid IOCase name: " + name);
- }
-
- /**
* Constructs a new instance.
*
* @param name the name
@@ -124,34 +124,6 @@ public enum IOCase {
}
/**
- * Replaces the enumeration from the stream with a real one.
- * This ensures that the correct flag is set for SYSTEM.
- *
- * @return the resolved object
- */
- private Object readResolve() {
- return forName(name);
- }
-
- /**
- * Gets the name of the constant.
- *
- * @return the name of the constant
- */
- public String getName() {
- return name;
- }
-
- /**
- * Does the object represent case sensitive comparison.
- *
- * @return true if case sensitive
- */
- public boolean isCaseSensitive() {
- return sensitive;
- }
-
- /**
* Compares two strings using the case-sensitivity rule.
* <p>
* This method mimics {@link String#compareTo} but takes case-sensitivity
@@ -170,39 +142,6 @@ public enum IOCase {
}
/**
- * Compares two strings using the case-sensitivity rule.
- * <p>
- * This method mimics {@link String#equals} but takes case-sensitivity
- * into account.
- * </p>
- *
- * @param str1 the first string to compare, not null
- * @param str2 the second string to compare, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkEquals(final String str1, final String str2) {
- Objects.requireNonNull(str1, "str1");
- Objects.requireNonNull(str2, "str2");
- return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
- }
-
- /**
- * Checks if one string starts with another using the case-sensitivity rule.
- * <p>
- * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
- * into account.
- * </p>
- *
- * @param str the string to check
- * @param start the start to compare against
- * @return true if equal using the case rules, false if either input is null
- */
- public boolean checkStartsWith(final String str, final String start) {
- return str != null && start != null && str.regionMatches(!sensitive, 0, start, 0, start.length());
- }
-
- /**
* Checks if one string ends with another using the case-sensitivity rule.
* <p>
* This method mimics {@link String#endsWith} but takes case-sensitivity
@@ -222,6 +161,24 @@ public enum IOCase {
}
/**
+ * Compares two strings using the case-sensitivity rule.
+ * <p>
+ * This method mimics {@link String#equals} but takes case-sensitivity
+ * into account.
+ * </p>
+ *
+ * @param str1 the first string to compare, not null
+ * @param str2 the second string to compare, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkEquals(final String str1, final String str2) {
+ Objects.requireNonNull(str1, "str1");
+ Objects.requireNonNull(str2, "str2");
+ return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
+ }
+
+ /**
* Checks if one string contains another starting at a specific index using the
* case-sensitivity rule.
* <p>
@@ -267,6 +224,49 @@ public enum IOCase {
}
/**
+ * Checks if one string starts with another using the case-sensitivity rule.
+ * <p>
+ * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
+ * into account.
+ * </p>
+ *
+ * @param str the string to check
+ * @param start the start to compare against
+ * @return true if equal using the case rules, false if either input is null
+ */
+ public boolean checkStartsWith(final String str, final String start) {
+ return str != null && start != null && str.regionMatches(!sensitive, 0, start, 0, start.length());
+ }
+
+ /**
+ * Gets the name of the constant.
+ *
+ * @return the name of the constant
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Does the object represent case sensitive comparison.
+ *
+ * @return true if case sensitive
+ */
+ public boolean isCaseSensitive() {
+ return sensitive;
+ }
+
+ /**
+ * Replaces the enumeration from the stream with a real one.
+ * This ensures that the correct flag is set for SYSTEM.
+ *
+ * @return the resolved object
+ */
+ private Object readResolve() {
+ return forName(name);
+ }
+
+ /**
* Gets a string describing the sensitivity.
*
* @return a string describing the sensitivity
diff --git a/src/main/java/org/apache/commons/io/IOIndexedException.java b/src/main/java/org/apache/commons/io/IOIndexedException.java
index ce45521..71253d4 100644
--- a/src/main/java/org/apache/commons/io/IOIndexedException.java
+++ b/src/main/java/org/apache/commons/io/IOIndexedException.java
@@ -27,19 +27,6 @@ import java.io.IOException;
public class IOIndexedException extends IOException {
private static final long serialVersionUID = 1L;
- private final int index;
-
- /**
- * Creates a new exception.
- *
- * @param index index of this exception.
- * @param cause cause exceptions.
- */
- public IOIndexedException(final int index, final Throwable cause) {
- super(toMessage(index, cause), cause);
- this.index = index;
- }
-
/**
* Converts input to a suitable String for exception message.
*
@@ -55,6 +42,19 @@ public class IOIndexedException extends IOException {
return String.format("%s #%,d: %s", name, index, msg);
}
+ private final int index;
+
+ /**
+ * Creates a new exception.
+ *
+ * @param index index of this exception.
+ * @param cause cause exceptions.
+ */
+ public IOIndexedException(final int index, final Throwable cause) {
+ super(toMessage(index, cause), cause);
+ this.index = index;
+ }
+
/**
* The index of this exception.
*
diff --git a/src/main/java/org/apache/commons/io/LineIterator.java b/src/main/java/org/apache/commons/io/LineIterator.java
index e49592f..aff8b1f 100644
--- a/src/main/java/org/apache/commons/io/LineIterator.java
+++ b/src/main/java/org/apache/commons/io/LineIterator.java
@@ -51,10 +51,23 @@ public class LineIterator implements Iterator<String>, Closeable {
// N.B. This class deliberately does not implement Iterable, see https://issues.apache.org/jira/browse/IO-181
+ /**
+ * Closes a {@code LineIterator} quietly.
+ *
+ * @param iterator The iterator to close, or {@code null}.
+ * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle
+ * suppressed exceptions manually.
+ * @see Throwable#addSuppressed(java.lang.Throwable)
+ */
+ @Deprecated
+ public static void closeQuietly(final LineIterator iterator) {
+ IOUtils.closeQuietly(iterator);
+ }
/** The reader that is being read. */
private final BufferedReader bufferedReader;
/** The current line. */
private String cachedLine;
+
/** A flag indicating if the iterator has been fully read. */
private boolean finished;
@@ -76,6 +89,22 @@ public class LineIterator implements Iterator<String>, Closeable {
}
/**
+ * Closes the underlying {@code Reader}.
+ * This method is useful if you only want to process the first few
+ * lines of a larger file. If you do not close the iterator
+ * then the {@code Reader} remains open.
+ * This method can safely be called multiple times.
+ *
+ * @throws IOException if closing the underlying {@code Reader} fails.
+ */
+ @Override
+ public void close() throws IOException {
+ finished = true;
+ cachedLine = null;
+ IOUtils.close(bufferedReader);
+ }
+
+ /**
* Indicates whether the {@code Reader} has more lines.
* If there is an {@code IOException} then {@link #close()} will
* be called on this instance.
@@ -146,22 +175,6 @@ public class LineIterator implements Iterator<String>, Closeable {
}
/**
- * Closes the underlying {@code Reader}.
- * This method is useful if you only want to process the first few
- * lines of a larger file. If you do not close the iterator
- * then the {@code Reader} remains open.
- * This method can safely be called multiple times.
- *
- * @throws IOException if closing the underlying {@code Reader} fails.
- */
- @Override
- public void close() throws IOException {
- finished = true;
- cachedLine = null;
- IOUtils.close(bufferedReader);
- }
-
- /**
* Unsupported.
*
* @throws UnsupportedOperationException always
@@ -171,17 +184,4 @@ public class LineIterator implements Iterator<String>, Closeable {
throw new UnsupportedOperationException("remove not supported");
}
- /**
- * Closes a {@code LineIterator} quietly.
- *
- * @param iterator The iterator to close, or {@code null}.
- * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle
- * suppressed exceptions manually.
- * @see Throwable#addSuppressed(java.lang.Throwable)
- */
- @Deprecated
- public static void closeQuietly(final LineIterator iterator) {
- IOUtils.closeQuietly(iterator);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/StreamIterator.java b/src/main/java/org/apache/commons/io/StreamIterator.java
index b5cc1c4..1d8a3ec 100644
--- a/src/main/java/org/apache/commons/io/StreamIterator.java
+++ b/src/main/java/org/apache/commons/io/StreamIterator.java
@@ -49,13 +49,22 @@ class StreamIterator<E> implements Iterator<E>, Closeable {
return new StreamIterator<>(stream).iterator;
}
+ private final Iterator<E> iterator;
+
+ private final Stream<E> stream;
private StreamIterator(final Stream<E> stream) {
this.stream = Objects.requireNonNull(stream, "stream");
this.iterator = stream.iterator();
}
- private final Iterator<E> iterator;
- private final Stream<E> stream;
+ /**
+ * Closes the underlying stream.
+ */
+ @Override
+ public void close() {
+ stream.close();
+
+ }
@Override
public boolean hasNext() {
@@ -75,13 +84,4 @@ class StreamIterator<E> implements Iterator<E>, Closeable {
return next;
}
- /**
- * Closes the underlying stream.
- */
- @Override
- public void close() {
- stream.close();
-
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/TaggedIOException.java b/src/main/java/org/apache/commons/io/TaggedIOException.java
index 4234e9e..43d7730 100644
--- a/src/main/java/org/apache/commons/io/TaggedIOException.java
+++ b/src/main/java/org/apache/commons/io/TaggedIOException.java
@@ -114,15 +114,6 @@ public class TaggedIOException extends IOExceptionWithCause {
}
/**
- * Returns the serializable tag object.
- *
- * @return tag object
- */
- public Serializable getTag() {
- return tag;
- }
-
- /**
* Returns the wrapped exception. The only difference to the overridden
* {@link Throwable#getCause()} method is the narrower return type.
*
@@ -133,4 +124,13 @@ public class TaggedIOException extends IOExceptionWithCause {
return (IOException) super.getCause();
}
+ /**
+ * Returns the serializable 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 bd1fd16..0db54d0 100644
--- a/src/main/java/org/apache/commons/io/ThreadMonitor.java
+++ b/src/main/java/org/apache/commons/io/ThreadMonitor.java
@@ -41,8 +41,26 @@ import java.time.Instant;
*/
class ThreadMonitor implements Runnable {
- private final Thread thread;
- private final Duration timeout;
+ private static int getNanosOfMiili(final Duration duration) {
+ return duration.getNano() % 1_000_000;
+ }
+ /**
+ * Sleeps for a guaranteed minimum duration unless interrupted.
+ *
+ * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else it deems appropriate.
+ * Read {@link Thread#sleep(long, int)}} for further interesting details.
+ *
+ * @param duration the sleep duration.
+ * @throws InterruptedException if interrupted.
+ */
+ static void sleep(final Duration duration) throws InterruptedException {
+ final Instant finishInstant = Instant.now().plus(duration);
+ Duration remainingDuration = duration;
+ do {
+ Thread.sleep(remainingDuration.toMillis(), getNanosOfMiili(remainingDuration));
+ remainingDuration = Duration.between(Instant.now(), finishInstant);
+ } while (!remainingDuration.isNegative());
+ }
/**
* Starts monitoring the current thread.
@@ -82,6 +100,10 @@ class ThreadMonitor implements Runnable {
}
}
+ private final Thread thread;
+
+ private final Duration timeout;
+
/**
* Constructs a new monitor.
*
@@ -107,26 +129,4 @@ class ThreadMonitor implements Runnable {
// timeout not reached
}
}
-
- /**
- * Sleeps for a guaranteed minimum duration unless interrupted.
- *
- * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else it deems appropriate.
- * Read {@link Thread#sleep(long, int)}} for further interesting details.
- *
- * @param duration the sleep duration.
- * @throws InterruptedException if interrupted.
- */
- static void sleep(final Duration duration) throws InterruptedException {
- final Instant finishInstant = Instant.now().plus(duration);
- Duration remainingDuration = duration;
- do {
- Thread.sleep(remainingDuration.toMillis(), getNanosOfMiili(remainingDuration));
- remainingDuration = Duration.between(Instant.now(), finishInstant);
- } while (!remainingDuration.isNegative());
- }
-
- private static int getNanosOfMiili(final Duration duration) {
- return duration.getNano() % 1_000_000;
- }
}
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 17f7682..daf08cf 100644
--- a/src/main/java/org/apache/commons/io/file/Counters.java
+++ b/src/main/java/org/apache/commons/io/file/Counters.java
@@ -155,13 +155,13 @@ public class Counters {
}
@Override
- public String toString() {
- return value.toString();
+ public void reset() {
+ value = BigInteger.ZERO;
}
@Override
- public void reset() {
- value = BigInteger.ZERO;
+ public String toString() {
+ return value.toString();
}
}
@@ -277,13 +277,13 @@ public class Counters {
}
@Override
- public String toString() {
- return Long.toString(value);
+ public void reset() {
+ value = 0L;
}
@Override
- public void reset() {
- value = 0L;
+ public String toString() {
+ return Long.toString(value);
}
}
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 7a573ee..9d65243 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -79,10 +79,6 @@ import org.apache.commons.io.filefilter.IOFileFilter;
*/
public final class PathUtils {
- private static final OpenOption[] OPEN_OPTIONS_TRUNCATE = new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
-
- private static final OpenOption[] OPEN_OPTIONS_APPEND = new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.APPEND};
-
/**
* Private worker/holder that computes and tracks relative path names and their equality. We reuse the sorted relative
* lists when comparing directories.
@@ -145,6 +141,10 @@ public final class PathUtils {
}
}
+ private static final OpenOption[] OPEN_OPTIONS_TRUNCATE = new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
+
+ private static final OpenOption[] OPEN_OPTIONS_APPEND = new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.APPEND};
+
/**
* Empty {@link CopyOption} array.
*
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 fa3b282..8a8d030 100644
--- a/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/AndFileFilter.java
@@ -73,6 +73,17 @@ public class AndFileFilter
}
/**
+ * Constructs a new instance for the give filters.
+ * @param fileFilters filters to OR.
+ *
+ * @since 2.9.0
+ */
+ public AndFileFilter(final IOFileFilter... fileFilters) {
+ this(Objects.requireNonNull(fileFilters, "fileFilters").length);
+ addFileFilter(fileFilters);
+ }
+
+ /**
* Constructs a new file filter that ANDs the result of other filters.
*
* @param filter1 the first filter, must second be null
@@ -86,17 +97,6 @@ public class AndFileFilter
}
/**
- * Constructs a new instance for the give filters.
- * @param fileFilters filters to OR.
- *
- * @since 2.9.0
- */
- public AndFileFilter(final IOFileFilter... fileFilters) {
- this(Objects.requireNonNull(fileFilters, "fileFilters").length);
- addFileFilter(fileFilters);
- }
-
- /**
* Constructs a new instance of {@code AndFileFilter}
* with the specified list of filters.
*
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 51545a1..8119f53 100644
--- a/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/FalseFileFilter.java
@@ -90,24 +90,24 @@ public class FalseFileFilter implements IOFileFilter, Serializable {
}
@Override
- public IOFileFilter negate() {
- return TrueFileFilter.INSTANCE;
- }
-
- @Override
- public String toString() {
- return TO_STRING;
- }
-
- @Override
public IOFileFilter and(final IOFileFilter fileFilter) {
// FALSE AND expression <=> FALSE
return INSTANCE;
}
@Override
+ public IOFileFilter negate() {
+ return TrueFileFilter.INSTANCE;
+ }
+
+ @Override
public IOFileFilter or(final IOFileFilter fileFilter) {
// FALSE OR expression <=> expression
return fileFilter;
}
+
+ @Override
+ public String toString() {
+ return TO_STRING;
+ }
}
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 89ed47d..5f72405 100644
--- a/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java
+++ b/src/main/java/org/apache/commons/io/filefilter/FileFilterUtils.java
@@ -251,33 +251,6 @@ public class FileFilterUtils {
/**
* <p>
- * Applies an {@link IOFileFilter} to the provided {@link File} stream and collects the accepted files.
- * </p>
- *
- * @param filter the filter to apply to the stream of files.
- * @param stream the stream of files on which to apply the filter.
- * @param collector how to collect the end result.
- *
- * @param <R> the return type.
- * @param <A> the mutable accumulation type of the reduction operation (often hidden as an implementation detail)
- * @return a subset of files from the stream that is accepted by the filter.
- * @throws IllegalArgumentException if the filter is {@code null}.
- */
- private static <R, A> R filterFiles(final IOFileFilter filter, final Stream<File> stream,
- final Collector<? super File, A, R> collector) {
- //Objects.requireNonNull(filter, "filter");
- Objects.requireNonNull(collector, "collector");
- if (filter == null) {
- throw new IllegalArgumentException("file filter is null");
- }
- if (stream == null) {
- return Stream.<File>empty().collect(collector);
- }
- return stream.filter(filter::accept).collect(collector);
- }
-
- /**
- * <p>
* Applies an {@link IOFileFilter} to the provided {@link File}
* objects. The resulting array is a subset of the original file list that
* matches the provided filter.
@@ -308,6 +281,33 @@ public class FileFilterUtils {
/**
* <p>
+ * Applies an {@link IOFileFilter} to the provided {@link File} stream and collects the accepted files.
+ * </p>
+ *
+ * @param filter the filter to apply to the stream of files.
+ * @param stream the stream of files on which to apply the filter.
+ * @param collector how to collect the end result.
+ *
+ * @param <R> the return type.
+ * @param <A> the mutable accumulation type of the reduction operation (often hidden as an implementation detail)
+ * @return a subset of files from the stream that is accepted by the filter.
+ * @throws IllegalArgumentException if the filter is {@code null}.
+ */
+ private static <R, A> R filterFiles(final IOFileFilter filter, final Stream<File> stream,
+ final Collector<? super File, A, R> collector) {
+ //Objects.requireNonNull(filter, "filter");
+ Objects.requireNonNull(collector, "collector");
+ if (filter == null) {
+ throw new IllegalArgumentException("file filter is null");
+ }
+ if (stream == null) {
+ return Stream.<File>empty().collect(collector);
+ }
+ return stream.filter(filter::accept).collect(collector);
+ }
+
+ /**
+ * <p>
* Applies an {@link IOFileFilter} to the provided {@link File}
* objects. The resulting list is a subset of the original files that
* matches the provided filter.
diff --git a/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java
index a3fa9fd..aa4001b 100644
--- a/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/TrueFileFilter.java
@@ -89,6 +89,12 @@ public class TrueFileFilter implements IOFileFilter, Serializable {
}
@Override
+ public IOFileFilter and(final IOFileFilter fileFilter) {
+ // TRUE AND expression <=> expression
+ return fileFilter;
+ }
+
+ @Override
public IOFileFilter negate() {
return FalseFileFilter.INSTANCE;
}
@@ -100,12 +106,6 @@ public class TrueFileFilter implements IOFileFilter, Serializable {
}
@Override
- public IOFileFilter and(final IOFileFilter fileFilter) {
- // TRUE AND expression <=> expression
- return fileFilter;
- }
-
- @Override
public String toString() {
return TO_STRING;
}
diff --git a/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java b/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java
index 399a6c4..38bb6c6 100644
--- a/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/WildcardFilter.java
@@ -141,46 +141,46 @@ public class WildcardFilter extends AbstractFileFilter implements Serializable {
/**
* Checks to see if the file name matches one of the wildcards.
- * @param file the file to check
*
+ * @param dir the file directory
+ * @param name the file name
* @return true if the file name matches one of the wildcards
- * @since 2.9.0
*/
@Override
- public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- if (Files.isDirectory(file)) {
- return FileVisitResult.TERMINATE;
+ public boolean accept(final File dir, final String name) {
+ if (dir != null && new File(dir, name).isDirectory()) {
+ return false;
}
for (final String wildcard : wildcards) {
- if (FilenameUtils.wildcardMatch(Objects.toString(file.getFileName(), null), wildcard)) {
- return FileVisitResult.CONTINUE;
+ if (FilenameUtils.wildcardMatch(name, wildcard)) {
+ return true;
}
}
- return FileVisitResult.TERMINATE;
+ return false;
}
/**
* Checks to see if the file name matches one of the wildcards.
+ * @param file the file to check
*
- * @param dir the file directory
- * @param name the file name
* @return true if the file name matches one of the wildcards
+ * @since 2.9.0
*/
@Override
- public boolean accept(final File dir, final String name) {
- if (dir != null && new File(dir, name).isDirectory()) {
- return false;
+ public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
+ if (Files.isDirectory(file)) {
+ return FileVisitResult.TERMINATE;
}
for (final String wildcard : wildcards) {
- if (FilenameUtils.wildcardMatch(name, wildcard)) {
- return true;
+ if (FilenameUtils.wildcardMatch(Objects.toString(file.getFileName(), null), wildcard)) {
+ return FileVisitResult.CONTINUE;
}
}
- return false;
+ return FileVisitResult.TERMINATE;
}
}
diff --git a/src/main/java/org/apache/commons/io/function/IOFunction.java b/src/main/java/org/apache/commons/io/function/IOFunction.java
index 4129f57..ab2a337 100644
--- a/src/main/java/org/apache/commons/io/function/IOFunction.java
+++ b/src/main/java/org/apache/commons/io/function/IOFunction.java
@@ -34,6 +34,92 @@ import java.util.function.Supplier;
public interface IOFunction<T, R> {
/**
+ * Returns a {@link IOFunction} that always returns its input argument.
+ *
+ * @param <T> the type of the input and output objects to the function
+ * @return a function that always returns its input argument
+ */
+ static <T> IOFunction<T, T> identity() {
+ return t -> t;
+ }
+
+ /**
+ * Returns a composed {@link IOFunction} that first applies this function to
+ * its input, and then applies the {@code after} consumer to the result.
+ * If evaluation of either function throws an exception, it is relayed to
+ * the caller of the composed function.
+ *
+ * @param after the consumer to apply after this function is applied
+ * @return a composed function that first applies this function and then
+ * applies the {@code after} consumer
+ * @throws NullPointerException if after is null
+ *
+ * @see #compose(IOFunction)
+ */
+ default IOConsumer<T> andThen(final Consumer<? super R> after) {
+ Objects.requireNonNull(after, "after");
+ return (final T t) -> after.accept(apply(t));
+ }
+
+ /**
+ * Returns a composed {@link IOFunction} that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ * If evaluation of either function throws an exception, it is relayed to
+ * the caller of the composed function.
+ *
+ * @param <V> the type of output of the {@code after} function, and of the
+ * composed function
+ * @param after the function to apply after this function is applied
+ * @return a composed function that first applies this function and then
+ * applies the {@code after} function
+ * @throws NullPointerException if after is null
+ *
+ * @see #compose(IOFunction)
+ */
+ default <V> IOFunction<T, V> andThen(final Function<? super R, ? extends V> after) {
+ Objects.requireNonNull(after, "after");
+ return (final T t) -> after.apply(apply(t));
+ }
+
+ /**
+ * Returns a composed {@link IOFunction} that first applies this function to
+ * its input, and then applies the {@code after} consumer to the result.
+ * If evaluation of either function throws an exception, it is relayed to
+ * the caller of the composed function.
+ *
+ * @param after the consumer to apply after this function is applied
+ * @return a composed function that first applies this function and then
+ * applies the {@code after} consumer
+ * @throws NullPointerException if after is null
+ *
+ * @see #compose(IOFunction)
+ */
+ default IOConsumer<T> andThen(final IOConsumer<? super R> after) {
+ Objects.requireNonNull(after, "after");
+ return (final T t) -> after.accept(apply(t));
+ }
+
+ /**
+ * Returns a composed {@link IOFunction} that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ * If evaluation of either function throws an exception, it is relayed to
+ * the caller of the composed function.
+ *
+ * @param <V> the type of output of the {@code after} function, and of the
+ * composed function
+ * @param after the function to apply after this function is applied
+ * @return a composed function that first applies this function and then
+ * applies the {@code after} function
+ * @throws NullPointerException if after is null
+ *
+ * @see #compose(IOFunction)
+ */
+ default <V> IOFunction<T, V> andThen(final IOFunction<? super R, ? extends V> after) {
+ Objects.requireNonNull(after, "after");
+ return (final T t) -> after.apply(apply(t));
+ }
+
+ /**
* Applies this function to the given argument.
*
* @param t the function argument
@@ -58,7 +144,7 @@ public interface IOFunction<T, R> {
*
* @see #andThen(IOFunction)
*/
- default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) {
+ default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) {
Objects.requireNonNull(before, "before");
return (final V v) -> apply(before.apply(v));
}
@@ -78,7 +164,7 @@ public interface IOFunction<T, R> {
*
* @see #andThen(IOFunction)
*/
- default <V> IOFunction<V, R> compose(final Function<? super V, ? extends T> before) {
+ default <V> IOFunction<V, R> compose(final IOFunction<? super V, ? extends T> before) {
Objects.requireNonNull(before, "before");
return (final V v) -> apply(before.apply(v));
}
@@ -118,90 +204,4 @@ public interface IOFunction<T, R> {
Objects.requireNonNull(before, "before");
return () -> apply(before.get());
}
-
- /**
- * Returns a composed {@link IOFunction} that first applies this function to
- * its input, and then applies the {@code after} function to the result.
- * If evaluation of either function throws an exception, it is relayed to
- * the caller of the composed function.
- *
- * @param <V> the type of output of the {@code after} function, and of the
- * composed function
- * @param after the function to apply after this function is applied
- * @return a composed function that first applies this function and then
- * applies the {@code after} function
- * @throws NullPointerException if after is null
- *
- * @see #compose(IOFunction)
- */
- default <V> IOFunction<T, V> andThen(final IOFunction<? super R, ? extends V> after) {
- Objects.requireNonNull(after, "after");
- return (final T t) -> after.apply(apply(t));
- }
-
- /**
- * Returns a composed {@link IOFunction} that first applies this function to
- * its input, and then applies the {@code after} function to the result.
- * If evaluation of either function throws an exception, it is relayed to
- * the caller of the composed function.
- *
- * @param <V> the type of output of the {@code after} function, and of the
- * composed function
- * @param after the function to apply after this function is applied
- * @return a composed function that first applies this function and then
- * applies the {@code after} function
- * @throws NullPointerException if after is null
- *
- * @see #compose(IOFunction)
- */
- default <V> IOFunction<T, V> andThen(final Function<? super R, ? extends V> after) {
- Objects.requireNonNull(after, "after");
- return (final T t) -> after.apply(apply(t));
- }
-
- /**
- * Returns a composed {@link IOFunction} that first applies this function to
- * its input, and then applies the {@code after} consumer to the result.
- * If evaluation of either function throws an exception, it is relayed to
- * the caller of the composed function.
- *
- * @param after the consumer to apply after this function is applied
- * @return a composed function that first applies this function and then
- * applies the {@code after} consumer
- * @throws NullPointerException if after is null
- *
- * @see #compose(IOFunction)
- */
- default IOConsumer<T> andThen(final IOConsumer<? super R> after) {
- Objects.requireNonNull(after, "after");
- return (final T t) -> after.accept(apply(t));
- }
-
- /**
- * Returns a composed {@link IOFunction} that first applies this function to
- * its input, and then applies the {@code after} consumer to the result.
- * If evaluation of either function throws an exception, it is relayed to
- * the caller of the composed function.
- *
- * @param after the consumer to apply after this function is applied
- * @return a composed function that first applies this function and then
- * applies the {@code after} consumer
- * @throws NullPointerException if after is null
- *
- * @see #compose(IOFunction)
- */
- default IOConsumer<T> andThen(final Consumer<? super R> after) {
- Objects.requireNonNull(after, "after");
- return (final T t) -> after.accept(apply(t));
- }
-
- /**
- * Returns a {@link IOFunction} that always returns its input argument.
- *
- * @param <T> the type of the input and output objects to the function
- * @return a function that always returns its input argument
- */
- static <T> IOFunction<T, T> identity() {
- return t -> t;
- }
}
diff --git a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
index 86b3530..bf3d317 100644
--- a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java
@@ -48,6 +48,20 @@ public class AutoCloseInputStream extends ProxyInputStream {
}
/**
+ * Automatically closes the stream if the end of stream was reached.
+ *
+ * @param n number of bytes read, or -1 if no more bytes are available
+ * @throws IOException if the stream could not be closed
+ * @since 2.0
+ */
+ @Override
+ protected void afterRead(final int n) throws IOException {
+ if (n == EOF) {
+ close();
+ }
+ }
+
+ /**
* Closes the underlying input stream and replaces the reference to it
* with a {@link ClosedInputStream} instance.
* <p>
@@ -67,20 +81,6 @@ public class AutoCloseInputStream extends ProxyInputStream {
}
/**
- * Automatically closes the stream if the end of stream was reached.
- *
- * @param n number of bytes read, or -1 if no more bytes are available
- * @throws IOException if the stream could not be closed
- * @since 2.0
- */
- @Override
- protected void afterRead(final int n) throws IOException {
- if (n == EOF) {
- close();
- }
- }
-
- /**
* Ensures that the stream is closed before it gets garbage-collected.
* As mentioned in {@link #close()}, this is a no-op if the stream has
* already been closed.
diff --git a/src/main/java/org/apache/commons/io/input/BOMInputStream.java b/src/main/java/org/apache/commons/io/input/BOMInputStream.java
index e948378..2cfe523 100644
--- a/src/main/java/org/apache/commons/io/input/BOMInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BOMInputStream.java
@@ -88,6 +88,14 @@ import org.apache.commons.io.IOUtils;
* @since 2.0
*/
public class BOMInputStream extends ProxyInputStream {
+ /**
+ * Compares ByteOrderMark objects in descending length order.
+ */
+ private static final Comparator<ByteOrderMark> ByteOrderMarkLengthComparator = (bom1, bom2) -> {
+ final int len1 = bom1.length();
+ final int len2 = bom2.length();
+ return Integer.compare(len2, len1);
+ };
private final boolean include;
/**
* BOMs are sorted from longest to shortest.
@@ -98,6 +106,7 @@ public class BOMInputStream extends ProxyInputStream {
private int fbLength;
private int fbIndex;
private int markFbIndex;
+
private boolean markedAtStart;
/**
@@ -123,27 +132,6 @@ public class BOMInputStream extends ProxyInputStream {
}
/**
- * 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
- */
- public BOMInputStream(final InputStream delegate, final ByteOrderMark... boms) {
- this(delegate, false, boms);
- }
-
- /**
- * Compares ByteOrderMark objects in descending length order.
- */
- private static final Comparator<ByteOrderMark> ByteOrderMarkLengthComparator = (bom1, bom2) -> {
- final int len1 = bom1.length();
- final int len2 = bom2.length();
- return Integer.compare(len2, len1);
- };
-
- /**
* Constructs a new BOM InputStream that detects the specified BOMs and optionally includes them.
*
* @param delegate
@@ -167,33 +155,29 @@ public class BOMInputStream extends ProxyInputStream {
}
/**
- * Indicates whether the stream contains one of the specified BOMs.
+ * Constructs a new BOM InputStream that excludes 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
+ * @param delegate
+ * the InputStream to delegate to
+ * @param boms
+ * The BOMs to detect and exclude
*/
- public boolean hasBOM() throws IOException {
- return getBOM() != null;
+ public BOMInputStream(final InputStream delegate, final ByteOrderMark... boms) {
+ this(delegate, false, boms);
}
/**
- * Indicates whether the stream contains the specified BOM.
+ * Find a BOM with the specified bytes.
*
- * @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
+ * @return The matched BOM or null if none matched
*/
- public boolean hasBOM(final ByteOrderMark bom) throws IOException {
- if (!boms.contains(bom)) {
- throw new IllegalArgumentException("Stream not configure to detect " + bom);
+ private ByteOrderMark find() {
+ for (final ByteOrderMark bom : boms) {
+ if (matches(bom)) {
+ return bom;
+ }
}
- getBOM();
- return byteOrderMark != null && byteOrderMark.equals(bom);
+ return null;
}
/**
@@ -244,31 +228,46 @@ public class BOMInputStream extends ProxyInputStream {
}
/**
- * This method reads and either preserves or skips the first bytes in the stream. It behaves like the single-byte
- * {@code read()} method, either returning a valid byte or -1 to indicate that the initial bytes have been
- * processed already.
+ * Indicates whether the stream contains one of the specified BOMs.
*
- * @return the byte read (excluding BOM) or -1 if the end of stream
+ * @return true if the stream has one of the specified BOMs, otherwise false if it does not
* @throws IOException
- * if an I/O error occurs
+ * if an error reading the first bytes of the stream occurs
*/
- private int readFirstBytes() throws IOException {
- getBOM();
- return fbIndex < fbLength ? firstBytes[fbIndex++] : EOF;
+ public boolean hasBOM() throws IOException {
+ return getBOM() != null;
}
/**
- * Find a BOM with the specified bytes.
+ * Indicates whether the stream contains the specified BOM.
*
- * @return The matched BOM or null if none matched
+ * @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
*/
- private ByteOrderMark find() {
- for (final ByteOrderMark bom : boms) {
- if (matches(bom)) {
- return bom;
- }
+ public boolean hasBOM(final ByteOrderMark bom) throws IOException {
+ if (!boms.contains(bom)) {
+ throw new IllegalArgumentException("Stream not configure to detect " + bom);
}
- return null;
+ getBOM();
+ return byteOrderMark != null && byteOrderMark.equals(bom);
+ }
+
+ /**
+ * Invokes the delegate's {@code mark(int)} method.
+ *
+ * @param readlimit
+ * read ahead limit
+ */
+ @Override
+ public synchronized void mark(final int readlimit) {
+ markFbIndex = fbIndex;
+ markedAtStart = firstBytes == null;
+ in.mark(readlimit);
}
/**
@@ -309,6 +308,20 @@ public class BOMInputStream extends ProxyInputStream {
}
/**
+ * Invokes the delegate's {@code read(byte[])} method, detecting and optionally skipping BOM.
+ *
+ * @param buf
+ * the buffer to read the bytes into
+ * @return the number of bytes read (excluding BOM) or -1 if the end of stream
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ @Override
+ public int read(final byte[] buf) throws IOException {
+ return read(buf, 0, buf.length);
+ }
+
+ /**
* Invokes the delegate's {@code read(byte[], int, int)} method, detecting and optionally skipping BOM.
*
* @param buf
@@ -338,30 +351,17 @@ public class BOMInputStream extends ProxyInputStream {
}
/**
- * Invokes the delegate's {@code read(byte[])} method, detecting and optionally skipping BOM.
+ * This method reads and either preserves or skips the first bytes in the stream. It behaves like the single-byte
+ * {@code read()} method, either returning a valid byte or -1 to indicate that the initial bytes have been
+ * processed already.
*
- * @param buf
- * the buffer to read the bytes into
- * @return the number of bytes read (excluding BOM) or -1 if the end of stream
+ * @return the byte read (excluding BOM) or -1 if the end of stream
* @throws IOException
* if an I/O error occurs
*/
- @Override
- public int read(final byte[] buf) throws IOException {
- return read(buf, 0, buf.length);
- }
-
- /**
- * Invokes the delegate's {@code mark(int)} method.
- *
- * @param readlimit
- * read ahead limit
- */
- @Override
- public synchronized void mark(final int readlimit) {
- markFbIndex = fbIndex;
- markedAtStart = firstBytes == null;
- in.mark(readlimit);
+ private int readFirstBytes() throws IOException {
+ getBOM();
+ return fbIndex < fbLength ? firstBytes[fbIndex++] : EOF;
}
/**
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 6babddb..f09a6ee 100644
--- a/src/main/java/org/apache/commons/io/input/BoundedInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BoundedInputStream.java
@@ -54,6 +54,16 @@ public class BoundedInputStream extends InputStream {
/**
* Creates a new {@code BoundedInputStream} that wraps the given input
+ * stream and is unlimited.
+ *
+ * @param in The wrapped input stream
+ */
+ public BoundedInputStream(final InputStream in) {
+ this(in, EOF);
+ }
+
+ /**
+ * Creates a new {@code BoundedInputStream} that wraps the given input
* stream and limits it to a certain size.
*
* @param in The wrapped input stream
@@ -67,13 +77,57 @@ public class BoundedInputStream extends InputStream {
}
/**
- * Creates a new {@code BoundedInputStream} that wraps the given input
- * stream and is unlimited.
+ * {@inheritDoc}
+ */
+ @Override
+ public int available() throws IOException {
+ if (max>=0 && pos>=max) {
+ return 0;
+ }
+ return in.available();
+ }
+
+ /**
+ * Invokes the delegate's {@code close()} method
+ * if {@link #isPropagateClose()} is {@code true}.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ if (propagateClose) {
+ in.close();
+ }
+ }
+
+ /**
+ * Indicates whether the {@link #close()} method
+ * should propagate to the underling {@link InputStream}.
*
- * @param in The wrapped input stream
+ * @return {@code true} if calling {@link #close()}
+ * propagates to the {@code close()} method of the
+ * underlying stream or {@code false} if it does not.
*/
- public BoundedInputStream(final InputStream in) {
- this(in, EOF);
+ public boolean isPropagateClose() {
+ return propagateClose;
+ }
+
+ /**
+ * Invokes the delegate's {@code mark(int)} method.
+ * @param readlimit read ahead limit
+ */
+ @Override
+ public synchronized void mark(final int readlimit) {
+ in.mark(readlimit);
+ mark = pos;
+ }
+
+ /**
+ * Invokes the delegate's {@code markSupported()} method.
+ * @return true if mark is supported, otherwise false
+ */
+ @Override
+ public boolean markSupported() {
+ return in.markSupported();
}
/**
@@ -131,52 +185,6 @@ public class BoundedInputStream extends InputStream {
}
/**
- * Invokes the delegate's {@code skip(long)} method.
- * @param n the number of bytes to skip
- * @return the actual number of bytes skipped
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public long skip(final long n) throws IOException {
- final long toSkip = max>=0 ? Math.min(n, max-pos) : n;
- final long skippedBytes = in.skip(toSkip);
- pos+=skippedBytes;
- return skippedBytes;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int available() throws IOException {
- if (max>=0 && pos>=max) {
- return 0;
- }
- return in.available();
- }
-
- /**
- * Invokes the delegate's {@code toString()} method.
- * @return the delegate's {@code toString()}
- */
- @Override
- public String toString() {
- return in.toString();
- }
-
- /**
- * Invokes the delegate's {@code close()} method
- * if {@link #isPropagateClose()} is {@code true}.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- if (propagateClose) {
- in.close();
- }
- }
-
- /**
* Invokes the delegate's {@code reset()} method.
* @throws IOException if an I/O error occurs.
*/
@@ -187,37 +195,6 @@ public class BoundedInputStream extends InputStream {
}
/**
- * Invokes the delegate's {@code mark(int)} method.
- * @param readlimit read ahead limit
- */
- @Override
- public synchronized void mark(final int readlimit) {
- in.mark(readlimit);
- mark = pos;
- }
-
- /**
- * Invokes the delegate's {@code markSupported()} method.
- * @return true if mark is supported, otherwise false
- */
- @Override
- public boolean markSupported() {
- return in.markSupported();
- }
-
- /**
- * Indicates whether the {@link #close()} method
- * should propagate to the underling {@link InputStream}.
- *
- * @return {@code true} if calling {@link #close()}
- * propagates to the {@code close()} method of the
- * underlying stream or {@code false} if it does not.
- */
- public boolean isPropagateClose() {
- return propagateClose;
- }
-
- /**
* Set whether the {@link #close()} method
* should propagate to the underling {@link InputStream}.
*
@@ -229,4 +206,27 @@ public class BoundedInputStream extends InputStream {
public void setPropagateClose(final boolean propagateClose) {
this.propagateClose = propagateClose;
}
+
+ /**
+ * Invokes the delegate's {@code skip(long)} method.
+ * @param n the number of bytes to skip
+ * @return the actual number of bytes skipped
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public long skip(final long n) throws IOException {
+ final long toSkip = max>=0 ? Math.min(n, max-pos) : n;
+ final long skippedBytes = in.skip(toSkip);
+ pos+=skippedBytes;
+ return skippedBytes;
+ }
+
+ /**
+ * Invokes the delegate's {@code toString()} method.
+ * @return the delegate's {@code toString()}
+ */
+ @Override
+ public String toString() {
+ return in.toString();
+ }
}
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 00e9736..6bb59a5 100644
--- a/src/main/java/org/apache/commons/io/input/BoundedReader.java
+++ b/src/main/java/org/apache/commons/io/input/BoundedReader.java
@@ -70,18 +70,6 @@ public class BoundedReader extends Reader {
}
/**
- * Resets the target to the latest mark,
- *
- * @throws IOException If an I/O error occurs while calling the underlying reader's reset method
- * @see java.io.Reader#reset()
- */
- @Override
- public void reset() throws IOException {
- charsRead = markedAt;
- target.reset();
- }
-
- /**
* marks the target stream
*
* @param readAheadLimit The number of characters that can be read while still retaining the ability to do #reset().
@@ -143,4 +131,16 @@ public class BoundedReader extends Reader {
}
return len;
}
+
+ /**
+ * Resets the target to the latest mark,
+ *
+ * @throws IOException If an I/O error occurs while calling the underlying reader's reset method
+ * @see java.io.Reader#reset()
+ */
+ @Override
+ public void reset() throws IOException {
+ charsRead = markedAt;
+ target.reset();
+ }
}
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 907e37c..03131d0 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
@@ -42,6 +42,13 @@ public class BrokenInputStream extends InputStream {
private final IOException exception;
/**
+ * Creates a new stream that always throws an {@link IOException}
+ */
+ public BrokenInputStream() {
+ this(new IOException("Broken input stream"));
+ }
+
+ /**
* Creates a new stream that always throws the given exception.
*
* @param exception the exception to be thrown
@@ -51,43 +58,34 @@ public class BrokenInputStream extends InputStream {
}
/**
- * Creates a new stream that always throws an {@link IOException}
- */
- public BrokenInputStream() {
- this(new IOException("Broken input stream"));
- }
-
- /**
* Throws the configured exception.
*
* @return nothing
* @throws IOException always thrown
*/
@Override
- public int read() throws IOException {
+ public int available() throws IOException {
throw exception;
}
/**
* Throws the configured exception.
*
- * @return nothing
* @throws IOException always thrown
*/
@Override
- public int available() throws IOException {
+ public void close() throws IOException {
throw exception;
}
/**
* Throws the configured exception.
*
- * @param n ignored
* @return nothing
* @throws IOException always thrown
*/
@Override
- public long skip(final long n) throws IOException {
+ public int read() throws IOException {
throw exception;
}
@@ -104,10 +102,12 @@ public class BrokenInputStream extends InputStream {
/**
* Throws the configured exception.
*
+ * @param n ignored
+ * @return nothing
* @throws IOException always thrown
*/
@Override
- public void close() throws IOException {
+ public long skip(final long n) throws IOException {
throw exception;
}
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 b627c3c..ddce28c 100644
--- a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
@@ -53,6 +53,18 @@ public class CharSequenceInputStream extends InputStream {
private int mark_bbuf; // position in bbuf
/**
+ * Constructor, calls {@link #CharSequenceInputStream(CharSequence, Charset, int)}
+ * with a buffer size of 2048.
+ *
+ * @param cs the input character sequence
+ * @param charset the character set name to use
+ * @throws IllegalArgumentException if the buffer is not large enough to hold a complete character
+ */
+ public CharSequenceInputStream(final CharSequence cs, final Charset charset) {
+ this(cs, charset, BUFFER_SIZE);
+ }
+
+ /**
* Constructor.
*
* @param cs the input character sequence
@@ -78,39 +90,47 @@ public class CharSequenceInputStream extends InputStream {
}
/**
- * Constructor, calls {@link #CharSequenceInputStream(CharSequence, Charset, int)}.
+ * Constructor, calls {@link #CharSequenceInputStream(CharSequence, String, int)}
+ * with a buffer size of 2048.
*
* @param cs the input character sequence
* @param charset the character set name to use
- * @param bufferSize the buffer size to use.
* @throws IllegalArgumentException if the buffer is not large enough to hold a complete character
*/
- public CharSequenceInputStream(final CharSequence cs, final String charset, final int bufferSize) {
- this(cs, Charset.forName(charset), bufferSize);
+ public CharSequenceInputStream(final CharSequence cs, final String charset) {
+ this(cs, charset, BUFFER_SIZE);
}
/**
- * Constructor, calls {@link #CharSequenceInputStream(CharSequence, Charset, int)}
- * with a buffer size of 2048.
+ * Constructor, calls {@link #CharSequenceInputStream(CharSequence, Charset, int)}.
*
* @param cs the input character sequence
* @param charset the character set name to use
+ * @param bufferSize the buffer size to use.
* @throws IllegalArgumentException if the buffer is not large enough to hold a complete character
*/
- public CharSequenceInputStream(final CharSequence cs, final Charset charset) {
- this(cs, charset, BUFFER_SIZE);
+ public CharSequenceInputStream(final CharSequence cs, final String charset, final int bufferSize) {
+ this(cs, Charset.forName(charset), bufferSize);
}
/**
- * Constructor, calls {@link #CharSequenceInputStream(CharSequence, String, int)}
- * with a buffer size of 2048.
+ * Return an estimate of the number of bytes remaining in the byte stream.
+ * @return the count of bytes that can be read without blocking (or returning EOF).
*
- * @param cs the input character sequence
- * @param charset the character set name to use
- * @throws IllegalArgumentException if the buffer is not large enough to hold a complete character
+ * @throws IOException if an error occurs (probably not possible)
*/
- public CharSequenceInputStream(final CharSequence cs, final String charset) {
- this(cs, charset, BUFFER_SIZE);
+ @Override
+ public int available() throws IOException {
+ // The cached entries are in bbuf; since encoding always creates at least one byte
+ // per character, we can add the two to get a better estimate (e.g. if bbuf is empty)
+ // Note that the previous implementation (2.4) could return zero even though there were
+ // encoded bytes still available.
+ return this.bbuf.remaining() + this.cbuf.remaining();
+ }
+
+ @Override
+ public void close() throws IOException {
+ // noop
}
/**
@@ -128,6 +148,43 @@ public class CharSequenceInputStream extends InputStream {
this.bbuf.flip();
}
+ /**
+ * {@inheritDoc}
+ * @param readlimit max read limit (ignored)
+ */
+ @Override
+ public synchronized void mark(final int readlimit) {
+ this.mark_cbuf = this.cbuf.position();
+ this.mark_bbuf = this.bbuf.position();
+ this.cbuf.mark();
+ this.bbuf.mark();
+ // It would be nice to be able to use mark & reset on the cbuf and bbuf;
+ // however the bbuf is re-used so that won't work
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public int read() throws IOException {
+ for (;;) {
+ if (this.bbuf.hasRemaining()) {
+ return this.bbuf.get() & 0xFF;
+ }
+ fillBuffer();
+ if (!this.bbuf.hasRemaining() && !this.cbuf.hasRemaining()) {
+ return EOF;
+ }
+ }
+ }
+
+ @Override
+ public int read(final byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
@Override
public int read(final byte[] array, int off, int len) throws IOException {
Objects.requireNonNull(array, "array");
@@ -160,72 +217,6 @@ public class CharSequenceInputStream extends InputStream {
}
@Override
- public int read() throws IOException {
- for (;;) {
- if (this.bbuf.hasRemaining()) {
- return this.bbuf.get() & 0xFF;
- }
- fillBuffer();
- if (!this.bbuf.hasRemaining() && !this.cbuf.hasRemaining()) {
- return EOF;
- }
- }
- }
-
- @Override
- public int read(final byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @Override
- public long skip(long n) throws IOException {
- /*
- * This could be made more efficient by using position to skip within the current buffer.
- */
- long skipped = 0;
- while (n > 0 && available() > 0) {
- this.read();
- n--;
- skipped++;
- }
- return skipped;
- }
-
- /**
- * Return an estimate of the number of bytes remaining in the byte stream.
- * @return the count of bytes that can be read without blocking (or returning EOF).
- *
- * @throws IOException if an error occurs (probably not possible)
- */
- @Override
- public int available() throws IOException {
- // The cached entries are in bbuf; since encoding always creates at least one byte
- // per character, we can add the two to get a better estimate (e.g. if bbuf is empty)
- // Note that the previous implementation (2.4) could return zero even though there were
- // encoded bytes still available.
- return this.bbuf.remaining() + this.cbuf.remaining();
- }
-
- @Override
- public void close() throws IOException {
- // noop
- }
-
- /**
- * {@inheritDoc}
- * @param readlimit max read limit (ignored)
- */
- @Override
- public synchronized void mark(final int readlimit) {
- this.mark_cbuf = this.cbuf.position();
- this.mark_bbuf = this.bbuf.position();
- this.cbuf.mark();
- this.bbuf.mark();
- // It would be nice to be able to use mark & reset on the cbuf and bbuf;
- // however the bbuf is re-used so that won't work
- }
-
- @Override
public synchronized void reset() throws IOException {
/*
* This is not the most efficient implementation, as it re-encodes from the beginning.
@@ -262,8 +253,17 @@ public class CharSequenceInputStream extends InputStream {
}
@Override
- public boolean markSupported() {
- return true;
+ public long skip(long n) throws IOException {
+ /*
+ * This could be made more efficient by using position to skip within the current buffer.
+ */
+ long skipped = 0;
+ while (n > 0 && available() > 0) {
+ this.read();
+ n--;
+ skipped++;
+ }
+ return skipped;
}
}
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 7a7fcd3..89448e6 100644
--- a/src/main/java/org/apache/commons/io/input/CharSequenceReader.java
+++ b/src/main/java/org/apache/commons/io/input/CharSequenceReader.java
@@ -135,12 +135,12 @@ public class CharSequenceReader extends Reader implements Serializable {
}
/**
- * Returns the index in the character sequence to start reading from, taking into account its length.
- *
- * @return The start index in the character sequence (inclusive).
+ * Close resets the file back to the start and removes any marked position.
*/
- private int start() {
- return Math.min(charSequence.length(), start);
+ @Override
+ public void close() {
+ idx = start;
+ mark = start;
}
/**
@@ -157,25 +157,6 @@ public class CharSequenceReader extends Reader implements Serializable {
}
/**
- * Close resets the file back to the start and removes any marked position.
- */
- @Override
- public void close() {
- idx = start;
- mark = start;
- }
-
- /**
- * Tells whether this stream is ready to be read.
- *
- * @return {@code true} if more characters from the character sequence are available, or {@code false} otherwise.
- */
- @Override
- public boolean ready() {
- return idx < end();
- }
-
- /**
* Mark the current position.
*
* @param readAheadLimit ignored
@@ -261,6 +242,16 @@ public class CharSequenceReader extends Reader implements Serializable {
}
/**
+ * Tells whether this stream is ready to be read.
+ *
+ * @return {@code true} if more characters from the character sequence are available, or {@code false} otherwise.
+ */
+ @Override
+ public boolean ready() {
+ return idx < end();
+ }
+
+ /**
* Reset the reader to the last marked position (or the beginning if
* mark has not been called).
*/
@@ -291,6 +282,15 @@ public class CharSequenceReader extends Reader implements Serializable {
}
/**
+ * Returns the index in the character sequence to start reading from, taking into account its length.
+ *
+ * @return The start index in the character sequence (inclusive).
+ */
+ private int start() {
+ return Math.min(charSequence.length(), start);
+ }
+
+ /**
* Return a String representation of the underlying
* character sequence.
*
diff --git a/src/main/java/org/apache/commons/io/input/ClosedReader.java b/src/main/java/org/apache/commons/io/input/ClosedReader.java
index ac5b0df..71e21d2 100644
--- a/src/main/java/org/apache/commons/io/input/ClosedReader.java
+++ b/src/main/java/org/apache/commons/io/input/ClosedReader.java
@@ -49,6 +49,11 @@ public class ClosedReader extends Reader {
@Deprecated
public static final ClosedReader CLOSED_READER = INSTANCE;
+ @Override
+ public void close() throws IOException {
+ // noop
+ }
+
/**
* Returns -1 to indicate that the stream is closed.
*
@@ -62,9 +67,4 @@ public class ClosedReader extends Reader {
return EOF;
}
- @Override
- public void close() throws IOException {
- // noop
- }
-
}
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 17d7c29..7054b8f 100644
--- a/src/main/java/org/apache/commons/io/input/CountingInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/CountingInputStream.java
@@ -45,22 +45,6 @@ public class CountingInputStream extends ProxyInputStream {
/**
- * 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
- * @throws IOException if an I/O error occurs.
- * @see java.io.InputStream#skip(long)
- */
- @Override
- public synchronized long skip(final long length) throws IOException {
- final long skip = super.skip(length);
- this.count += skip;
- return skip;
- }
-
- /**
* Adds the number of read bytes to the count.
*
* @param n number of bytes read, or -1 if no more bytes are available
@@ -76,6 +60,20 @@ public class CountingInputStream extends ProxyInputStream {
/**
* The number of bytes that have passed through this stream.
* <p>
+ * NOTE: This method is an alternative for {@code getCount()}
+ * and was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the number of bytes accumulated
+ * @since 1.3
+ */
+ public synchronized long getByteCount() {
+ return this.count;
+ }
+
+ /**
+ * The number of bytes that have passed through this stream.
+ * <p>
* NOTE: From v1.3 this method throws an ArithmeticException if the
* count is greater than can be expressed by an {@code int}.
* See {@link #getByteCount()} for a method using a {@code long}.
@@ -94,6 +92,22 @@ public class CountingInputStream extends ProxyInputStream {
/**
* Set the byte count back to 0.
* <p>
+ * NOTE: This method is an alternative for {@code resetCount()}
+ * and was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
+ *
+ * @return the count previous to resetting
+ * @since 1.3
+ */
+ public synchronized long resetByteCount() {
+ final long tmp = this.count;
+ this.count = 0;
+ return tmp;
+ }
+
+ /**
+ * Set the byte count back to 0.
+ * <p>
* NOTE: From v1.3 this method throws an ArithmeticException if the
* count is greater than can be expressed by an {@code int}.
* See {@link #resetByteCount()} for a method using a {@code long}.
@@ -110,33 +124,19 @@ public class CountingInputStream extends ProxyInputStream {
}
/**
- * The number of bytes that have passed through this stream.
- * <p>
- * NOTE: This method is an alternative for {@code getCount()}
- * and was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
- *
- * @return the number of bytes accumulated
- * @since 1.3
- */
- public synchronized long getByteCount() {
- return this.count;
- }
-
- /**
- * Set the byte count back to 0.
- * <p>
- * NOTE: This method is an alternative for {@code resetCount()}
- * and was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
+ * Skips the stream over the specified number of bytes, adding the skipped
+ * amount to the count.
*
- * @return the count previous to resetting
- * @since 1.3
+ * @param length the number of bytes to skip
+ * @return the actual number of bytes skipped
+ * @throws IOException if an I/O error occurs.
+ * @see java.io.InputStream#skip(long)
*/
- public synchronized long resetByteCount() {
- final long tmp = this.count;
- this.count = 0;
- return tmp;
+ @Override
+ public synchronized long skip(final long length) throws IOException {
+ final long skip = super.skip(length);
+ this.count += skip;
+ return skip;
}
}
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 1e9d46f..62c2b75 100644
--- a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java
@@ -46,18 +46,30 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream {
}
@Override
- public void data(final int input) throws IOException {
- messageDigest.update((byte) input);
+ public void data(final byte[] input, final int offset, final int length) throws IOException {
+ messageDigest.update(input, offset, length);
}
@Override
- public void data(final byte[] input, final int offset, final int length) throws IOException {
- messageDigest.update(input, offset, length);
+ public void data(final int input) throws IOException {
+ messageDigest.update((byte) input);
}
}
private final MessageDigest messageDigest;
+ /**
+ * Creates a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the
+ * "MD5" algorithm.
+ *
+ * @param inputStream the stream to calculate the message digest for
+ * @throws NoSuchAlgorithmException if no Provider supports a MessageDigestSpi implementation for the specified
+ * algorithm.
+ */
+ public MessageDigestCalculatingInputStream(final InputStream inputStream) throws NoSuchAlgorithmException {
+ this(inputStream, MessageDigest.getInstance("MD5"));
+ }
+
/** Creates a new instance, which calculates a signature on the given stream,
* using the given {@link MessageDigest}.
* @param inputStream the stream to calculate the message digest for
@@ -82,18 +94,6 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream {
this(inputStream, MessageDigest.getInstance(algorithm));
}
- /**
- * Creates a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the
- * "MD5" algorithm.
- *
- * @param inputStream the stream to calculate the message digest for
- * @throws NoSuchAlgorithmException if no Provider supports a MessageDigestSpi implementation for the specified
- * algorithm.
- */
- public MessageDigestCalculatingInputStream(final InputStream inputStream) throws NoSuchAlgorithmException {
- this(inputStream, MessageDigest.getInstance("MD5"));
- }
-
/** Returns the {@link MessageDigest}, which is being used for generating the
* checksum.
* <em>Note</em>: The checksum will only reflect the data, which has been read so far.
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 34363ec..438d602 100644
--- a/src/main/java/org/apache/commons/io/input/NullInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/NullInputStream.java
@@ -120,24 +120,6 @@ public class NullInputStream extends InputStream {
}
/**
- * Return the current position.
- *
- * @return the current position.
- */
- public long getPosition() {
- return position;
- }
-
- /**
- * Return the size this {@link InputStream} emulates.
- *
- * @return The size of the input stream to emulate.
- */
- public long getSize() {
- return size;
- }
-
- /**
* Return the number of bytes that can be read.
*
* @return The number of bytes that can be read.
@@ -168,6 +150,40 @@ public class NullInputStream extends InputStream {
}
/**
+ * Handle End of File.
+ *
+ * @return {@code -1} if {@code throwEofException} is
+ * set to {@code false}
+ * @throws EOFException if {@code throwEofException} is set
+ * to {@code true}.
+ */
+ private int doEndOfFile() throws EOFException {
+ eof = true;
+ if (throwEofException) {
+ throw new EOFException();
+ }
+ return EOF;
+ }
+
+ /**
+ * Return the current position.
+ *
+ * @return the current position.
+ */
+ public long getPosition() {
+ return position;
+ }
+
+ /**
+ * Return the size this {@link InputStream} emulates.
+ *
+ * @return The size of the input stream to emulate.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
* Mark the current position.
*
* @param readlimit The number of bytes before this marked position
@@ -194,6 +210,32 @@ public class NullInputStream extends InputStream {
}
/**
+ * Return a byte value for the {@code read()} method.
+ * <p>
+ * This implementation returns zero.
+ *
+ * @return This implementation always returns zero.
+ */
+ protected int processByte() {
+ // do nothing - overridable by subclass
+ return 0;
+ }
+
+ /**
+ * Process the bytes for the {@code read(byte[], offset, length)}
+ * method.
+ * <p>
+ * This implementation leaves the byte array unchanged.
+ *
+ * @param bytes The byte array
+ * @param offset The offset to start at.
+ * @param length The number of bytes.
+ */
+ protected void processBytes(final byte[] bytes, final int offset, final int length) {
+ // do nothing - overridable by subclass
+ }
+
+ /**
* Read a byte.
*
* @return Either The byte value returned by {@code processByte()}
@@ -315,46 +357,4 @@ public class NullInputStream extends InputStream {
return returnLength;
}
- /**
- * Return a byte value for the {@code read()} method.
- * <p>
- * This implementation returns zero.
- *
- * @return This implementation always returns zero.
- */
- protected int processByte() {
- // do nothing - overridable by subclass
- return 0;
- }
-
- /**
- * Process the bytes for the {@code read(byte[], offset, length)}
- * method.
- * <p>
- * This implementation leaves the byte array unchanged.
- *
- * @param bytes The byte array
- * @param offset The offset to start at.
- * @param length The number of bytes.
- */
- protected void processBytes(final byte[] bytes, final int offset, final int length) {
- // do nothing - overridable by subclass
- }
-
- /**
- * Handle End of File.
- *
- * @return {@code -1} if {@code throwEofException} is
- * set to {@code false}
- * @throws EOFException if {@code throwEofException} is set
- * to {@code true}.
- */
- private int doEndOfFile() throws EOFException {
- eof = true;
- if (throwEofException) {
- throw new EOFException();
- }
- return EOF;
- }
-
}
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 bf6cd0a..6e214eb 100644
--- a/src/main/java/org/apache/commons/io/input/NullReader.java
+++ b/src/main/java/org/apache/commons/io/input/NullReader.java
@@ -119,6 +119,35 @@ public class NullReader extends Reader {
}
/**
+ * Closes this Reader - resets the internal state to
+ * the initial values.
+ *
+ * @throws IOException If an error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ eof = false;
+ position = 0;
+ mark = -1;
+ }
+
+ /**
+ * Handles End of File.
+ *
+ * @return {@code -1} if {@code throwEofException} is
+ * set to {@code false}
+ * @throws EOFException if {@code throwEofException} is set
+ * to {@code true}.
+ */
+ private int doEndOfFile() throws EOFException {
+ eof = true;
+ if (throwEofException) {
+ throw new EOFException();
+ }
+ return EOF;
+ }
+
+ /**
* Returns the current position.
*
* @return the current position.
@@ -137,19 +166,6 @@ public class NullReader extends Reader {
}
/**
- * Closes this Reader - resets the internal state to
- * the initial values.
- *
- * @throws IOException If an error occurs.
- */
- @Override
- public void close() throws IOException {
- eof = false;
- position = 0;
- mark = -1;
- }
-
- /**
* Marks the current position.
*
* @param readlimit The number of characters before this marked position
@@ -176,6 +192,34 @@ public class NullReader extends Reader {
}
/**
+ * Returns a character value for the {@code read()} method.
+ * <p>
+ * This implementation returns zero.
+ * </p>
+ *
+ * @return This implementation always returns zero.
+ */
+ protected int processChar() {
+ // do nothing - overridable by subclass
+ return 0;
+ }
+
+ /**
+ * Process the characters for the {@code read(char[], offset, length)}
+ * method.
+ * <p>
+ * This implementation leaves the character array unchanged.
+ * </p>
+ *
+ * @param chars The character array
+ * @param offset The offset to start at.
+ * @param length The number of characters.
+ */
+ protected void processChars(final char[] chars, final int offset, final int length) {
+ // do nothing - overridable by subclass
+ }
+
+ /**
* Reads a character.
*
* @return Either The character value returned by {@code processChar()}
@@ -297,48 +341,4 @@ public class NullReader extends Reader {
return returnLength;
}
- /**
- * Returns a character value for the {@code read()} method.
- * <p>
- * This implementation returns zero.
- * </p>
- *
- * @return This implementation always returns zero.
- */
- protected int processChar() {
- // do nothing - overridable by subclass
- return 0;
- }
-
- /**
- * Process the characters for the {@code read(char[], offset, length)}
- * method.
- * <p>
- * This implementation leaves the character array unchanged.
- * </p>
- *
- * @param chars The character array
- * @param offset The offset to start at.
- * @param length The number of characters.
- */
- protected void processChars(final char[] chars, final int offset, final int length) {
- // do nothing - overridable by subclass
- }
-
- /**
- * Handles End of File.
- *
- * @return {@code -1} if {@code throwEofException} is
- * set to {@code false}
- * @throws EOFException if {@code throwEofException} is set
- * to {@code true}.
- */
- private int doEndOfFile() throws EOFException {
- eof = true;
- if (throwEofException) {
- throw new EOFException();
- }
- return EOF;
- }
-
}
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 fdea363..b1b8ec5 100644
--- a/src/main/java/org/apache/commons/io/input/ProxyInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/ProxyInputStream.java
@@ -51,6 +51,106 @@ public abstract class ProxyInputStream extends FilterInputStream {
}
/**
+ * Invoked by the read methods after the proxied call has returned
+ * successfully. The number of bytes returned to the caller (or -1 if
+ * the end of stream was reached) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common post-processing
+ * functionality without having to override all the read methods.
+ * The default implementation does nothing.
+ * <p>
+ * Note this method is <em>not</em> 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.
+ *
+ * @since 2.0
+ * @param n number of bytes read, or -1 if the end of stream was reached
+ * @throws IOException if the post-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void afterRead(final int n) throws IOException {
+ // no-op
+ }
+
+ /**
+ * Invokes the delegate's {@code available()} method.
+ * @return the number of available bytes
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int available() throws IOException {
+ try {
+ return super.available();
+ } catch (final IOException e) {
+ handleIOException(e);
+ return 0;
+ }
+ }
+
+ /**
+ * Invoked by the read methods before the call is proxied. The number
+ * of bytes that the caller wanted to read (1 for the {@link #read()}
+ * method, buffer length for {@link #read(byte[])}, etc.) is given as
+ * an argument.
+ * <p>
+ * Subclasses can override this method to add common pre-processing
+ * functionality without having to override all the read methods.
+ * The default implementation does nothing.
+ * <p>
+ * Note this method is <em>not</em> 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.
+ *
+ * @since 2.0
+ * @param n number of bytes that the caller asked to be read
+ * @throws IOException if the pre-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void beforeRead(final int n) throws IOException {
+ // no-op
+ }
+
+ /**
+ * Invokes the delegate's {@code close()} method.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ IOUtils.close(in, this::handleIOException);
+ }
+
+ /**
+ * Handle any IOExceptions thrown.
+ * <p>
+ * This method provides a point to implement custom exception
+ * handling. The default behavior is to re-throw the exception.
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ * @since 2.0
+ */
+ protected void handleIOException(final IOException e) throws IOException {
+ throw e;
+ }
+
+ /**
+ * Invokes the delegate's {@code mark(int)} method.
+ * @param readlimit read ahead limit
+ */
+ @Override
+ public synchronized void mark(final int readlimit) {
+ in.mark(readlimit);
+ }
+
+ /**
+ * Invokes the delegate's {@code markSupported()} method.
+ * @return true if mark is supported, otherwise false
+ */
+ @Override
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ /**
* Invokes the delegate's {@code read()} method.
* @return the byte read or -1 if the end of stream
* @throws IOException if an I/O error occurs.
@@ -109,132 +209,32 @@ public abstract class ProxyInputStream extends FilterInputStream {
}
/**
- * Invokes the delegate's {@code skip(long)} method.
- * @param ln the number of bytes to skip
- * @return the actual number of bytes skipped
+ * Invokes the delegate's {@code reset()} method.
* @throws IOException if an I/O error occurs.
*/
@Override
- public long skip(final long ln) throws IOException {
+ public synchronized void reset() throws IOException {
try {
- return in.skip(ln);
+ in.reset();
} catch (final IOException e) {
handleIOException(e);
- return 0;
}
}
/**
- * Invokes the delegate's {@code available()} method.
- * @return the number of available bytes
+ * Invokes the delegate's {@code skip(long)} method.
+ * @param ln the number of bytes to skip
+ * @return the actual number of bytes skipped
* @throws IOException if an I/O error occurs.
*/
@Override
- public int available() throws IOException {
+ public long skip(final long ln) throws IOException {
try {
- return super.available();
+ return in.skip(ln);
} catch (final IOException e) {
handleIOException(e);
return 0;
}
}
- /**
- * Invokes the delegate's {@code close()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- IOUtils.close(in, this::handleIOException);
- }
-
- /**
- * Invokes the delegate's {@code mark(int)} method.
- * @param readlimit read ahead limit
- */
- @Override
- public synchronized void mark(final int readlimit) {
- in.mark(readlimit);
- }
-
- /**
- * Invokes the delegate's {@code reset()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public synchronized void reset() throws IOException {
- try {
- in.reset();
- } catch (final IOException e) {
- handleIOException(e);
- }
- }
-
- /**
- * Invokes the delegate's {@code markSupported()} method.
- * @return true if mark is supported, otherwise false
- */
- @Override
- public boolean markSupported() {
- return in.markSupported();
- }
-
- /**
- * Invoked by the read methods before the call is proxied. The number
- * of bytes that the caller wanted to read (1 for the {@link #read()}
- * method, buffer length for {@link #read(byte[])}, etc.) is given as
- * an argument.
- * <p>
- * Subclasses can override this method to add common pre-processing
- * functionality without having to override all the read methods.
- * The default implementation does nothing.
- * <p>
- * Note this method is <em>not</em> 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.
- *
- * @since 2.0
- * @param n number of bytes that the caller asked to be read
- * @throws IOException if the pre-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void beforeRead(final int n) throws IOException {
- // no-op
- }
-
- /**
- * Invoked by the read methods after the proxied call has returned
- * successfully. The number of bytes returned to the caller (or -1 if
- * the end of stream was reached) is given as an argument.
- * <p>
- * Subclasses can override this method to add common post-processing
- * functionality without having to override all the read methods.
- * The default implementation does nothing.
- * <p>
- * Note this method is <em>not</em> 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.
- *
- * @since 2.0
- * @param n number of bytes read, or -1 if the end of stream was reached
- * @throws IOException if the post-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void afterRead(final int n) throws IOException {
- // no-op
- }
-
- /**
- * Handle any IOExceptions thrown.
- * <p>
- * This method provides a point to implement custom exception
- * handling. The default behavior is to re-throw the exception.
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- * @since 2.0
- */
- protected void handleIOException(final IOException e) throws IOException {
- throw e;
- }
-
}
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 8ed16ae..f05f5b0 100644
--- a/src/main/java/org/apache/commons/io/input/ProxyReader.java
+++ b/src/main/java/org/apache/commons/io/input/ProxyReader.java
@@ -48,6 +48,100 @@ public abstract class ProxyReader extends FilterReader {
}
/**
+ * Invoked by the read methods after the proxied call has returned
+ * successfully. The number of chars returned to the caller (or -1 if
+ * the end of stream was reached) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common post-processing
+ * functionality without having to override all the read methods.
+ * The default implementation does nothing.
+ * <p>
+ * Note this method is <em>not</em> 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.
+ *
+ * @since 2.0
+ * @param n number of chars read, or -1 if the end of stream was reached
+ * @throws IOException if the post-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void afterRead(final int n) throws IOException {
+ // noop
+ }
+
+ /**
+ * Invoked by the read methods before the call is proxied. The number
+ * of chars that the caller wanted to read (1 for the {@link #read()}
+ * method, buffer length for {@link #read(char[])}, etc.) is given as
+ * an argument.
+ * <p>
+ * Subclasses can override this method to add common pre-processing
+ * functionality without having to override all the read methods.
+ * The default implementation does nothing.
+ * <p>
+ * Note this method is <em>not</em> 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.
+ *
+ * @since 2.0
+ * @param n number of chars that the caller asked to be read
+ * @throws IOException if the pre-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void beforeRead(final int n) throws IOException {
+ // noop
+ }
+
+ /**
+ * Invokes the delegate's {@code close()} method.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ try {
+ in.close();
+ } catch (final IOException e) {
+ handleIOException(e);
+ }
+ }
+
+ /**
+ * Handle any IOExceptions thrown.
+ * <p>
+ * This method provides a point to implement custom exception
+ * handling. The default behavior is to re-throw the exception.
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ * @since 2.0
+ */
+ protected void handleIOException(final IOException e) throws IOException {
+ throw e;
+ }
+
+ /**
+ * Invokes the delegate's {@code mark(int)} method.
+ * @param idx read ahead limit
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public synchronized void mark(final int idx) throws IOException {
+ try {
+ in.mark(idx);
+ } catch (final IOException e) {
+ handleIOException(e);
+ }
+ }
+
+ /**
+ * Invokes the delegate's {@code markSupported()} method.
+ * @return true if mark is supported, otherwise false
+ */
+ @Override
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ /**
* Invokes the delegate's {@code read()} method.
* @return the character read or -1 if the end of stream
* @throws IOException if an I/O error occurs.
@@ -126,22 +220,6 @@ public abstract class ProxyReader extends FilterReader {
}
/**
- * Invokes the delegate's {@code skip(long)} method.
- * @param ln the number of bytes to skip
- * @return the number of bytes to skipped or EOF if the end of stream
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public long skip(final long ln) throws IOException {
- try {
- return in.skip(ln);
- } catch (final IOException e) {
- handleIOException(e);
- return 0;
- }
- }
-
- /**
* Invokes the delegate's {@code ready()} method.
* @return true if the stream is ready to be read
* @throws IOException if an I/O error occurs.
@@ -157,110 +235,32 @@ public abstract class ProxyReader extends FilterReader {
}
/**
- * Invokes the delegate's {@code close()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- try {
- in.close();
- } catch (final IOException e) {
- handleIOException(e);
- }
- }
-
- /**
- * Invokes the delegate's {@code mark(int)} method.
- * @param idx read ahead limit
+ * Invokes the delegate's {@code reset()} method.
* @throws IOException if an I/O error occurs.
*/
@Override
- public synchronized void mark(final int idx) throws IOException {
+ public synchronized void reset() throws IOException {
try {
- in.mark(idx);
+ in.reset();
} catch (final IOException e) {
handleIOException(e);
}
}
/**
- * Invokes the delegate's {@code reset()} method.
+ * Invokes the delegate's {@code skip(long)} method.
+ * @param ln the number of bytes to skip
+ * @return the number of bytes to skipped or EOF if the end of stream
* @throws IOException if an I/O error occurs.
*/
@Override
- public synchronized void reset() throws IOException {
+ public long skip(final long ln) throws IOException {
try {
- in.reset();
+ return in.skip(ln);
} catch (final IOException e) {
handleIOException(e);
+ return 0;
}
}
- /**
- * Invokes the delegate's {@code markSupported()} method.
- * @return true if mark is supported, otherwise false
- */
- @Override
- public boolean markSupported() {
- return in.markSupported();
- }
-
- /**
- * Invoked by the read methods before the call is proxied. The number
- * of chars that the caller wanted to read (1 for the {@link #read()}
- * method, buffer length for {@link #read(char[])}, etc.) is given as
- * an argument.
- * <p>
- * Subclasses can override this method to add common pre-processing
- * functionality without having to override all the read methods.
- * The default implementation does nothing.
- * <p>
- * Note this method is <em>not</em> 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.
- *
- * @since 2.0
- * @param n number of chars that the caller asked to be read
- * @throws IOException if the pre-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void beforeRead(final int n) throws IOException {
- // noop
- }
-
- /**
- * Invoked by the read methods after the proxied call has returned
- * successfully. The number of chars returned to the caller (or -1 if
- * the end of stream was reached) is given as an argument.
- * <p>
- * Subclasses can override this method to add common post-processing
- * functionality without having to override all the read methods.
- * The default implementation does nothing.
- * <p>
- * Note this method is <em>not</em> 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.
- *
- * @since 2.0
- * @param n number of chars read, or -1 if the end of stream was reached
- * @throws IOException if the post-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void afterRead(final int n) throws IOException {
- // noop
- }
-
- /**
- * Handle any IOExceptions thrown.
- * <p>
- * This method provides a point to implement custom exception
- * handling. The default behavior is to re-throw the exception.
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- * @since 2.0
- */
- protected void handleIOException(final IOException e) throws IOException {
- throw e;
- }
-
}
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 061a507..5e4b3db 100644
--- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java
@@ -106,31 +106,26 @@ public class ReaderInputStream extends InputStream {
private boolean endOfInput;
/**
- * Constructs a new {@link ReaderInputStream}.
+ * Constructs a new {@link ReaderInputStream} that uses the default character encoding
+ * with a default input buffer size of {@value #DEFAULT_BUFFER_SIZE} characters.
*
* @param reader the target {@link Reader}
- * @param encoder the charset encoder
- * @since 2.1
+ * @deprecated 2.5 use {@link #ReaderInputStream(Reader, Charset)} instead
*/
- public ReaderInputStream(final Reader reader, final CharsetEncoder encoder) {
- this(reader, encoder, DEFAULT_BUFFER_SIZE);
+ @Deprecated
+ public ReaderInputStream(final Reader reader) {
+ this(reader, Charset.defaultCharset());
}
/**
- * Constructs a new {@link ReaderInputStream}.
+ * Constructs a new {@link ReaderInputStream} with a default input buffer size of
+ * {@value #DEFAULT_BUFFER_SIZE} characters.
*
* @param reader the target {@link Reader}
- * @param encoder the charset encoder
- * @param bufferSize the size of the input buffer in number of characters
- * @since 2.1
+ * @param charset the charset encoding
*/
- public ReaderInputStream(final Reader reader, final CharsetEncoder encoder, final int bufferSize) {
- this.reader = reader;
- this.encoder = encoder;
- this.encoderIn = CharBuffer.allocate(bufferSize);
- this.encoderIn.flip();
- this.encoderOut = ByteBuffer.allocate(128);
- this.encoderOut.flip();
+ public ReaderInputStream(final Reader reader, final Charset charset) {
+ this(reader, charset, DEFAULT_BUFFER_SIZE);
}
/**
@@ -151,25 +146,31 @@ public class ReaderInputStream extends InputStream {
}
/**
- * Constructs a new {@link ReaderInputStream} with a default input buffer size of
- * {@value #DEFAULT_BUFFER_SIZE} characters.
+ * Constructs a new {@link ReaderInputStream}.
*
* @param reader the target {@link Reader}
- * @param charset the charset encoding
+ * @param encoder the charset encoder
+ * @since 2.1
*/
- public ReaderInputStream(final Reader reader, final Charset charset) {
- this(reader, charset, DEFAULT_BUFFER_SIZE);
+ public ReaderInputStream(final Reader reader, final CharsetEncoder encoder) {
+ this(reader, encoder, DEFAULT_BUFFER_SIZE);
}
/**
* Constructs a new {@link ReaderInputStream}.
*
* @param reader the target {@link Reader}
- * @param charsetName the name of the charset encoding
+ * @param encoder the charset encoder
* @param bufferSize the size of the input buffer in number of characters
+ * @since 2.1
*/
- public ReaderInputStream(final Reader reader, final String charsetName, final int bufferSize) {
- this(reader, Charset.forName(charsetName), bufferSize);
+ public ReaderInputStream(final Reader reader, final CharsetEncoder encoder, final int bufferSize) {
+ this.reader = reader;
+ this.encoder = encoder;
+ this.encoderIn = CharBuffer.allocate(bufferSize);
+ this.encoderIn.flip();
+ this.encoderOut = ByteBuffer.allocate(128);
+ this.encoderOut.flip();
}
/**
@@ -184,15 +185,24 @@ public class ReaderInputStream extends InputStream {
}
/**
- * Constructs a new {@link ReaderInputStream} that uses the default character encoding
- * with a default input buffer size of {@value #DEFAULT_BUFFER_SIZE} characters.
+ * Constructs a new {@link ReaderInputStream}.
*
* @param reader the target {@link Reader}
- * @deprecated 2.5 use {@link #ReaderInputStream(Reader, Charset)} instead
+ * @param charsetName the name of the charset encoding
+ * @param bufferSize the size of the input buffer in number of characters
*/
- @Deprecated
- public ReaderInputStream(final Reader reader) {
- this(reader, Charset.defaultCharset());
+ public ReaderInputStream(final Reader reader, final String charsetName, final int bufferSize) {
+ this(reader, Charset.forName(charsetName), bufferSize);
+ }
+
+ /**
+ * Close the stream. This method will cause the underlying {@link Reader}
+ * to be closed.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ reader.close();
}
/**
@@ -222,6 +232,39 @@ public class ReaderInputStream extends InputStream {
}
/**
+ * Read a single byte.
+ *
+ * @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
+ public int read() throws IOException {
+ for (;;) {
+ if (encoderOut.hasRemaining()) {
+ return encoderOut.get() & 0xFF;
+ }
+ fillBuffer();
+ if (endOfInput && !encoderOut.hasRemaining()) {
+ return EOF;
+ }
+ }
+ }
+
+ /**
+ * Read the specified number of bytes into an array.
+ *
+ * @param b the byte array to read into
+ * @return the number of bytes read or {@code -1}
+ * if the end of the stream has been reached
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public int read(final byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ /**
* Read the specified number of bytes into an array.
*
* @param array the byte array to read into
@@ -257,47 +300,4 @@ public class ReaderInputStream extends InputStream {
}
return read == 0 && endOfInput ? EOF : read;
}
-
- /**
- * Read the specified number of bytes into an array.
- *
- * @param b the byte array to read into
- * @return the number of bytes read or {@code -1}
- * if the end of the stream has been reached
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public int read(final byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- /**
- * Read a single byte.
- *
- * @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
- public int read() throws IOException {
- for (;;) {
- if (encoderOut.hasRemaining()) {
- return encoderOut.get() & 0xFF;
- }
- fillBuffer();
- if (endOfInput && !encoderOut.hasRemaining()) {
- return EOF;
- }
- }
- }
-
- /**
- * Close the stream. This method will cause the underlying {@link Reader}
- * to be closed.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- reader.close();
- }
}
diff --git a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java
index d30dc84..add4eb8 100644
--- a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java
@@ -79,6 +79,17 @@ public class TaggedInputStream extends ProxyInputStream {
}
/**
+ * Tags any IOExceptions thrown, wrapping and re-throwing.
+ *
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ protected void handleIOException(final IOException e) throws IOException {
+ throw new TaggedIOException(e, tag);
+ }
+
+ /**
* Tests if the given exception was caused by this stream.
*
* @param exception an exception
@@ -103,15 +114,4 @@ public class TaggedInputStream extends ProxyInputStream {
TaggedIOException.throwCauseIfTaggedWith(throwable, tag);
}
- /**
- * Tags any IOExceptions thrown, wrapping and re-throwing.
- *
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- */
- @Override
- protected void handleIOException(final IOException e) throws IOException {
- throw new TaggedIOException(e, tag);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/input/TaggedReader.java b/src/main/java/org/apache/commons/io/input/TaggedReader.java
index 6805f87..fff91e5 100644
--- a/src/main/java/org/apache/commons/io/input/TaggedReader.java
+++ b/src/main/java/org/apache/commons/io/input/TaggedReader.java
@@ -78,6 +78,17 @@ public class TaggedReader extends ProxyReader {
}
/**
+ * Tags any IOExceptions thrown, wrapping and re-throwing.
+ *
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ protected void handleIOException(final IOException e) throws IOException {
+ throw new TaggedIOException(e, tag);
+ }
+
+ /**
* Tests if the given exception was caused by this reader.
*
* @param exception an exception
@@ -99,15 +110,4 @@ public class TaggedReader extends ProxyReader {
TaggedIOException.throwCauseIfTaggedWith(throwable, tag);
}
- /**
- * Tags any IOExceptions thrown, wrapping and re-throwing.
- *
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- */
- @Override
- protected void handleIOException(final IOException e) throws IOException {
- throw new TaggedIOException(e, tag);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/input/TailerListener.java b/src/main/java/org/apache/commons/io/input/TailerListener.java
index de8de20..ae86685 100644
--- a/src/main/java/org/apache/commons/io/input/TailerListener.java
+++ b/src/main/java/org/apache/commons/io/input/TailerListener.java
@@ -24,13 +24,6 @@ package org.apache.commons.io.input;
public interface TailerListener {
/**
- * The tailer will call this method during construction,
- * giving the listener a method of stopping the tailer.
- * @param tailer the tailer.
- */
- void init(Tailer tailer);
-
- /**
* This method is called if the tailed file is not found.
* <p>
* <b>Note:</b> this is called from the tailer thread.
@@ -50,21 +43,28 @@ public interface TailerListener {
void fileRotated();
/**
- * Handles a line from a Tailer.
+ * Handles an Exception.
* <p>
* <b>Note:</b> this is called from the tailer thread.
* </p>
- * @param line the line.
+ * @param ex the exception.
*/
- void handle(String line);
+ void handle(Exception ex);
/**
- * Handles an Exception.
+ * Handles a line from a Tailer.
* <p>
* <b>Note:</b> this is called from the tailer thread.
* </p>
- * @param ex the exception.
+ * @param line the line.
*/
- void handle(Exception ex);
+ void handle(String line);
+
+ /**
+ * The tailer will call this method during construction,
+ * giving the listener a method of stopping the tailer.
+ * @param tailer the tailer.
+ */
+ void init(Tailer tailer);
}
diff --git a/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java b/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java
index fbf0b44..6b8760c 100644
--- a/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java
+++ b/src/main/java/org/apache/commons/io/input/TailerListenerAdapter.java
@@ -24,12 +24,16 @@ package org.apache.commons.io.input;
public class TailerListenerAdapter implements TailerListener {
/**
- * The tailer will call this method during construction,
- * giving the listener a method of stopping the tailer.
- * @param tailer the tailer.
+ * Called each time the Tailer reaches the end of the file.
+ *
+ * <b>Note:</b> this is called from the tailer thread.
+ *
+ * Note: a future version of commons-io will pull this method up to the TailerListener interface,
+ * for now clients must subclass this class to use this feature.
+ *
+ * @since 2.5
*/
- @Override
- public void init(final Tailer tailer) {
+ public void endOfFileReached() {
// noop
}
@@ -53,34 +57,30 @@ public class TailerListenerAdapter implements TailerListener {
}
/**
- * Handles a line from a Tailer.
- * @param line the line.
+ * Handles an Exception .
+ * @param ex the exception.
*/
@Override
- public void handle(final String line) {
+ public void handle(final Exception ex) {
// noop
}
/**
- * Handles an Exception .
- * @param ex the exception.
+ * Handles a line from a Tailer.
+ * @param line the line.
*/
@Override
- public void handle(final Exception ex) {
+ public void handle(final String line) {
// noop
}
/**
- * Called each time the Tailer reaches the end of the file.
- *
- * <b>Note:</b> this is called from the tailer thread.
- *
- * Note: a future version of commons-io will pull this method up to the TailerListener interface,
- * for now clients must subclass this class to use this feature.
- *
- * @since 2.5
+ * The tailer will call this method during construction,
+ * giving the listener a method of stopping the tailer.
+ * @param tailer the tailer.
*/
- public void endOfFileReached() {
+ @Override
+ public void init(final Tailer tailer) {
// noop
}
}
diff --git a/src/main/java/org/apache/commons/io/input/TeeInputStream.java b/src/main/java/org/apache/commons/io/input/TeeInputStream.java
index 27d32b8..ae1abff 100644
--- a/src/main/java/org/apache/commons/io/input/TeeInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/TeeInputStream.java
@@ -119,16 +119,14 @@ public class TeeInputStream extends ProxyInputStream {
* to the associated output stream.
*
* @param bts byte buffer
- * @param st start offset within the buffer
- * @param end maximum number of bytes to read
* @return number of bytes read, or -1 if the stream has ended
* @throws IOException if the stream could not be read (or written)
*/
@Override
- public int read(final byte[] bts, final int st, final int end) throws IOException {
- final int n = super.read(bts, st, end);
+ public int read(final byte[] bts) throws IOException {
+ final int n = super.read(bts);
if (n != EOF) {
- branch.write(bts, st, n);
+ branch.write(bts, 0, n);
}
return n;
}
@@ -138,14 +136,16 @@ public class TeeInputStream extends ProxyInputStream {
* to the associated output stream.
*
* @param bts byte buffer
+ * @param st start offset within the buffer
+ * @param end maximum number of bytes to read
* @return number of bytes read, or -1 if the stream has ended
* @throws IOException if the stream could not be read (or written)
*/
@Override
- public int read(final byte[] bts) throws IOException {
- final int n = super.read(bts);
+ public int read(final byte[] bts, final int st, final int end) throws IOException {
+ final int n = super.read(bts, st, end);
if (n != EOF) {
- branch.write(bts, 0, n);
+ branch.write(bts, st, n);
}
return n;
}
diff --git a/src/main/java/org/apache/commons/io/input/TimestampedObserver.java b/src/main/java/org/apache/commons/io/input/TimestampedObserver.java
index c9af849..ef8fc88 100644
--- a/src/main/java/org/apache/commons/io/input/TimestampedObserver.java
+++ b/src/main/java/org/apache/commons/io/input/TimestampedObserver.java
@@ -60,6 +60,15 @@ public class TimestampedObserver extends Observer {
}
/**
+ * Gets the instant for when this instance was created.
+ *
+ * @return the instant for when this instance was created.
+ */
+ public Instant getOpenInstant() {
+ return openInstant;
+ }
+
+ /**
* Gets the Duration between creation and close.
*
* @return the Duration between creation and close.
@@ -77,15 +86,6 @@ public class TimestampedObserver extends Observer {
return Duration.between(openInstant, Instant.now());
}
- /**
- * Gets the instant for when this instance was created.
- *
- * @return the instant for when this instance was created.
- */
- public Instant getOpenInstant() {
- return openInstant;
- }
-
@Override
public String toString() {
return "TimestampedObserver [openInstant=" + openInstant + ", closeInstant=" + closeInstant + "]";
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 e4bfe71..40dd692 100644
--- a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
@@ -52,19 +52,37 @@ public class UnixLineEndingInputStream extends InputStream {
}
/**
- * Reads the next item from the target, updating internal flags in the process
- * @return the next int read from the target stream
+ * Closes the stream. Also closes the underlying stream.
* @throws IOException upon error
*/
- private int readWithUpdate() throws IOException {
- final int target = this.target.read();
- eofSeen = target == EOF;
- if (eofSeen) {
- return target;
+ @Override
+ public void close() throws IOException {
+ super.close();
+ target.close();
+ }
+
+ /**
+ * Handles the EOF-handling at the end of the stream
+ * @param previousWasSlashR Indicates if the last seen was a \r
+ * @return The next char to output to the stream
+ */
+ private int eofGame(final boolean previousWasSlashR) {
+ if (previousWasSlashR || !ensureLineFeedAtEndOfFile) {
+ return EOF;
}
- slashNSeen = target == LF;
- slashRSeen = target == CR;
- return target;
+ if (!slashNSeen) {
+ slashNSeen = true;
+ return LF;
+ }
+ return EOF;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void mark(final int readlimit) {
+ throw UnsupportedOperationExceptions.mark();
}
/**
@@ -92,36 +110,18 @@ public class UnixLineEndingInputStream extends InputStream {
}
/**
- * Handles the EOF-handling at the end of the stream
- * @param previousWasSlashR Indicates if the last seen was a \r
- * @return The next char to output to the stream
- */
- private int eofGame(final boolean previousWasSlashR) {
- if (previousWasSlashR || !ensureLineFeedAtEndOfFile) {
- return EOF;
- }
- if (!slashNSeen) {
- slashNSeen = true;
- return LF;
- }
- return EOF;
- }
-
- /**
- * Closes the stream. Also closes the underlying stream.
+ * Reads the next item from the target, updating internal flags in the process
+ * @return the next int read from the target stream
* @throws IOException upon error
*/
- @Override
- public void close() throws IOException {
- super.close();
- target.close();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public synchronized void mark(final int readlimit) {
- throw UnsupportedOperationExceptions.mark();
+ private int readWithUpdate() throws IOException {
+ final int target = this.target.read();
+ eofSeen = target == EOF;
+ if (eofSeen) {
+ return target;
+ }
+ slashNSeen = target == LF;
+ slashRSeen = target == CR;
+ return target;
}
}
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 0537230..4f96e2e 100644
--- a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
@@ -118,6 +118,17 @@ public class UnsynchronizedByteArrayInputStream extends InputStream {
return offset < eod ? eod - offset : 0;
}
+ @SuppressWarnings("sync-override")
+ @Override
+ public void mark(final int readlimit) {
+ this.markedOffset = this.offset;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
@Override
public int read() {
return offset < eod ? data[offset++] & 0xff : END_OF_STREAM;
@@ -152,6 +163,12 @@ public class UnsynchronizedByteArrayInputStream extends InputStream {
return actualLen;
}
+ @SuppressWarnings("sync-override")
+ @Override
+ public void reset() {
+ this.offset = this.markedOffset;
+ }
+
@Override
public long skip(final long n) {
if (n < 0) {
@@ -166,21 +183,4 @@ public class UnsynchronizedByteArrayInputStream extends InputStream {
offset += actualSkip;
return actualSkip;
}
-
- @Override
- public boolean markSupported() {
- return true;
- }
-
- @SuppressWarnings("sync-override")
- @Override
- public void mark(final int readlimit) {
- this.markedOffset = this.offset;
- }
-
- @SuppressWarnings("sync-override")
- @Override
- public void reset() {
- this.offset = this.markedOffset;
- }
}
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 921b334..bbf1797 100644
--- a/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
@@ -54,43 +54,13 @@ public class WindowsLineEndingInputStream extends InputStream {
}
/**
- * Reads the next item from the target, updating internal flags in the process
- * @return the next int read from the target stream
+ * Closes the stream. Also closes the underlying stream.
* @throws IOException upon error
*/
- private int readWithUpdate() throws IOException {
- final int target = this.target.read();
- eofSeen = target == EOF;
- if (eofSeen) {
- return target;
- }
- slashRSeen = target == CR;
- slashNSeen = target == LF;
- return target;
- }
-
- /**
- * {@inheritDoc}
- */
@Override
- public int read() throws IOException {
- if (eofSeen) {
- return eofGame();
- }
- if (injectSlashN) {
- injectSlashN = false;
- return LF;
- }
- final boolean prevWasSlashR = slashRSeen;
- final int target = readWithUpdate();
- if (eofSeen) {
- return eofGame();
- }
- if ((target == LF) && !prevWasSlashR) {
- injectSlashN = true;
- return CR;
- }
- return target;
+ public void close() throws IOException {
+ super.close();
+ target.close();
}
/**
@@ -114,20 +84,50 @@ public class WindowsLineEndingInputStream extends InputStream {
}
/**
- * Closes the stream. Also closes the underlying stream.
- * @throws IOException upon error
+ * {@inheritDoc}
*/
@Override
- public void close() throws IOException {
- super.close();
- target.close();
+ public synchronized void mark(final int readlimit) {
+ throw UnsupportedOperationExceptions.mark();
}
/**
* {@inheritDoc}
*/
@Override
- public synchronized void mark(final int readlimit) {
- throw UnsupportedOperationExceptions.mark();
+ public int read() throws IOException {
+ if (eofSeen) {
+ return eofGame();
+ }
+ if (injectSlashN) {
+ injectSlashN = false;
+ return LF;
+ }
+ final boolean prevWasSlashR = slashRSeen;
+ final int target = readWithUpdate();
+ if (eofSeen) {
+ return eofGame();
+ }
+ if ((target == LF) && !prevWasSlashR) {
+ injectSlashN = true;
+ return CR;
+ }
+ return target;
+ }
+
+ /**
+ * Reads the next item from the target, updating internal flags in the process
+ * @return the next int read from the target stream
+ * @throws IOException upon error
+ */
+ private int readWithUpdate() throws IOException {
+ final int target = this.target.read();
+ eofSeen = target == EOF;
+ if (eofSeen) {
+ return target;
+ }
+ slashRSeen = target == CR;
+ slashNSeen = target == LF;
+ return target;
}
}
diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java b/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java
index ca61be7..7570329 100644
--- a/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java
+++ b/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java
@@ -96,21 +96,15 @@ public class XmlStreamReaderException extends IOException {
}
/**
- * Returns the encoding guess based on the first bytes of the InputStream.
- *
- * @return the encoding guess, null if it couldn't be guessed.
- */
- public String getXmlGuessEncoding() {
- return xmlGuessEncoding;
- }
-
- /**
- * Returns the encoding found in the XML prolog of the InputStream.
+ * Returns the encoding in the content-type used to attempt determining the
+ * encoding.
*
- * @return the encoding of the XML prolog, null if none.
+ * @return the encoding in the content-type, null if there was not
+ * content-type, no encoding in it or the encoding detection did not
+ * involve HTTP.
*/
- public String getXmlEncoding() {
- return xmlEncoding;
+ public String getContentTypeEncoding() {
+ return contentTypeEncoding;
}
/**
@@ -125,14 +119,20 @@ public class XmlStreamReaderException extends IOException {
}
/**
- * Returns the encoding in the content-type used to attempt determining the
- * encoding.
+ * Returns the encoding found in the XML prolog of the InputStream.
*
- * @return the encoding in the content-type, null if there was not
- * content-type, no encoding in it or the encoding detection did not
- * involve HTTP.
+ * @return the encoding of the XML prolog, null if none.
*/
- public String getContentTypeEncoding() {
- return contentTypeEncoding;
+ public String getXmlEncoding() {
+ return xmlEncoding;
+ }
+
+ /**
+ * Returns the encoding guess based on the first bytes of the InputStream.
+ *
+ * @return the encoding guess, null if it couldn't be guessed.
+ */
+ public String getXmlGuessEncoding() {
+ return xmlGuessEncoding;
}
}
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 7853533..c8393a1 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
@@ -43,6 +43,16 @@ public class CircularBufferInputStream extends InputStream {
private boolean eof;
/**
+ * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size
+ * ({@link IOUtils#DEFAULT_BUFFER_SIZE}).
+ *
+ * @param inputStream The input stream, which is being buffered.
+ */
+ public CircularBufferInputStream(final InputStream inputStream) {
+ this(inputStream, IOUtils.DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
* Creates a new instance, which filters the given input stream, and uses the given buffer size.
*
* @param inputStream The input stream, which is being buffered.
@@ -58,14 +68,11 @@ public class CircularBufferInputStream extends InputStream {
this.eof = false;
}
- /**
- * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size
- * ({@link IOUtils#DEFAULT_BUFFER_SIZE}).
- *
- * @param inputStream The input stream, which is being buffered.
- */
- public CircularBufferInputStream(final InputStream inputStream) {
- this(inputStream, IOUtils.DEFAULT_BUFFER_SIZE);
+ @Override
+ public void close() throws IOException {
+ in.close();
+ eof = true;
+ buffer.clear();
}
/**
@@ -137,11 +144,4 @@ public class CircularBufferInputStream extends InputStream {
}
return result;
}
-
- @Override
- public void close() throws IOException {
- in.close();
- eof = true;
- buffer.clear();
- }
}
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 78998c3..98a4897 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
@@ -34,18 +34,6 @@ public class CircularByteBuffer {
private int currentNumberOfBytes;
/**
- * Creates a new instance with the given buffer size.
- *
- * @param size the size of buffer to create
- */
- public CircularByteBuffer(final int size) {
- buffer = IOUtils.byteArray(size);
- startOffset = 0;
- endOffset = 0;
- currentNumberOfBytes = 0;
- }
-
- /**
* Creates a new instance with a reasonable default buffer size ({@link IOUtils#DEFAULT_BUFFER_SIZE}).
*/
public CircularByteBuffer() {
@@ -53,64 +41,15 @@ public class CircularByteBuffer {
}
/**
- * Returns the next byte from the buffer, removing it at the same time, so
- * that following invocations won't return it again.
- *
- * @return The byte, which is being returned.
- * @throws IllegalStateException The buffer is empty. Use {@link #hasBytes()},
- * or {@link #getCurrentNumberOfBytes()}, to prevent this exception.
- */
- public byte read() {
- if (currentNumberOfBytes <= 0) {
- throw new IllegalStateException("No bytes available.");
- }
- final byte b = buffer[startOffset];
- --currentNumberOfBytes;
- if (++startOffset == buffer.length) {
- startOffset = 0;
- }
- return b;
- }
-
- /**
- * Returns the given number of bytes from the buffer by storing them in
- * the given byte array at the given offset.
+ * Creates a new instance with the given buffer size.
*
- * @param targetBuffer The byte array, where to add bytes.
- * @param targetOffset The offset, where to store bytes in the byte array.
- * @param length The number of bytes to return.
- * @throws NullPointerException The byte array {@code pBuffer} is null.
- * @throws IllegalArgumentException Either of {@code pOffset}, or {@code length} is negative,
- * or the length of the byte array {@code targetBuffer} is too small.
- * @throws IllegalStateException The buffer doesn't hold the given number
- * of bytes. Use {@link #getCurrentNumberOfBytes()} to prevent this
- * exception.
+ * @param size the size of buffer to create
*/
- public void read(final byte[] targetBuffer, final int targetOffset, final int length) {
- Objects.requireNonNull(targetBuffer, "targetBuffer");
- if (targetOffset < 0 || targetOffset >= targetBuffer.length) {
- throw new IllegalArgumentException("Invalid offset: " + targetOffset);
- }
- if (length < 0 || length > buffer.length) {
- throw new IllegalArgumentException("Invalid length: " + length);
- }
- if (targetOffset + length > targetBuffer.length) {
- throw new IllegalArgumentException("The supplied byte array contains only "
- + targetBuffer.length + " bytes, but offset, and length would require "
- + (targetOffset + length - 1));
- }
- if (currentNumberOfBytes < length) {
- throw new IllegalStateException("Currently, there are only " + currentNumberOfBytes
- + "in the buffer, not " + length);
- }
- int offset = targetOffset;
- for (int i = 0; i < length; i++) {
- targetBuffer[offset++] = buffer[startOffset];
- --currentNumberOfBytes;
- if (++startOffset == buffer.length) {
- startOffset = 0;
- }
- }
+ public CircularByteBuffer(final int size) {
+ buffer = IOUtils.byteArray(size);
+ startOffset = 0;
+ endOffset = 0;
+ currentNumberOfBytes = 0;
}
/**
@@ -133,44 +72,6 @@ public class CircularByteBuffer {
}
/**
- * Returns, whether the next bytes in the buffer are exactly those, given by
- * {@code sourceBuffer}, {@code offset}, and {@code length}. No bytes are being
- * 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
- * @return True, if the next invocations of {@link #read()} will return the
- * bytes at offsets {@code pOffset}+0, {@code pOffset}+1, ...,
- * {@code pOffset}+{@code length}-1 of byte array {@code pBuffer}.
- * @throws IllegalArgumentException Either of {@code pOffset}, or {@code length} is negative.
- * @throws NullPointerException The byte array {@code pBuffer} is null.
- */
- public boolean peek(final byte[] sourceBuffer, final int offset, final int length) {
- Objects.requireNonNull(sourceBuffer, "Buffer");
- if (offset < 0 || offset >= sourceBuffer.length) {
- throw new IllegalArgumentException("Invalid offset: " + offset);
- }
- if (length < 0 || length > buffer.length) {
- throw new IllegalArgumentException("Invalid length: " + length);
- }
- if (length < currentNumberOfBytes) {
- return false;
- }
- int localOffset = startOffset;
- for (int i = 0; i < length; i++) {
- if (buffer[localOffset] != sourceBuffer[i + offset]) {
- return false;
- }
- if (++localOffset == buffer.length) {
- localOffset = 0;
- }
- }
- return true;
- }
-
- /**
* Adds the given bytes to the buffer. This is the same as invoking {@link #add(byte)}
* for the bytes at offsets {@code offset+0}, {@code offset+1}, ...,
* {@code offset+length-1} of byte array {@code targetBuffer}.
@@ -204,6 +105,42 @@ public class CircularByteBuffer {
}
/**
+ * Removes all bytes from the buffer.
+ */
+ public void clear() {
+ startOffset = 0;
+ endOffset = 0;
+ currentNumberOfBytes = 0;
+ }
+
+ /**
+ * Returns the number of bytes, that are currently present in the buffer.
+ *
+ * @return the number of bytes
+ */
+ public int getCurrentNumberOfBytes() {
+ return currentNumberOfBytes;
+ }
+
+ /**
+ * Returns the number of bytes, that can currently be added to the buffer.
+ *
+ * @return the number of bytes that can be added
+ */
+ public int getSpace() {
+ return buffer.length - currentNumberOfBytes;
+ }
+
+ /**
+ * Returns, whether the buffer is currently holding, at least, a single byte.
+ *
+ * @return true if the buffer is not empty
+ */
+ public boolean hasBytes() {
+ return currentNumberOfBytes > 0;
+ }
+
+ /**
* Returns, whether there is currently room for a single byte in the buffer.
* Same as {@link #hasSpace(int) hasSpace(1)}.
*
@@ -228,38 +165,101 @@ public class CircularByteBuffer {
}
/**
- * Returns, whether the buffer is currently holding, at least, a single byte.
+ * Returns, whether the next bytes in the buffer are exactly those, given by
+ * {@code sourceBuffer}, {@code offset}, and {@code length}. No bytes are being
+ * removed from the buffer. If the result is true, then the following invocations
+ * of {@link #read()} are guaranteed to return exactly those bytes.
*
- * @return true if the buffer is not empty
+ * @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 pOffset}+0, {@code pOffset}+1, ...,
+ * {@code pOffset}+{@code length}-1 of byte array {@code pBuffer}.
+ * @throws IllegalArgumentException Either of {@code pOffset}, or {@code length} is negative.
+ * @throws NullPointerException The byte array {@code pBuffer} is null.
*/
- public boolean hasBytes() {
- return currentNumberOfBytes > 0;
+ public boolean peek(final byte[] sourceBuffer, final int offset, final int length) {
+ Objects.requireNonNull(sourceBuffer, "Buffer");
+ if (offset < 0 || offset >= sourceBuffer.length) {
+ throw new IllegalArgumentException("Invalid offset: " + offset);
+ }
+ if (length < 0 || length > buffer.length) {
+ throw new IllegalArgumentException("Invalid length: " + length);
+ }
+ if (length < currentNumberOfBytes) {
+ return false;
+ }
+ int localOffset = startOffset;
+ for (int i = 0; i < length; i++) {
+ if (buffer[localOffset] != sourceBuffer[i + offset]) {
+ return false;
+ }
+ if (++localOffset == buffer.length) {
+ localOffset = 0;
+ }
+ }
+ return true;
}
/**
- * Returns the number of bytes, that can currently be added to the buffer.
+ * Returns the next byte from the buffer, removing it at the same time, so
+ * that following invocations won't return it again.
*
- * @return the number of bytes that can be added
+ * @return The byte, which is being returned.
+ * @throws IllegalStateException The buffer is empty. Use {@link #hasBytes()},
+ * or {@link #getCurrentNumberOfBytes()}, to prevent this exception.
*/
- public int getSpace() {
- return buffer.length - currentNumberOfBytes;
+ public byte read() {
+ if (currentNumberOfBytes <= 0) {
+ throw new IllegalStateException("No bytes available.");
+ }
+ final byte b = buffer[startOffset];
+ --currentNumberOfBytes;
+ if (++startOffset == buffer.length) {
+ startOffset = 0;
+ }
+ return b;
}
/**
- * Returns the number of bytes, that are currently present in the buffer.
+ * Returns the given number of bytes from the buffer by storing them in
+ * the given byte array at the given offset.
*
- * @return the number of bytes
- */
- public int getCurrentNumberOfBytes() {
- return currentNumberOfBytes;
- }
-
- /**
- * Removes all bytes from the buffer.
+ * @param targetBuffer The byte array, where to add bytes.
+ * @param targetOffset The offset, where to store bytes in the byte array.
+ * @param length The number of bytes to return.
+ * @throws NullPointerException The byte array {@code pBuffer} is null.
+ * @throws IllegalArgumentException Either of {@code pOffset}, or {@code length} is negative,
+ * or the length of the byte array {@code targetBuffer} is too small.
+ * @throws IllegalStateException The buffer doesn't hold the given number
+ * of bytes. Use {@link #getCurrentNumberOfBytes()} to prevent this
+ * exception.
*/
- public void clear() {
- startOffset = 0;
- endOffset = 0;
- currentNumberOfBytes = 0;
+ public void read(final byte[] targetBuffer, final int targetOffset, final int length) {
+ Objects.requireNonNull(targetBuffer, "targetBuffer");
+ if (targetOffset < 0 || targetOffset >= targetBuffer.length) {
+ throw new IllegalArgumentException("Invalid offset: " + targetOffset);
+ }
+ if (length < 0 || length > buffer.length) {
+ throw new IllegalArgumentException("Invalid length: " + length);
+ }
+ if (targetOffset + length > targetBuffer.length) {
+ throw new IllegalArgumentException("The supplied byte array contains only "
+ + targetBuffer.length + " bytes, but offset, and length would require "
+ + (targetOffset + length - 1));
+ }
+ if (currentNumberOfBytes < length) {
+ throw new IllegalStateException("Currently, there are only " + currentNumberOfBytes
+ + "in the buffer, not " + length);
+ }
+ int offset = targetOffset;
+ for (int i = 0; i < length; i++) {
+ targetBuffer[offset++] = buffer[startOffset];
+ --currentNumberOfBytes;
+ if (++startOffset == buffer.length) {
+ startOffset = 0;
+ }
+ }
}
}
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 df15e70..6e9b88c 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
@@ -27,22 +27,22 @@ import java.util.Objects;
public class PeekableInputStream extends CircularBufferInputStream {
/**
- * Creates a new instance, which filters the given input stream, and uses the given buffer size.
+ * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size (8192).
*
* @param inputStream The input stream, which is being buffered.
- * @param bufferSize The size of the {@link CircularByteBuffer}, which is used internally.
*/
- public PeekableInputStream(final InputStream inputStream, final int bufferSize) {
- super(inputStream, bufferSize);
+ public PeekableInputStream(final InputStream inputStream) {
+ super(inputStream);
}
/**
- * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size (8192).
+ * Creates a new instance, which filters the given input stream, and uses the given buffer size.
*
* @param inputStream The input stream, which is being buffered.
+ * @param bufferSize The size of the {@link CircularByteBuffer}, which is used internally.
*/
- public PeekableInputStream(final InputStream inputStream) {
- super(inputStream);
+ public PeekableInputStream(final InputStream inputStream, final int bufferSize) {
+ super(inputStream, bufferSize);
}
/**
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 0d01ab4..fd3f40a 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationListener.java
@@ -29,11 +29,11 @@ import java.io.File;
public interface FileAlterationListener {
/**
- * File system observer started checking event.
+ * Directory changed Event.
*
- * @param observer The file system observer
+ * @param directory The directory changed
*/
- void onStart(final FileAlterationObserver observer);
+ void onDirectoryChange(final File directory);
/**
* Directory created Event.
@@ -43,18 +43,18 @@ public interface FileAlterationListener {
void onDirectoryCreate(final File directory);
/**
- * Directory changed Event.
+ * Directory deleted Event.
*
- * @param directory The directory changed
+ * @param directory The directory deleted
*/
- void onDirectoryChange(final File directory);
+ void onDirectoryDelete(final File directory);
/**
- * Directory deleted Event.
+ * File changed Event.
*
- * @param directory The directory deleted
+ * @param file The file changed
*/
- void onDirectoryDelete(final File directory);
+ void onFileChange(final File file);
/**
* File created Event.
@@ -64,18 +64,18 @@ public interface FileAlterationListener {
void onFileCreate(final File file);
/**
- * File changed Event.
+ * File deleted Event.
*
- * @param file The file changed
+ * @param file The file deleted
*/
- void onFileChange(final File file);
+ void onFileDelete(final File file);
/**
- * File deleted Event.
+ * File system observer started checking event.
*
- * @param file The file deleted
+ * @param observer The file system observer
*/
- void onFileDelete(final File file);
+ void onStart(final FileAlterationObserver observer);
/**
* File system observer finished checking event.
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 fa7a245..32633eb 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationListenerAdaptor.java
@@ -28,12 +28,12 @@ import java.io.File;
public class FileAlterationListenerAdaptor implements FileAlterationListener {
/**
- * File system observer started checking event.
+ * Directory changed Event.
*
- * @param observer The file system observer (ignored)
+ * @param directory The directory changed (ignored)
*/
@Override
- public void onStart(final FileAlterationObserver observer) {
+ public void onDirectoryChange(final File directory) {
// noop
}
@@ -48,22 +48,22 @@ public class FileAlterationListenerAdaptor implements FileAlterationListener {
}
/**
- * Directory changed Event.
+ * Directory deleted Event.
*
- * @param directory The directory changed (ignored)
+ * @param directory The directory deleted (ignored)
*/
@Override
- public void onDirectoryChange(final File directory) {
+ public void onDirectoryDelete(final File directory) {
// noop
}
/**
- * Directory deleted Event.
+ * File changed Event.
*
- * @param directory The directory deleted (ignored)
+ * @param file The file changed (ignored)
*/
@Override
- public void onDirectoryDelete(final File directory) {
+ public void onFileChange(final File file) {
// noop
}
@@ -78,22 +78,22 @@ public class FileAlterationListenerAdaptor implements FileAlterationListener {
}
/**
- * File changed Event.
+ * File deleted Event.
*
- * @param file The file changed (ignored)
+ * @param file The file deleted (ignored)
*/
@Override
- public void onFileChange(final File file) {
+ public void onFileDelete(final File file) {
// noop
}
/**
- * File deleted Event.
+ * File system observer started checking event.
*
- * @param file The file deleted (ignored)
+ * @param observer The file system observer (ignored)
*/
@Override
- public void onFileDelete(final File file) {
+ public void onStart(final FileAlterationObserver observer) {
// noop
}
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 126f940..df539aa 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationMonitor.java
@@ -93,32 +93,33 @@ public final class FileAlterationMonitor implements Runnable {
}
/**
- * Returns the interval.
+ * Adds a file system observer to this monitor.
*
- * @return the interval
+ * @param observer The file system observer to add
*/
- public long getInterval() {
- return intervalMillis;
+ public void addObserver(final FileAlterationObserver observer) {
+ if (observer != null) {
+ observers.add(observer);
+ }
}
/**
- * Sets the thread factory.
+ * Returns the interval.
*
- * @param threadFactory the thread factory
+ * @return the interval
*/
- public synchronized void setThreadFactory(final ThreadFactory threadFactory) {
- this.threadFactory = threadFactory;
+ public long getInterval() {
+ return intervalMillis;
}
/**
- * Adds a file system observer to this monitor.
+ * Returns the set of {@link FileAlterationObserver} registered with
+ * this monitor.
*
- * @param observer The file system observer to add
+ * @return The set of {@link FileAlterationObserver}
*/
- public void addObserver(final FileAlterationObserver observer) {
- if (observer != null) {
- observers.add(observer);
- }
+ public Iterable<FileAlterationObserver> getObservers() {
+ return observers;
}
/**
@@ -135,13 +136,32 @@ public final class FileAlterationMonitor implements Runnable {
}
/**
- * Returns the set of {@link FileAlterationObserver} registered with
- * this monitor.
+ * Runs this monitor.
+ */
+ @Override
+ public void run() {
+ while (running) {
+ for (final FileAlterationObserver observer : observers) {
+ observer.checkAndNotify();
+ }
+ if (!running) {
+ break;
+ }
+ try {
+ Thread.sleep(intervalMillis);
+ } catch (final InterruptedException ignored) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Sets the thread factory.
*
- * @return The set of {@link FileAlterationObserver}
+ * @param threadFactory the thread factory
*/
- public Iterable<FileAlterationObserver> getObservers() {
- return observers;
+ public synchronized void setThreadFactory(final ThreadFactory threadFactory) {
+ this.threadFactory = threadFactory;
}
/**
@@ -197,24 +217,4 @@ public final class FileAlterationMonitor implements Runnable {
observer.destroy();
}
}
-
- /**
- * Runs this monitor.
- */
- @Override
- public void run() {
- while (running) {
- for (final FileAlterationObserver observer : observers) {
- observer.checkAndNotify();
- }
- if (!running) {
- break;
- }
- try {
- Thread.sleep(intervalMillis);
- } catch (final InterruptedException ignored) {
- // ignore
- }
- }
- }
}
diff --git a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
index efab3cd..05f766f 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileAlterationObserver.java
@@ -130,36 +130,6 @@ public class FileAlterationObserver implements Serializable {
/**
* Constructs an observer for the specified directory.
*
- * @param directoryName the name of the directory to observe
- */
- public FileAlterationObserver(final String directoryName) {
- this(new File(directoryName));
- }
-
- /**
- * Constructs an observer for the specified directory and file filter.
- *
- * @param directoryName the name of the directory to observe
- * @param fileFilter The file filter or null if none
- */
- public FileAlterationObserver(final String directoryName, final FileFilter fileFilter) {
- this(new File(directoryName), fileFilter);
- }
-
- /**
- * Constructs an observer for the specified directory, file filter and file comparator.
- *
- * @param directoryName the name of the directory to observe
- * @param fileFilter The file filter or null if none
- * @param ioCase what case sensitivity to use comparing file names, null means system sensitive
- */
- public FileAlterationObserver(final String directoryName, final FileFilter fileFilter, final IOCase ioCase) {
- this(new File(directoryName), fileFilter, ioCase);
- }
-
- /**
- * Constructs an observer for the specified directory.
- *
* @param directory the directory to observe
*/
public FileAlterationObserver(final File directory) {
@@ -217,79 +187,47 @@ public class FileAlterationObserver implements Serializable {
}
/**
- * Returns the directory being observed.
+ * Constructs an observer for the specified directory.
*
- * @return the directory being observed
+ * @param directoryName the name of the directory to observe
*/
- public File getDirectory() {
- return rootEntry.getFile();
+ public FileAlterationObserver(final String directoryName) {
+ this(new File(directoryName));
}
/**
- * Returns the fileFilter.
+ * Constructs an observer for the specified directory and file filter.
*
- * @return the fileFilter
- * @since 2.1
+ * @param directoryName the name of the directory to observe
+ * @param fileFilter The file filter or null if none
*/
- public FileFilter getFileFilter() {
- return fileFilter;
+ public FileAlterationObserver(final String directoryName, final FileFilter fileFilter) {
+ this(new File(directoryName), fileFilter);
}
/**
- * Adds a file system listener.
+ * Constructs an observer for the specified directory, file filter and file comparator.
*
- * @param listener The file system listener
+ * @param directoryName the name of the directory to observe
+ * @param fileFilter The file filter or null if none
+ * @param ioCase what case sensitivity to use comparing file names, null means system sensitive
*/
- public void addListener(final FileAlterationListener listener) {
- if (listener != null) {
- listeners.add(listener);
- }
+ public FileAlterationObserver(final String directoryName, final FileFilter fileFilter, final IOCase ioCase) {
+ this(new File(directoryName), fileFilter, ioCase);
}
/**
- * Removes a file system listener.
+ * Adds a file system listener.
*
* @param listener The file system listener
*/
- public void removeListener(final FileAlterationListener listener) {
+ public void addListener(final FileAlterationListener listener) {
if (listener != null) {
- while (listeners.remove(listener)) {
- // empty
- }
+ listeners.add(listener);
}
}
/**
- * Returns the set of registered file system listeners.
- *
- * @return The file system listeners
- */
- public Iterable<FileAlterationListener> getListeners() {
- return listeners;
- }
-
- /**
- * Initializes the observer.
- *
- * @throws Exception if an error occurs
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- public void initialize() throws Exception {
- rootEntry.refresh(rootEntry.getFile());
- rootEntry.setChildren(doListFiles(rootEntry.getFile(), rootEntry));
- }
-
- /**
- * Final processing.
- *
- * @throws Exception if an error occurs
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- public void destroy() throws Exception {
- // noop
- }
-
- /**
* Checks whether the file and its children have been created, modified or deleted.
*/
public void checkAndNotify() {
@@ -363,18 +301,13 @@ public class FileAlterationObserver implements Serializable {
}
/**
- * Lists the files
- * @param file The file to list files for
- * @param entry the parent entry
- * @return The child files
+ * Final processing.
+ *
+ * @throws Exception if an error occurs
*/
- private FileEntry[] doListFiles(final File file, final FileEntry entry) {
- final File[] files = listFiles(file);
- final FileEntry[] children = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_FILE_ENTRY_ARRAY;
- for (int i = 0; i < files.length; i++) {
- children[i] = createFileEntry(entry, files[i]);
- }
- return children;
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ public void destroy() throws Exception {
+ // noop
}
/**
@@ -397,6 +330,36 @@ public class FileAlterationObserver implements Serializable {
}
/**
+ * Fires directory/file delete events to the registered listeners.
+ *
+ * @param entry The file entry
+ */
+ private void doDelete(final FileEntry entry) {
+ for (final FileAlterationListener listener : listeners) {
+ if (entry.isDirectory()) {
+ listener.onDirectoryDelete(entry.getFile());
+ } else {
+ listener.onFileDelete(entry.getFile());
+ }
+ }
+ }
+
+ /**
+ * Lists the files
+ * @param file The file to list files for
+ * @param entry the parent entry
+ * @return The child files
+ */
+ private FileEntry[] doListFiles(final File file, final FileEntry entry) {
+ final File[] files = listFiles(file);
+ final FileEntry[] children = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_FILE_ENTRY_ARRAY;
+ for (int i = 0; i < files.length; i++) {
+ children[i] = createFileEntry(entry, files[i]);
+ }
+ return children;
+ }
+
+ /**
* Fires directory/file change events to the registered listeners.
*
* @param entry The previous file system entry
@@ -415,18 +378,42 @@ public class FileAlterationObserver implements Serializable {
}
/**
- * Fires directory/file delete events to the registered listeners.
+ * Returns the directory being observed.
*
- * @param entry The file entry
+ * @return the directory being observed
*/
- private void doDelete(final FileEntry entry) {
- for (final FileAlterationListener listener : listeners) {
- if (entry.isDirectory()) {
- listener.onDirectoryDelete(entry.getFile());
- } else {
- listener.onFileDelete(entry.getFile());
- }
- }
+ public File getDirectory() {
+ return rootEntry.getFile();
+ }
+
+ /**
+ * Returns the fileFilter.
+ *
+ * @return the fileFilter
+ * @since 2.1
+ */
+ public FileFilter getFileFilter() {
+ return fileFilter;
+ }
+
+ /**
+ * Returns the set of registered file system listeners.
+ *
+ * @return The file system listeners
+ */
+ public Iterable<FileAlterationListener> getListeners() {
+ return listeners;
+ }
+
+ /**
+ * Initializes the observer.
+ *
+ * @throws Exception if an error occurs
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ public void initialize() throws Exception {
+ rootEntry.refresh(rootEntry.getFile());
+ rootEntry.setChildren(doListFiles(rootEntry.getFile(), rootEntry));
}
/**
@@ -451,6 +438,19 @@ public class FileAlterationObserver implements Serializable {
}
/**
+ * Removes a file system listener.
+ *
+ * @param listener The file system listener
+ */
+ public void removeListener(final FileAlterationListener listener) {
+ if (listener != null) {
+ while (listeners.remove(listener)) {
+ // empty
+ }
+ }
+ }
+
+ /**
* Returns a String representation of this observer.
*
* @return a String representation of this observer
diff --git a/src/main/java/org/apache/commons/io/monitor/FileEntry.java b/src/main/java/org/apache/commons/io/monitor/FileEntry.java
index b38f6a2..e58e76e 100644
--- a/src/main/java/org/apache/commons/io/monitor/FileEntry.java
+++ b/src/main/java/org/apache/commons/io/monitor/FileEntry.java
@@ -86,216 +86,216 @@ public class FileEntry implements Serializable {
}
/**
- * Refreshes the attributes from the {@link File}, indicating
- * whether the file has changed.
- * <p>
- * This implementation refreshes the {@code name}, {@code exists},
- * {@code directory}, {@code lastModified} and {@code length}
- * properties.
- * </p>
- * <p>
- * The {@code exists}, {@code directory}, {@code lastModified}
- * and {@code length} properties are compared for changes
- * </p>
+ * Gets the directory's files.
*
- * @param file the file instance to compare to
- * @return {@code true} if the file has changed, otherwise {@code false}
+ * @return This directory's files or an empty
+ * array if the file is not a directory or the
+ * directory is empty
*/
- public boolean refresh(final File file) {
- // cache original values
- final boolean origExists = exists;
- final FileTime origLastModified = lastModified;
- final boolean origDirectory = directory;
- final long origLength = length;
-
- // refresh the values
- name = file.getName();
- exists = Files.exists(file.toPath());
- directory = exists && file.isDirectory();
- try {
- lastModified = exists ? FileUtils.lastModifiedFileTime(file) : FileTimes.EPOCH;
- } catch (final IOException e) {
- lastModified = FileTimes.EPOCH;
- }
- length = exists && !directory ? file.length() : 0;
-
- // Return if there are changes
- return exists != origExists || !lastModified.equals(origLastModified) || directory != origDirectory
- || length != origLength;
+ public FileEntry[] getChildren() {
+ return children != null ? children : EMPTY_FILE_ENTRY_ARRAY;
}
/**
- * Creates a new child instance.
- * <p>
- * Custom implementations should override this method to return
- * a new instance of the appropriate type.
- * </p>
+ * Gets the file being monitored.
*
- * @param file The child file
- * @return a new child instance
+ * @return the file being monitored
*/
- public FileEntry newChildInstance(final File file) {
- return new FileEntry(this, file);
+ public File getFile() {
+ return file;
}
/**
- * Gets the parent entry.
+ * Gets the last modified time from the last time it
+ * was checked.
*
- * @return the parent entry
+ * @return the last modified time in milliseconds.
*/
- public FileEntry getParent() {
- return parent;
+ public long getLastModified() {
+ return lastModified.toMillis();
}
/**
- * Gets the level
+ * Gets the last modified time from the last time it was checked.
*
- * @return the level
+ * @return the last modified time.
+ * @since 2.12.0
*/
- public int getLevel() {
- return parent == null ? 0 : parent.getLevel() + 1;
+ public FileTime getLastModifiedFileTime() {
+ return lastModified;
}
/**
- * Gets the directory's files.
+ * Gets the length.
*
- * @return This directory's files or an empty
- * array if the file is not a directory or the
- * directory is empty
+ * @return the length
*/
- public FileEntry[] getChildren() {
- return children != null ? children : EMPTY_FILE_ENTRY_ARRAY;
+ public long getLength() {
+ return length;
}
/**
- * Sets the directory's files.
+ * Gets the level
*
- * @param children This directory's files, may be null
+ * @return the level
*/
- public void setChildren(final FileEntry... children) {
- this.children = children;
+ public int getLevel() {
+ return parent == null ? 0 : parent.getLevel() + 1;
}
/**
- * Gets the file being monitored.
+ * Gets the file name.
*
- * @return the file being monitored
+ * @return the file name
*/
- public File getFile() {
- return file;
+ public String getName() {
+ return name;
}
/**
- * Gets the file name.
+ * Gets the parent entry.
*
- * @return the file name
+ * @return the parent entry
*/
- public String getName() {
- return name;
+ public FileEntry getParent() {
+ return parent;
}
/**
- * Sets the file name.
+ * Tests whether the file is a directory or not.
*
- * @param name the file name
+ * @return whether the file is a directory or not
*/
- public void setName(final String name) {
- this.name = name;
+ public boolean isDirectory() {
+ return directory;
}
/**
- * Gets the last modified time from the last time it
+ * Tests whether the file existed the last time it
* was checked.
*
- * @return the last modified time in milliseconds.
+ * @return whether the file existed
*/
- public long getLastModified() {
- return lastModified.toMillis();
+ public boolean isExists() {
+ return exists;
}
/**
- * Gets the last modified time from the last time it was checked.
+ * Creates a new child instance.
+ * <p>
+ * Custom implementations should override this method to return
+ * a new instance of the appropriate type.
+ * </p>
*
- * @return the last modified time.
- * @since 2.12.0
+ * @param file The child file
+ * @return a new child instance
*/
- public FileTime getLastModifiedFileTime() {
- return lastModified;
+ public FileEntry newChildInstance(final File file) {
+ return new FileEntry(this, file);
}
/**
- * Sets the last modified time from the last time it
- * was checked.
+ * Refreshes the attributes from the {@link File}, indicating
+ * whether the file has changed.
+ * <p>
+ * This implementation refreshes the {@code name}, {@code exists},
+ * {@code directory}, {@code lastModified} and {@code length}
+ * properties.
+ * </p>
+ * <p>
+ * The {@code exists}, {@code directory}, {@code lastModified}
+ * and {@code length} properties are compared for changes
+ * </p>
*
- * @param lastModified The last modified time in milliseconds.
+ * @param file the file instance to compare to
+ * @return {@code true} if the file has changed, otherwise {@code false}
*/
- public void setLastModified(final long lastModified) {
- this.lastModified = FileTime.fromMillis(lastModified);
+ public boolean refresh(final File file) {
+ // cache original values
+ final boolean origExists = exists;
+ final FileTime origLastModified = lastModified;
+ final boolean origDirectory = directory;
+ final long origLength = length;
+
+ // refresh the values
+ name = file.getName();
+ exists = Files.exists(file.toPath());
+ directory = exists && file.isDirectory();
+ try {
+ lastModified = exists ? FileUtils.lastModifiedFileTime(file) : FileTimes.EPOCH;
+ } catch (final IOException e) {
+ lastModified = FileTimes.EPOCH;
+ }
+ length = exists && !directory ? file.length() : 0;
+
+ // Return if there are changes
+ return exists != origExists || !lastModified.equals(origLastModified) || directory != origDirectory
+ || length != origLength;
}
/**
- * Sets the last modified time from the last time it was checked.
+ * Sets the directory's files.
*
- * @param lastModified The last modified time.
- * @since 2.12.0
+ * @param children This directory's files, may be null
*/
- public void setLastModified(final FileTime lastModified) {
- this.lastModified = lastModified;
+ public void setChildren(final FileEntry... children) {
+ this.children = children;
}
/**
- * Gets the length.
+ * Sets whether the file is a directory or not.
*
- * @return the length
+ * @param directory whether the file is a directory or not
*/
- public long getLength() {
- return length;
+ public void setDirectory(final boolean directory) {
+ this.directory = directory;
}
/**
- * Sets the length.
+ * Sets whether the file existed the last time it
+ * was checked.
*
- * @param length the length
+ * @param exists whether the file exists or not
*/
- public void setLength(final long length) {
- this.length = length;
+ public void setExists(final boolean exists) {
+ this.exists = exists;
}
/**
- * Tests whether the file existed the last time it
- * was checked.
+ * Sets the last modified time from the last time it was checked.
*
- * @return whether the file existed
+ * @param lastModified The last modified time.
+ * @since 2.12.0
*/
- public boolean isExists() {
- return exists;
+ public void setLastModified(final FileTime lastModified) {
+ this.lastModified = lastModified;
}
/**
- * Sets whether the file existed the last time it
+ * Sets the last modified time from the last time it
* was checked.
*
- * @param exists whether the file exists or not
+ * @param lastModified The last modified time in milliseconds.
*/
- public void setExists(final boolean exists) {
- this.exists = exists;
+ public void setLastModified(final long lastModified) {
+ this.lastModified = FileTime.fromMillis(lastModified);
}
/**
- * Tests whether the file is a directory or not.
+ * Sets the length.
*
- * @return whether the file is a directory or not
+ * @param length the length
*/
- public boolean isDirectory() {
- return directory;
+ public void setLength(final long length) {
+ this.length = length;
}
/**
- * Sets whether the file is a directory or not.
+ * Sets the file name.
*
- * @param directory whether the file is a directory or not
+ * @param name the file name
*/
- public void setDirectory(final boolean directory) {
- this.directory = directory;
+ 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 733e025..c47cfa2 100644
--- a/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/AbstractByteArrayOutputStream.java
@@ -59,8 +59,27 @@ import org.apache.commons.io.input.ClosedInputStream;
*/
public abstract class AbstractByteArrayOutputStream extends OutputStream {
- static final int DEFAULT_SIZE = 1024;
+ /**
+ * Constructor for an InputStream subclass.
+ *
+ * @param <T> the type of the InputStream.
+ */
+ @FunctionalInterface
+ protected interface InputStreamConstructor<T extends InputStream> {
+
+ /**
+ * Constructs an InputStream subclass.
+ *
+ * @param buf the buffer
+ * @param offset the offset into the buffer
+ * @param length the length of the buffer
+ *
+ * @return the InputStream subclass.
+ */
+ T construct(final byte[] buf, final int offset, final int length);
+ }
+ static final int DEFAULT_SIZE = 1024;
/** The list of buffers, which grows and never reduces. */
private final List<byte[]> buffers = new ArrayList<>();
/** The index of the current buffer. */
@@ -71,10 +90,24 @@ public abstract class AbstractByteArrayOutputStream extends OutputStream {
private byte[] currentBuffer;
/** The total count of bytes written. */
protected int count;
+
/** Flag to indicate if the buffers can be reused after reset */
private boolean reuseBuffers = true;
/**
+ * Closing a {@code ByteArrayOutputStream} has no effect. The methods in
+ * this class can be called after the stream has been closed without
+ * generating an {@code IOException}.
+ *
+ * @throws IOException never (this method should not declare this exception
+ * but it has to now due to backwards compatibility)
+ */
+ @Override
+ public void close() throws IOException {
+ //nop
+ }
+
+ /**
* Makes a new buffer available either by allocating
* a new one or re-cycling an existing one.
*
@@ -105,120 +138,6 @@ public abstract class AbstractByteArrayOutputStream extends OutputStream {
}
/**
- * Writes the bytes to the byte array.
- * @param b the bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
- */
- @Override
- public abstract void write(final byte[] b, final int off, final int len);
-
- /**
- * Writes the bytes to the byte array.
- * @param b the bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
- */
- protected void writeImpl(final byte[] b, final int off, final int len) {
- final int newcount = count + len;
- int remaining = len;
- int inBufferPos = count - filledBufferSum;
- while (remaining > 0) {
- final int part = Math.min(remaining, currentBuffer.length - inBufferPos);
- System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
- remaining -= part;
- if (remaining > 0) {
- needNewBuffer(newcount);
- inBufferPos = 0;
- }
- }
- count = newcount;
- }
-
- /**
- * Write a byte to byte array.
- * @param b the byte to write
- */
- @Override
- public abstract void write(final int b);
-
- /**
- * Write a byte to byte array.
- * @param b the byte to write
- */
- protected void writeImpl(final int b) {
- int inBufferPos = count - filledBufferSum;
- if (inBufferPos == currentBuffer.length) {
- needNewBuffer(count + 1);
- inBufferPos = 0;
- }
- currentBuffer[inBufferPos] = (byte) b;
- count++;
- }
-
-
- /**
- * Writes the entire contents of the specified input stream to this
- * byte stream. Bytes from the input stream are read directly into the
- * internal buffers of this streams.
- *
- * @param in the input stream to read from
- * @return total number of bytes read from the input stream
- * (and written to this stream)
- * @throws IOException if an I/O error occurs while reading the input stream
- * @since 1.4
- */
- public abstract int write(final InputStream in) throws IOException;
-
- /**
- * Writes the entire contents of the specified input stream to this
- * byte stream. Bytes from the input stream are read directly into the
- * internal buffers of this streams.
- *
- * @param in the input stream to read from
- * @return total number of bytes read from the input stream
- * (and written to this stream)
- * @throws IOException if an I/O error occurs while reading the input stream
- * @since 2.7
- */
- protected int writeImpl(final InputStream in) throws IOException {
- int readCount = 0;
- int inBufferPos = count - filledBufferSum;
- int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
- while (n != EOF) {
- readCount += n;
- inBufferPos += n;
- count += n;
- if (inBufferPos == currentBuffer.length) {
- needNewBuffer(currentBuffer.length);
- inBufferPos = 0;
- }
- n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
- }
- return readCount;
- }
-
- /**
- * Returns the current size of the byte array.
- *
- * @return the current size of the byte array
- */
- public abstract int size();
-
- /**
- * Closing a {@code ByteArrayOutputStream} has no effect. The methods in
- * this class can be called after the stream has been closed without
- * generating an {@code IOException}.
- *
- * @throws IOException never (this method should not declare this exception
- * but it has to now due to backwards compatibility)
- */
- @Override
- public void close() throws IOException {
- //nop
- }
-
- /**
* @see java.io.ByteArrayOutputStream#reset()
*/
public abstract void reset();
@@ -242,34 +161,47 @@ public abstract class AbstractByteArrayOutputStream extends OutputStream {
}
}
+
/**
- * Writes the entire contents of this byte stream to the
- * specified output stream.
+ * Returns the current size of the byte array.
*
- * @param out the output stream to write to
- * @throws IOException if an I/O error occurs, such as if the stream is closed
- * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
+ * @return the current size of the byte array
*/
- public abstract void writeTo(final OutputStream out) throws IOException;
+ public abstract int size();
/**
- * Writes the entire contents of this byte stream to the
- * specified output stream.
+ * Gets the current contents of this byte stream as a byte array.
+ * The result is independent of this stream.
*
- * @param out the output stream to write to
- * @throws IOException if an I/O error occurs, such as if the stream is closed
- * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
+ * @return the current contents of this output stream, as a byte array
+ * @see java.io.ByteArrayOutputStream#toByteArray()
*/
- protected void writeToImpl(final OutputStream out) throws IOException {
+ public abstract byte[] toByteArray();
+
+ /**
+ * Gets the current contents of this byte stream as a byte array.
+ * The result is independent of this stream.
+ *
+ * @return the current contents of this output stream, as a byte array
+ * @see java.io.ByteArrayOutputStream#toByteArray()
+ */
+ protected byte[] toByteArrayImpl() {
int remaining = count;
+ if (remaining == 0) {
+ return IOUtils.EMPTY_BYTE_ARRAY;
+ }
+ final byte[] newbuf = IOUtils.byteArray(remaining);
+ int pos = 0;
for (final byte[] buf : buffers) {
final int c = Math.min(buf.length, remaining);
- out.write(buf, 0, c);
+ System.arraycopy(buf, 0, newbuf, pos, c);
+ pos += c;
remaining -= c;
if (remaining == 0) {
break;
}
}
+ return newbuf;
}
/**
@@ -320,61 +252,6 @@ public abstract class AbstractByteArrayOutputStream extends OutputStream {
}
/**
- * Constructor for an InputStream subclass.
- *
- * @param <T> the type of the InputStream.
- */
- @FunctionalInterface
- protected interface InputStreamConstructor<T extends InputStream> {
-
- /**
- * Constructs an InputStream subclass.
- *
- * @param buf the buffer
- * @param offset the offset into the buffer
- * @param length the length of the buffer
- *
- * @return the InputStream subclass.
- */
- T construct(final byte[] buf, final int offset, final int length);
- }
-
- /**
- * Gets the current contents of this byte stream as a byte array.
- * The result is independent of this stream.
- *
- * @return the current contents of this output stream, as a byte array
- * @see java.io.ByteArrayOutputStream#toByteArray()
- */
- public abstract byte[] toByteArray();
-
- /**
- * Gets the current contents of this byte stream as a byte array.
- * The result is independent of this stream.
- *
- * @return the current contents of this output stream, as a byte array
- * @see java.io.ByteArrayOutputStream#toByteArray()
- */
- protected byte[] toByteArrayImpl() {
- int remaining = count;
- if (remaining == 0) {
- return IOUtils.EMPTY_BYTE_ARRAY;
- }
- final byte[] newbuf = IOUtils.byteArray(remaining);
- int pos = 0;
- for (final byte[] buf : buffers) {
- final int c = Math.min(buf.length, remaining);
- System.arraycopy(buf, 0, newbuf, pos, c);
- pos += c;
- remaining -= c;
- if (remaining == 0) {
- break;
- }
- }
- return newbuf;
- }
-
- /**
* Gets the current contents of this byte stream as a string
* using the platform default charset.
* @return the contents of the byte array as a String
@@ -392,26 +269,149 @@ public abstract class AbstractByteArrayOutputStream extends OutputStream {
* Gets the current contents of this byte stream as a string
* using the specified encoding.
*
- * @param enc the name of the character encoding
+ * @param charset the character encoding
* @return the string converted from the byte array
- * @throws UnsupportedEncodingException if the encoding is not supported
* @see java.io.ByteArrayOutputStream#toString(String)
+ * @since 2.5
*/
- public String toString(final String enc) throws UnsupportedEncodingException {
- return new String(toByteArray(), enc);
+ public String toString(final Charset charset) {
+ return new String(toByteArray(), charset);
}
/**
* Gets the current contents of this byte stream as a string
* using the specified encoding.
*
- * @param charset the character encoding
+ * @param enc the name of the character encoding
* @return the string converted from the byte array
+ * @throws UnsupportedEncodingException if the encoding is not supported
* @see java.io.ByteArrayOutputStream#toString(String)
- * @since 2.5
*/
- public String toString(final Charset charset) {
- return new String(toByteArray(), charset);
+ public String toString(final String enc) throws UnsupportedEncodingException {
+ return new String(toByteArray(), enc);
+ }
+
+ /**
+ * Writes the bytes to the byte array.
+ * @param b the bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
+ */
+ @Override
+ public abstract void write(final byte[] b, final int off, final int len);
+
+ /**
+ * Writes the entire contents of the specified input stream to this
+ * byte stream. Bytes from the input stream are read directly into the
+ * internal buffers of this streams.
+ *
+ * @param in the input stream to read from
+ * @return total number of bytes read from the input stream
+ * (and written to this stream)
+ * @throws IOException if an I/O error occurs while reading the input stream
+ * @since 1.4
+ */
+ public abstract int write(final InputStream in) throws IOException;
+
+ /**
+ * Write a byte to byte array.
+ * @param b the byte to write
+ */
+ @Override
+ public abstract void write(final int b);
+
+ /**
+ * Writes the bytes to the byte array.
+ * @param b the bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
+ */
+ protected void writeImpl(final byte[] b, final int off, final int len) {
+ final int newcount = count + len;
+ int remaining = len;
+ int inBufferPos = count - filledBufferSum;
+ while (remaining > 0) {
+ final int part = Math.min(remaining, currentBuffer.length - inBufferPos);
+ System.arraycopy(b, off + len - remaining, currentBuffer, inBufferPos, part);
+ remaining -= part;
+ if (remaining > 0) {
+ needNewBuffer(newcount);
+ inBufferPos = 0;
+ }
+ }
+ count = newcount;
+ }
+
+ /**
+ * Writes the entire contents of the specified input stream to this
+ * byte stream. Bytes from the input stream are read directly into the
+ * internal buffers of this streams.
+ *
+ * @param in the input stream to read from
+ * @return total number of bytes read from the input stream
+ * (and written to this stream)
+ * @throws IOException if an I/O error occurs while reading the input stream
+ * @since 2.7
+ */
+ protected int writeImpl(final InputStream in) throws IOException {
+ int readCount = 0;
+ int inBufferPos = count - filledBufferSum;
+ int n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
+ while (n != EOF) {
+ readCount += n;
+ inBufferPos += n;
+ count += n;
+ if (inBufferPos == currentBuffer.length) {
+ needNewBuffer(currentBuffer.length);
+ inBufferPos = 0;
+ }
+ n = in.read(currentBuffer, inBufferPos, currentBuffer.length - inBufferPos);
+ }
+ return readCount;
+ }
+
+ /**
+ * Write a byte to byte array.
+ * @param b the byte to write
+ */
+ protected void writeImpl(final int b) {
+ int inBufferPos = count - filledBufferSum;
+ if (inBufferPos == currentBuffer.length) {
+ needNewBuffer(count + 1);
+ inBufferPos = 0;
+ }
+ currentBuffer[inBufferPos] = (byte) b;
+ count++;
+ }
+
+ /**
+ * Writes the entire contents of this byte stream to the
+ * specified output stream.
+ *
+ * @param out the output stream to write to
+ * @throws IOException if an I/O error occurs, such as if the stream is closed
+ * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
+ */
+ public abstract void writeTo(final OutputStream out) throws IOException;
+
+ /**
+ * Writes the entire contents of this byte stream to the
+ * specified output stream.
+ *
+ * @param out the output stream to write to
+ * @throws IOException if an I/O error occurs, such as if the stream is closed
+ * @see java.io.ByteArrayOutputStream#writeTo(OutputStream)
+ */
+ protected void writeToImpl(final OutputStream out) throws IOException {
+ int remaining = count;
+ for (final byte[] buf : buffers) {
+ final int c = Math.min(buf.length, remaining);
+ out.write(buf, 0, c);
+ remaining -= c;
+ if (remaining == 0) {
+ break;
+ }
+ }
}
}
diff --git a/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java b/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java
index 50bb8e1..5d1852d 100644
--- a/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/AppendableOutputStream.java
@@ -46,6 +46,15 @@ public class AppendableOutputStream <T extends Appendable> extends OutputStream
}
/**
+ * Return the target appendable.
+ *
+ * @return the target appendable
+ */
+ public T getAppendable() {
+ return appendable;
+ }
+
+ /**
* Write a character to the underlying appendable.
*
* @param b the character to write
@@ -56,13 +65,4 @@ public class AppendableOutputStream <T extends Appendable> extends OutputStream
appendable.append((char)b);
}
- /**
- * Return the target appendable.
- *
- * @return the target appendable
- */
- public T getAppendable() {
- return appendable;
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
index 70befe2..4c4ec40 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
@@ -37,6 +37,13 @@ public class BrokenOutputStream extends OutputStream {
private final IOException exception;
/**
+ * Creates a new stream that always throws an {@link IOException}
+ */
+ public BrokenOutputStream() {
+ this(new IOException("Broken output stream"));
+ }
+
+ /**
* Creates a new stream that always throws the given exception.
*
* @param exception the exception to be thrown
@@ -46,20 +53,12 @@ public class BrokenOutputStream extends OutputStream {
}
/**
- * Creates a new stream that always throws an {@link IOException}
- */
- public BrokenOutputStream() {
- this(new IOException("Broken output stream"));
- }
-
- /**
* Throws the configured exception.
*
- * @param b ignored
* @throws IOException always thrown
*/
@Override
- public void write(final int b) throws IOException {
+ public void close() throws IOException {
throw exception;
}
@@ -76,10 +75,11 @@ public class BrokenOutputStream extends OutputStream {
/**
* Throws the configured exception.
*
+ * @param b ignored
* @throws IOException always thrown
*/
@Override
- public void close() throws IOException {
+ public void write(final int b) throws IOException {
throw exception;
}
diff --git a/src/main/java/org/apache/commons/io/output/BrokenWriter.java b/src/main/java/org/apache/commons/io/output/BrokenWriter.java
index f2b659b..d49eff3 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenWriter.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenWriter.java
@@ -42,6 +42,13 @@ public class BrokenWriter extends Writer {
private final IOException exception;
/**
+ * Creates a new writer that always throws an {@link IOException}
+ */
+ public BrokenWriter() {
+ this(new IOException("Broken writer"));
+ }
+
+ /**
* Creates a new writer that always throws the given exception.
*
* @param exception the exception to be thrown
@@ -51,22 +58,12 @@ public class BrokenWriter extends Writer {
}
/**
- * Creates a new writer that always throws an {@link IOException}
- */
- public BrokenWriter() {
- this(new IOException("Broken writer"));
- }
-
- /**
* Throws the configured exception.
*
- * @param cbuf ignored
- * @param off ignored
- * @param len ignored
* @throws IOException always thrown
*/
@Override
- public void write(final char[] cbuf, final int off, final int len) throws IOException {
+ public void close() throws IOException {
throw exception;
}
@@ -83,10 +80,13 @@ public class BrokenWriter extends Writer {
/**
* Throws the configured exception.
*
+ * @param cbuf ignored
+ * @param off ignored
+ * @param len ignored
* @throws IOException always thrown
*/
@Override
- public void close() throws IOException {
+ public void write(final char[] cbuf, final int off, final int len) throws IOException {
throw exception;
}
diff --git a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java
index 7032004..f5ecca5 100644
--- a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java
@@ -27,76 +27,6 @@ import java.io.OutputStream;
public class ByteArrayOutputStream extends AbstractByteArrayOutputStream {
/**
- * Creates a new byte array output stream. The buffer capacity is
- * initially {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary.
- */
- public ByteArrayOutputStream() {
- this(DEFAULT_SIZE);
- }
-
- /**
- * Creates a new byte array output stream, with a buffer capacity of
- * the specified size, in bytes.
- *
- * @param size the initial size
- * @throws IllegalArgumentException if size is negative
- */
- public ByteArrayOutputStream(final int size) {
- if (size < 0) {
- throw new IllegalArgumentException(
- "Negative initial size: " + size);
- }
- synchronized (this) {
- needNewBuffer(size);
- }
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len) {
- if ((off < 0)
- || (off > b.length)
- || (len < 0)
- || ((off + len) > b.length)
- || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException();
- }
- if (len == 0) {
- return;
- }
- synchronized (this) {
- writeImpl(b, off, len);
- }
- }
-
- @Override
- public synchronized void write(final int b) {
- writeImpl(b);
- }
-
- @Override
- public synchronized int write(final InputStream in) throws IOException {
- return writeImpl(in);
- }
-
- @Override
- public synchronized int size() {
- return count;
- }
-
- /**
- * @see java.io.ByteArrayOutputStream#reset()
- */
- @Override
- public synchronized void reset() {
- resetImpl();
- }
-
- @Override
- public synchronized void writeTo(final OutputStream out) throws IOException {
- writeToImpl(out);
- }
-
- /**
* Fetches entire contents of an {@code InputStream} and represent
* same data as result InputStream.
* <p>
@@ -154,13 +84,83 @@ public class ByteArrayOutputStream extends AbstractByteArrayOutputStream {
}
}
+ /**
+ * Creates a new byte array output stream. The buffer capacity is
+ * initially {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary.
+ */
+ public ByteArrayOutputStream() {
+ this(DEFAULT_SIZE);
+ }
+
+ /**
+ * Creates a new byte array output stream, with a buffer capacity of
+ * the specified size, in bytes.
+ *
+ * @param size the initial size
+ * @throws IllegalArgumentException if size is negative
+ */
+ public ByteArrayOutputStream(final int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException(
+ "Negative initial size: " + size);
+ }
+ synchronized (this) {
+ needNewBuffer(size);
+ }
+ }
+
+ /**
+ * @see java.io.ByteArrayOutputStream#reset()
+ */
@Override
- public synchronized InputStream toInputStream() {
- return toInputStream(java.io.ByteArrayInputStream::new);
+ public synchronized void reset() {
+ resetImpl();
+ }
+
+ @Override
+ public synchronized int size() {
+ return count;
}
@Override
public synchronized byte[] toByteArray() {
return toByteArrayImpl();
}
+
+ @Override
+ public synchronized InputStream toInputStream() {
+ return toInputStream(java.io.ByteArrayInputStream::new);
+ }
+
+ @Override
+ public void write(final byte[] b, final int off, final int len) {
+ if ((off < 0)
+ || (off > b.length)
+ || (len < 0)
+ || ((off + len) > b.length)
+ || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (len == 0) {
+ return;
+ }
+ synchronized (this) {
+ writeImpl(b, off, len);
+ }
+ }
+
+ @Override
+ public synchronized int write(final InputStream in) throws IOException {
+ return writeImpl(in);
+ }
+
+ @Override
+ public synchronized void write(final int b) {
+ writeImpl(b);
+ }
+
+ @Override
+ public synchronized void writeTo(final OutputStream out) throws IOException {
+ writeToImpl(out);
+ }
}
diff --git a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
index 394b84e..e319454 100644
--- a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java
@@ -40,6 +40,15 @@ public class ChunkedOutputStream extends FilterOutputStream {
private final int chunkSize;
/**
+ * Creates a new stream that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE}.
+ *
+ * @param stream the stream to wrap
+ */
+ public ChunkedOutputStream(final OutputStream stream) {
+ this(stream, DEFAULT_CHUNK_SIZE);
+ }
+
+ /**
* Creates a new stream that uses the specified chunk size.
*
* @param stream the stream to wrap
@@ -55,15 +64,6 @@ public class ChunkedOutputStream extends FilterOutputStream {
}
/**
- * Creates a new stream that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE}.
- *
- * @param stream the stream to wrap
- */
- public ChunkedOutputStream(final OutputStream stream) {
- this(stream, DEFAULT_CHUNK_SIZE);
- }
-
- /**
* Writes the data buffer in chunks to the underlying stream
*
* @param data the data to write
diff --git a/src/main/java/org/apache/commons/io/output/ChunkedWriter.java b/src/main/java/org/apache/commons/io/output/ChunkedWriter.java
index 7b9a16a..409c78e 100644
--- a/src/main/java/org/apache/commons/io/output/ChunkedWriter.java
+++ b/src/main/java/org/apache/commons/io/output/ChunkedWriter.java
@@ -40,6 +40,14 @@ public class ChunkedWriter extends FilterWriter {
private final int chunkSize;
/**
+ * Creates a new writer that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE}
+ * @param writer the writer to wrap
+ */
+ public ChunkedWriter(final Writer writer) {
+ this(writer, DEFAULT_CHUNK_SIZE);
+ }
+
+ /**
* Creates a new writer that uses the specified chunk size.
*
* @param writer the writer to wrap
@@ -55,14 +63,6 @@ public class ChunkedWriter extends FilterWriter {
}
/**
- * Creates a new writer that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE}
- * @param writer the writer to wrap
- */
- public ChunkedWriter(final Writer writer) {
- this(writer, DEFAULT_CHUNK_SIZE);
- }
-
- /**
* writes the data buffer in chunks to the underlying writer
* @param data The data
* @param srcOffset the offset
diff --git a/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java b/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java
index 051d145..8050e46 100644
--- a/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ClosedOutputStream.java
@@ -48,21 +48,21 @@ public class ClosedOutputStream extends OutputStream {
/**
* Throws an {@link IOException} to indicate that the stream is closed.
*
- * @param b ignored
* @throws IOException always thrown
*/
@Override
- public void write(final int b) throws IOException {
- throw new IOException("write(" + b + ") failed: stream is closed");
+ public void flush() throws IOException {
+ throw new IOException("flush() failed: stream is closed");
}
/**
* Throws an {@link IOException} to indicate that the stream is closed.
*
+ * @param b ignored
* @throws IOException always thrown
*/
@Override
- public void flush() throws IOException {
- throw new IOException("flush() failed: stream is closed");
+ public void write(final int b) throws IOException {
+ throw new IOException("write(" + b + ") failed: stream is closed");
}
}
diff --git a/src/main/java/org/apache/commons/io/output/CountingOutputStream.java b/src/main/java/org/apache/commons/io/output/CountingOutputStream.java
index 486b789..78506eb 100644
--- a/src/main/java/org/apache/commons/io/output/CountingOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/CountingOutputStream.java
@@ -56,33 +56,29 @@ public class CountingOutputStream extends ProxyOutputStream {
/**
* The number of bytes that have passed through this stream.
* <p>
- * NOTE: From v1.3 this method throws an ArithmeticException if the
- * count is greater than can be expressed by an {@code int}.
- * See {@link #getByteCount()} for a method using a {@code long}.
+ * NOTE: This method is an alternative for {@code getCount()}.
+ * It was added because that method returns an integer which will
+ * result in incorrect count for files over 2GB.
*
* @return the number of bytes accumulated
- * @throws ArithmeticException if the byte count is too large
+ * @since 1.3
*/
- public int getCount() {
- final long result = getByteCount();
- if (result > Integer.MAX_VALUE) {
- throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
- }
- return (int) result;
+ public synchronized long getByteCount() {
+ return this.count;
}
/**
- * Set the byte count back to 0.
+ * The number of bytes that have passed through this stream.
* <p>
* NOTE: From v1.3 this method throws an ArithmeticException if the
* count is greater than can be expressed by an {@code int}.
- * See {@link #resetByteCount()} for a method using a {@code long}.
+ * See {@link #getByteCount()} for a method using a {@code long}.
*
- * @return the count previous to resetting
+ * @return the number of bytes accumulated
* @throws ArithmeticException if the byte count is too large
*/
- public int resetCount() {
- final long result = resetByteCount();
+ public int getCount() {
+ final long result = getByteCount();
if (result > Integer.MAX_VALUE) {
throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
}
@@ -90,33 +86,37 @@ public class CountingOutputStream extends ProxyOutputStream {
}
/**
- * The number of bytes that have passed through this stream.
+ * Set the byte count back to 0.
* <p>
- * NOTE: This method is an alternative for {@code getCount()}.
+ * NOTE: This method is an alternative for {@code resetCount()}.
* It was added because that method returns an integer which will
* result in incorrect count for files over 2GB.
*
- * @return the number of bytes accumulated
+ * @return the count previous to resetting
* @since 1.3
*/
- public synchronized long getByteCount() {
- return this.count;
+ public synchronized long resetByteCount() {
+ final long tmp = this.count;
+ this.count = 0;
+ return tmp;
}
/**
* Set the byte count back to 0.
* <p>
- * NOTE: This method is an alternative for {@code resetCount()}.
- * It was added because that method returns an integer which will
- * result in incorrect count for files over 2GB.
+ * NOTE: From v1.3 this method throws an ArithmeticException if the
+ * count is greater than can be expressed by an {@code int}.
+ * See {@link #resetByteCount()} for a method using a {@code long}.
*
* @return the count previous to resetting
- * @since 1.3
+ * @throws ArithmeticException if the byte count is too large
*/
- public synchronized long resetByteCount() {
- final long tmp = this.count;
- this.count = 0;
- return tmp;
+ public int resetCount() {
+ final long result = resetByteCount();
+ if (result > Integer.MAX_VALUE) {
+ throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
+ }
+ return (int) result;
}
}
diff --git a/src/main/java/org/apache/commons/io/output/NullOutputStream.java b/src/main/java/org/apache/commons/io/output/NullOutputStream.java
index b9cac75..0fd2a53 100644
--- a/src/main/java/org/apache/commons/io/output/NullOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/NullOutputStream.java
@@ -28,17 +28,6 @@ import java.io.OutputStream;
public class NullOutputStream extends OutputStream {
/**
- * Deprecated in favor of {@link #NULL_OUTPUT_STREAM}.
- *
- * TODO: Will be private in 3.0.
- *
- * @deprecated Use {@link #NULL_OUTPUT_STREAM}.
- */
- @Deprecated
- public NullOutputStream() {
- }
-
- /**
* The singleton instance.
*
* @since 2.12.0
@@ -54,35 +43,46 @@ public class NullOutputStream extends OutputStream {
public static final NullOutputStream NULL_OUTPUT_STREAM = INSTANCE;
/**
+ * Deprecated in favor of {@link #NULL_OUTPUT_STREAM}.
+ *
+ * TODO: Will be private in 3.0.
+ *
+ * @deprecated Use {@link #NULL_OUTPUT_STREAM}.
+ */
+ @Deprecated
+ public NullOutputStream() {
+ }
+
+ /**
* Does nothing - output to {@code /dev/null}.
*
* @param b The bytes to write
- * @param off The start offset
- * @param len The number of bytes to write
+ * @throws IOException never
*/
@Override
- public void write(final byte[] b, final int off, final int len) {
+ public void write(final byte[] b) throws IOException {
// To /dev/null
}
/**
* Does nothing - output to {@code /dev/null}.
*
- * @param b The byte to write
+ * @param b The bytes to write
+ * @param off The start offset
+ * @param len The number of bytes to write
*/
@Override
- public void write(final int b) {
+ public void write(final byte[] b, final int off, final int len) {
// To /dev/null
}
/**
* Does nothing - output to {@code /dev/null}.
*
- * @param b The bytes to write
- * @throws IOException never
+ * @param b The byte to write
*/
@Override
- public void write(final byte[] b) throws IOException {
+ public void write(final int b) {
// To /dev/null
}
diff --git a/src/main/java/org/apache/commons/io/output/NullWriter.java b/src/main/java/org/apache/commons/io/output/NullWriter.java
index ccfccc5..602763b 100644
--- a/src/main/java/org/apache/commons/io/output/NullWriter.java
+++ b/src/main/java/org/apache/commons/io/output/NullWriter.java
@@ -62,13 +62,11 @@ public class NullWriter extends Writer {
/**
* Does nothing - output to {@code /dev/null}.
* @param csq The character sequence to write
- * @param start The index of the first character to write
- * @param end The index of the first character to write (exclusive)
* @return this writer
* @since 2.0
*/
@Override
- public Writer append(final CharSequence csq, final int start, final int end) {
+ public Writer append(final CharSequence csq) {
//to /dev/null
return this;
}
@@ -76,21 +74,26 @@ public class NullWriter extends Writer {
/**
* Does nothing - output to {@code /dev/null}.
* @param csq The character sequence to write
+ * @param start The index of the first character to write
+ * @param end The index of the first character to write (exclusive)
* @return this writer
* @since 2.0
*/
@Override
- public Writer append(final CharSequence csq) {
+ public Writer append(final CharSequence csq, final int start, final int end) {
//to /dev/null
return this;
}
- /**
- * Does nothing - output to {@code /dev/null}.
- * @param idx The character to write
- */
+ /** @see java.io.Writer#close() */
@Override
- public void write(final int idx) {
+ public void close() {
+ //to /dev/null
+ }
+
+ /** @see java.io.Writer#flush() */
+ @Override
+ public void flush() {
//to /dev/null
}
@@ -116,6 +119,15 @@ public class NullWriter extends Writer {
/**
* Does nothing - output to {@code /dev/null}.
+ * @param idx The character to write
+ */
+ @Override
+ public void write(final int idx) {
+ //to /dev/null
+ }
+
+ /**
+ * Does nothing - output to {@code /dev/null}.
* @param str The string to write
*/
@Override
@@ -134,16 +146,4 @@ public class NullWriter extends Writer {
//to /dev/null
}
- /** @see java.io.Writer#flush() */
- @Override
- public void flush() {
- //to /dev/null
- }
-
- /** @see java.io.Writer#close() */
- @Override
- public void close() {
- //to /dev/null
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/ProxyOutputStream.java b/src/main/java/org/apache/commons/io/output/ProxyOutputStream.java
index 1679114..cc60832 100644
--- a/src/main/java/org/apache/commons/io/output/ProxyOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/ProxyOutputStream.java
@@ -46,22 +46,78 @@ public class ProxyOutputStream extends FilterOutputStream {
}
/**
- * Invokes the delegate's {@code write(int)} method.
- * @param idx the byte to write
+ * Invoked by the write methods after the proxied call has returned
+ * successfully. The number of bytes written (1 for the
+ * {@link #write(int)} method, buffer length for {@link #write(byte[])},
+ * etc.) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common post-processing
+ * functionality without having to override all the write methods.
+ * The default implementation does nothing.
+ *
+ * @since 2.0
+ * @param n number of bytes written
+ * @throws IOException if the post-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void afterWrite(final int n) throws IOException {
+ // noop
+ }
+
+ /**
+ * Invoked by the write methods before the call is proxied. The number
+ * of bytes to be written (1 for the {@link #write(int)} method, buffer
+ * length for {@link #write(byte[])}, etc.) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common pre-processing
+ * functionality without having to override all the write methods.
+ * The default implementation does nothing.
+ *
+ * @since 2.0
+ * @param n number of bytes to be written
+ * @throws IOException if the pre-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void beforeWrite(final int n) throws IOException {
+ // noop
+ }
+
+ /**
+ * Invokes the delegate's {@code close()} method.
* @throws IOException if an I/O error occurs.
*/
@Override
- public void write(final int idx) throws IOException {
+ public void close() throws IOException {
+ IOUtils.close(out, this::handleIOException);
+ }
+
+ /**
+ * Invokes the delegate's {@code flush()} method.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
try {
- beforeWrite(1);
- out.write(idx);
- afterWrite(1);
+ out.flush();
} catch (final IOException e) {
handleIOException(e);
}
}
/**
+ * Handle any IOExceptions thrown.
+ * <p>
+ * This method provides a point to implement custom exception
+ * handling. The default behavior is to re-throw the exception.
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ * @since 2.0
+ */
+ protected void handleIOException(final IOException e) throws IOException {
+ throw e;
+ }
+
+ /**
* Invokes the delegate's {@code write(byte[])} method.
* @param bts the bytes to write
* @throws IOException if an I/O error occurs.
@@ -97,75 +153,19 @@ public class ProxyOutputStream extends FilterOutputStream {
}
/**
- * Invokes the delegate's {@code flush()} method.
+ * Invokes the delegate's {@code write(int)} method.
+ * @param idx the byte to write
* @throws IOException if an I/O error occurs.
*/
@Override
- public void flush() throws IOException {
+ public void write(final int idx) throws IOException {
try {
- out.flush();
+ beforeWrite(1);
+ out.write(idx);
+ afterWrite(1);
} catch (final IOException e) {
handleIOException(e);
}
}
- /**
- * Invokes the delegate's {@code close()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- IOUtils.close(out, this::handleIOException);
- }
-
- /**
- * Invoked by the write methods before the call is proxied. The number
- * of bytes to be written (1 for the {@link #write(int)} method, buffer
- * length for {@link #write(byte[])}, etc.) is given as an argument.
- * <p>
- * Subclasses can override this method to add common pre-processing
- * functionality without having to override all the write methods.
- * The default implementation does nothing.
- *
- * @since 2.0
- * @param n number of bytes to be written
- * @throws IOException if the pre-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void beforeWrite(final int n) throws IOException {
- // noop
- }
-
- /**
- * Invoked by the write methods after the proxied call has returned
- * successfully. The number of bytes written (1 for the
- * {@link #write(int)} method, buffer length for {@link #write(byte[])},
- * etc.) is given as an argument.
- * <p>
- * Subclasses can override this method to add common post-processing
- * functionality without having to override all the write methods.
- * The default implementation does nothing.
- *
- * @since 2.0
- * @param n number of bytes written
- * @throws IOException if the post-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void afterWrite(final int n) throws IOException {
- // noop
- }
-
- /**
- * Handle any IOExceptions thrown.
- * <p>
- * This method provides a point to implement custom exception
- * handling. The default behavior is to re-throw the exception.
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- * @since 2.0
- */
- protected void handleIOException(final IOException e) throws IOException {
- throw e;
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/ProxyWriter.java b/src/main/java/org/apache/commons/io/output/ProxyWriter.java
index 1d50e97..8dd1549 100644
--- a/src/main/java/org/apache/commons/io/output/ProxyWriter.java
+++ b/src/main/java/org/apache/commons/io/output/ProxyWriter.java
@@ -41,6 +41,26 @@ public class ProxyWriter extends FilterWriter {
}
/**
+ * Invoked by the write methods after the proxied call has returned
+ * successfully. The number of chars written (1 for the
+ * {@link #write(int)} method, buffer length for {@link #write(char[])},
+ * etc.) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common post-processing
+ * functionality without having to override all the write methods.
+ * The default implementation does nothing.
+ * </p>
+ *
+ * @since 2.0
+ * @param n number of chars written
+ * @throws IOException if the post-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void afterWrite(final int n) throws IOException {
+ // noop
+ }
+
+ /**
* Invokes the delegate's {@code append(char)} method.
* @param c The character to write
* @return this writer
@@ -60,20 +80,19 @@ public class ProxyWriter extends FilterWriter {
}
/**
- * Invokes the delegate's {@code append(CharSequence, int, int)} method.
+ * Invokes the delegate's {@code append(CharSequence)} method.
* @param csq The character sequence to write
- * @param start The index of the first character to write
- * @param end The index of the first character to write (exclusive)
* @return this writer
* @throws IOException if an I/O error occurs.
* @since 2.0
*/
@Override
- public Writer append(final CharSequence csq, final int start, final int end) throws IOException {
+ public Writer append(final CharSequence csq) throws IOException {
try {
- beforeWrite(end - start);
- out.append(csq, start, end);
- afterWrite(end - start);
+ final int len = IOUtils.length(csq);
+ beforeWrite(len);
+ out.append(csq);
+ afterWrite(len);
} catch (final IOException e) {
handleIOException(e);
}
@@ -81,19 +100,20 @@ public class ProxyWriter extends FilterWriter {
}
/**
- * Invokes the delegate's {@code append(CharSequence)} method.
+ * Invokes the delegate's {@code append(CharSequence, int, int)} method.
* @param csq The character sequence to write
+ * @param start The index of the first character to write
+ * @param end The index of the first character to write (exclusive)
* @return this writer
* @throws IOException if an I/O error occurs.
* @since 2.0
*/
@Override
- public Writer append(final CharSequence csq) throws IOException {
+ public Writer append(final CharSequence csq, final int start, final int end) throws IOException {
try {
- final int len = IOUtils.length(csq);
- beforeWrite(len);
- out.append(csq);
- afterWrite(len);
+ beforeWrite(end - start);
+ out.append(csq, start, end);
+ afterWrite(end - start);
} catch (final IOException e) {
handleIOException(e);
}
@@ -101,22 +121,62 @@ public class ProxyWriter extends FilterWriter {
}
/**
- * Invokes the delegate's {@code write(int)} method.
- * @param c the character to write
+ * Invoked by the write methods before the call is proxied. The number
+ * of chars to be written (1 for the {@link #write(int)} method, buffer
+ * length for {@link #write(char[])}, etc.) is given as an argument.
+ * <p>
+ * Subclasses can override this method to add common pre-processing
+ * functionality without having to override all the write methods.
+ * The default implementation does nothing.
+ * </p>
+ *
+ * @since 2.0
+ * @param n number of chars to be written
+ * @throws IOException if the pre-processing fails
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void beforeWrite(final int n) throws IOException {
+ // noop
+ }
+
+ /**
+ * Invokes the delegate's {@code close()} method.
* @throws IOException if an I/O error occurs.
*/
@Override
- public void write(final int c) throws IOException {
+ public void close() throws IOException {
+ IOUtils.close(out, this::handleIOException);
+ }
+
+ /**
+ * Invokes the delegate's {@code flush()} method.
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
try {
- beforeWrite(1);
- out.write(c);
- afterWrite(1);
+ out.flush();
} catch (final IOException e) {
handleIOException(e);
}
}
/**
+ * Handle any IOExceptions thrown.
+ * <p>
+ * This method provides a point to implement custom exception
+ * handling. The default behavior is to re-throw the exception.
+ * </p>
+ *
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ * @since 2.0
+ */
+ protected void handleIOException(final IOException e) throws IOException {
+ throw e;
+ }
+
+ /**
* Invokes the delegate's {@code write(char[])} method.
* @param cbuf the characters to write
* @throws IOException if an I/O error occurs.
@@ -152,6 +212,22 @@ public class ProxyWriter extends FilterWriter {
}
/**
+ * Invokes the delegate's {@code write(int)} method.
+ * @param c the character to write
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void write(final int c) throws IOException {
+ try {
+ beforeWrite(1);
+ out.write(c);
+ afterWrite(1);
+ } catch (final IOException e) {
+ handleIOException(e);
+ }
+ }
+
+ /**
* Invokes the delegate's {@code write(String)} method.
* @param str the string to write
* @throws IOException if an I/O error occurs.
@@ -186,80 +262,4 @@ public class ProxyWriter extends FilterWriter {
}
}
- /**
- * Invokes the delegate's {@code flush()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void flush() throws IOException {
- try {
- out.flush();
- } catch (final IOException e) {
- handleIOException(e);
- }
- }
-
- /**
- * Invokes the delegate's {@code close()} method.
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- IOUtils.close(out, this::handleIOException);
- }
-
- /**
- * Invoked by the write methods before the call is proxied. The number
- * of chars to be written (1 for the {@link #write(int)} method, buffer
- * length for {@link #write(char[])}, etc.) is given as an argument.
- * <p>
- * Subclasses can override this method to add common pre-processing
- * functionality without having to override all the write methods.
- * The default implementation does nothing.
- * </p>
- *
- * @since 2.0
- * @param n number of chars to be written
- * @throws IOException if the pre-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void beforeWrite(final int n) throws IOException {
- // noop
- }
-
- /**
- * Invoked by the write methods after the proxied call has returned
- * successfully. The number of chars written (1 for the
- * {@link #write(int)} method, buffer length for {@link #write(char[])},
- * etc.) is given as an argument.
- * <p>
- * Subclasses can override this method to add common post-processing
- * functionality without having to override all the write methods.
- * The default implementation does nothing.
- * </p>
- *
- * @since 2.0
- * @param n number of chars written
- * @throws IOException if the post-processing fails
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void afterWrite(final int n) throws IOException {
- // noop
- }
-
- /**
- * Handle any IOExceptions thrown.
- * <p>
- * This method provides a point to implement custom exception
- * handling. The default behavior is to re-throw the exception.
- * </p>
- *
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- * @since 2.0
- */
- protected void handleIOException(final IOException e) throws IOException {
- throw e;
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java b/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java
index 261714e..bd9530d 100644
--- a/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java
+++ b/src/main/java/org/apache/commons/io/output/StringBuilderWriter.java
@@ -119,15 +119,22 @@ public class StringBuilderWriter extends Writer implements Serializable {
/**
- * Writes a String to the {@link StringBuilder}.
+ * Returns the underlying builder.
*
- * @param value The value to write
+ * @return The underlying builder
+ */
+ public StringBuilder getBuilder() {
+ return builder;
+ }
+
+ /**
+ * Returns {@link StringBuilder#toString()}.
+ *
+ * @return The contents of the String builder.
*/
@Override
- public void write(final String value) {
- if (value != null) {
- builder.append(value);
- }
+ public String toString() {
+ return builder.toString();
}
/**
@@ -145,21 +152,14 @@ public class StringBuilderWriter extends Writer implements Serializable {
}
/**
- * Returns the underlying builder.
- *
- * @return The underlying builder
- */
- public StringBuilder getBuilder() {
- return builder;
- }
-
- /**
- * Returns {@link StringBuilder#toString()}.
+ * Writes a String to the {@link StringBuilder}.
*
- * @return The contents of the String builder.
+ * @param value The value to write
*/
@Override
- public String toString() {
- return builder.toString();
+ public void write(final String value) {
+ if (value != null) {
+ builder.append(value);
+ }
}
}
diff --git a/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java b/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java
index 50f373f..eeb23a0 100644
--- a/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java
@@ -79,6 +79,17 @@ public class TaggedOutputStream extends ProxyOutputStream {
}
/**
+ * Tags any IOExceptions thrown, wrapping and re-throwing.
+ *
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ protected void handleIOException(final IOException e) throws IOException {
+ throw new TaggedIOException(e, tag);
+ }
+
+ /**
* Tests if the given exception was caused by this stream.
*
* @param exception an exception
@@ -103,15 +114,4 @@ public class TaggedOutputStream extends ProxyOutputStream {
TaggedIOException.throwCauseIfTaggedWith(exception, tag);
}
- /**
- * Tags any IOExceptions thrown, wrapping and re-throwing.
- *
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- */
- @Override
- protected void handleIOException(final IOException e) throws IOException {
- throw new TaggedIOException(e, tag);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/TaggedWriter.java b/src/main/java/org/apache/commons/io/output/TaggedWriter.java
index 00f9f03..eb6f79d 100644
--- a/src/main/java/org/apache/commons/io/output/TaggedWriter.java
+++ b/src/main/java/org/apache/commons/io/output/TaggedWriter.java
@@ -79,6 +79,17 @@ public class TaggedWriter extends ProxyWriter {
}
/**
+ * Tags any IOExceptions thrown, wrapping and re-throwing.
+ *
+ * @param e The IOException thrown
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ protected void handleIOException(final IOException e) throws IOException {
+ throw new TaggedIOException(e, tag);
+ }
+
+ /**
* Tests if the given exception was caused by this writer.
*
* @param exception an exception
@@ -103,15 +114,4 @@ public class TaggedWriter extends ProxyWriter {
TaggedIOException.throwCauseIfTaggedWith(exception, tag);
}
- /**
- * Tags any IOExceptions thrown, wrapping and re-throwing.
- *
- * @param e The IOException thrown
- * @throws IOException if an I/O error occurs.
- */
- @Override
- protected void handleIOException(final IOException e) throws IOException {
- throw new TaggedIOException(e, tag);
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/TeeOutputStream.java b/src/main/java/org/apache/commons/io/output/TeeOutputStream.java
index dc70af8..b1456a4 100644
--- a/src/main/java/org/apache/commons/io/output/TeeOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/TeeOutputStream.java
@@ -44,6 +44,39 @@ public class TeeOutputStream extends ProxyOutputStream {
}
/**
+ * Closes both output streams.
+ * <p>
+ * If closing the main output stream throws an exception, attempt to close the branch output stream.
+ * </p>
+ *
+ * <p>
+ * If closing the main and branch output streams both throw exceptions, which exceptions is thrown by this method is
+ * currently unspecified and subject to change.
+ * </p>
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ try {
+ super.close();
+ } finally {
+ this.branch.close();
+ }
+ }
+
+ /**
+ * Flushes both streams.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+ this.branch.flush();
+ }
+
+ /**
* Writes the bytes to both streams.
*
* @param b the bytes to write
@@ -81,37 +114,4 @@ public class TeeOutputStream extends ProxyOutputStream {
this.branch.write(b);
}
- /**
- * Flushes both streams.
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void flush() throws IOException {
- super.flush();
- this.branch.flush();
- }
-
- /**
- * Closes both output streams.
- * <p>
- * If closing the main output stream throws an exception, attempt to close the branch output stream.
- * </p>
- *
- * <p>
- * If closing the main and branch output streams both throw exceptions, which exceptions is thrown by this method is
- * currently unspecified and subject to change.
- * </p>
- *
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void close() throws IOException {
- try {
- super.close();
- } finally {
- this.branch.close();
- }
- }
-
}
diff --git a/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java b/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java
index 9a2eb1d..2cbe0b8 100644
--- a/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java
@@ -64,10 +64,6 @@ public class UncheckedFilterOutputStream extends FilterOutputStream {
}
}
- private void uncheck(final IOException e) {
- throw new UncheckedIOException(e);
- }
-
/**
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
*/
@@ -80,6 +76,10 @@ public class UncheckedFilterOutputStream extends FilterOutputStream {
}
}
+ private void uncheck(final IOException e) {
+ throw new UncheckedIOException(e);
+ }
+
/**
* Calls this method's super and rethrow {@link IOException} as {@link UncheckedIOException}.
*/
diff --git a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java
index 6c4fbec..d69ce85 100644
--- a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java
@@ -31,66 +31,6 @@ import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream;
public final class UnsynchronizedByteArrayOutputStream extends AbstractByteArrayOutputStream {
/**
- * Creates a new byte array output stream. The buffer capacity is initially
- * {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary.
- */
- public UnsynchronizedByteArrayOutputStream() {
- this(DEFAULT_SIZE);
- }
-
- /**
- * Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.
- *
- * @param size the initial size
- * @throws IllegalArgumentException if size is negative
- */
- public UnsynchronizedByteArrayOutputStream(final int size) {
- if (size < 0) {
- throw new IllegalArgumentException("Negative initial size: " + size);
- }
- needNewBuffer(size);
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len) {
- if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException(String.format("offset=%,d, length=%,d", off, len));
- }
- if (len == 0) {
- return;
- }
- writeImpl(b, off, len);
- }
-
- @Override
- public void write(final int b) {
- writeImpl(b);
- }
-
- @Override
- public int write(final InputStream in) throws IOException {
- return writeImpl(in);
- }
-
- @Override
- public int size() {
- return count;
- }
-
- /**
- * @see java.io.ByteArrayOutputStream#reset()
- */
- @Override
- public void reset() {
- resetImpl();
- }
-
- @Override
- public void writeTo(final OutputStream out) throws IOException {
- writeToImpl(out);
- }
-
- /**
* Fetches entire contents of an {@code InputStream} and represent same data as result InputStream.
* <p>
* This method is useful where,
@@ -137,13 +77,73 @@ public final class UnsynchronizedByteArrayOutputStream extends AbstractByteArray
}
}
+ /**
+ * Creates a new byte array output stream. The buffer capacity is initially
+ * {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary.
+ */
+ public UnsynchronizedByteArrayOutputStream() {
+ this(DEFAULT_SIZE);
+ }
+
+ /**
+ * Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes.
+ *
+ * @param size the initial size
+ * @throws IllegalArgumentException if size is negative
+ */
+ public UnsynchronizedByteArrayOutputStream(final int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException("Negative initial size: " + size);
+ }
+ needNewBuffer(size);
+ }
+
+ /**
+ * @see java.io.ByteArrayOutputStream#reset()
+ */
@Override
- public InputStream toInputStream() {
- return toInputStream(UnsynchronizedByteArrayInputStream::new);
+ public void reset() {
+ resetImpl();
+ }
+
+ @Override
+ public int size() {
+ return count;
}
@Override
public byte[] toByteArray() {
return toByteArrayImpl();
}
+
+ @Override
+ public InputStream toInputStream() {
+ return toInputStream(UnsynchronizedByteArrayInputStream::new);
+ }
+
+ @Override
+ public void write(final byte[] b, final int off, final int len) {
+ if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException(String.format("offset=%,d, length=%,d", off, len));
+ }
+ if (len == 0) {
+ return;
+ }
+ writeImpl(b, off, len);
+ }
+
+ @Override
+ public int write(final InputStream in) throws IOException {
+ return writeImpl(in);
+ }
+
+ @Override
+ public void write(final int b) {
+ writeImpl(b);
+ }
+
+ @Override
+ public void writeTo(final OutputStream out) throws IOException {
+ writeToImpl(out);
+ }
}
diff --git a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
index 1a30612..ae6d1a5 100644
--- a/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/WriterOutputStream.java
@@ -74,8 +74,43 @@ import java.nio.charset.CodingErrorAction;
public class WriterOutputStream extends OutputStream {
private static final int BUFFER_SIZE = 1024;
+ /**
+ * Check if the JDK in use properly supports the given charset.
+ *
+ * @param charset the charset to check the support for
+ */
+ private static void checkIbmJdkWithBrokenUTF16(final Charset charset){
+ if (!"UTF-16".equals(charset.name())) {
+ return;
+ }
+ final String TEST_STRING_2 = "v\u00e9s";
+ final byte[] bytes = TEST_STRING_2.getBytes(charset);
+
+ final CharsetDecoder charsetDecoder2 = charset.newDecoder();
+ final ByteBuffer bb2 = ByteBuffer.allocate(16);
+ final CharBuffer cb2 = CharBuffer.allocate(TEST_STRING_2.length());
+ final int len = bytes.length;
+ for (int i = 0; i < len; i++) {
+ bb2.put(bytes[i]);
+ bb2.flip();
+ try {
+ charsetDecoder2.decode(bb2, cb2, i == (len - 1));
+ } catch ( final IllegalArgumentException e){
+ throw new UnsupportedOperationException("UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " +
+ "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream");
+ }
+ bb2.compact();
+ }
+ cb2.rewind();
+ if (!TEST_STRING_2.equals(cb2.toString())){
+ throw new UnsupportedOperationException("UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " +
+ "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream");
+ }
+
+ }
private final Writer writer;
private final CharsetDecoder decoder;
+
private final boolean writeImmediately;
/**
@@ -93,38 +128,28 @@ public class WriterOutputStream extends OutputStream {
private final CharBuffer decoderOut;
/**
- * Constructs a new {@link WriterOutputStream} with a default output buffer size of {@value #BUFFER_SIZE}
- * characters. The output buffer will only be flushed when it overflows or when {@link #flush()} or {@link #close()}
- * is called.
+ * Constructs a new {@link WriterOutputStream} that uses the default character encoding and with a default output
+ * buffer size of {@value #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
*
* @param writer the target {@link Writer}
- * @param decoder the charset decoder
- * @since 2.1
+ * @deprecated 2.5 use {@link #WriterOutputStream(Writer, Charset)} instead
*/
- public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) {
- this(writer, decoder, BUFFER_SIZE, false);
+ @Deprecated
+ public WriterOutputStream(final Writer writer) {
+ this(writer, Charset.defaultCharset(), BUFFER_SIZE, false);
}
/**
- * Constructs a new {@link WriterOutputStream}.
+ * Constructs a new {@link WriterOutputStream} with a default output buffer size of {@value #BUFFER_SIZE}
+ * characters. The output buffer will only be flushed when it overflows or when {@link #flush()} or {@link #close()}
+ * is called.
*
* @param writer the target {@link Writer}
- * @param decoder the charset decoder
- * @param bufferSize the size of the output buffer in number of characters
- * @param writeImmediately If {@code true} the output buffer will be flushed after each
- * write operation, i.e. all available data will be written to the
- * underlying {@link Writer} immediately. If {@code false}, the
- * output buffer will only be flushed when it overflows or when
- * {@link #flush()} or {@link #close()} is called.
- * @since 2.1
+ * @param charset the charset encoding
*/
- public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize,
- final boolean writeImmediately) {
- checkIbmJdkWithBrokenUTF16( decoder.charset());
- this.writer = writer;
- this.decoder = decoder;
- this.writeImmediately = writeImmediately;
- decoderOut = CharBuffer.allocate(bufferSize);
+ public WriterOutputStream(final Writer writer, final Charset charset) {
+ this(writer, charset, BUFFER_SIZE, false);
}
/**
@@ -156,27 +181,33 @@ public class WriterOutputStream extends OutputStream {
* is called.
*
* @param writer the target {@link Writer}
- * @param charset the charset encoding
+ * @param decoder the charset decoder
+ * @since 2.1
*/
- public WriterOutputStream(final Writer writer, final Charset charset) {
- this(writer, charset, BUFFER_SIZE, false);
+ public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) {
+ this(writer, decoder, BUFFER_SIZE, false);
}
/**
* Constructs a new {@link WriterOutputStream}.
*
* @param writer the target {@link Writer}
- * @param charsetName the name of the charset encoding
+ * @param decoder the charset decoder
* @param bufferSize the size of the output buffer in number of characters
* @param writeImmediately If {@code true} the output buffer will be flushed after each
* write operation, i.e. all available data will be written to the
* underlying {@link Writer} immediately. If {@code false}, the
* output buffer will only be flushed when it overflows or when
* {@link #flush()} or {@link #close()} is called.
+ * @since 2.1
*/
- public WriterOutputStream(final Writer writer, final String charsetName, final int bufferSize,
+ public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, final int bufferSize,
final boolean writeImmediately) {
- this(writer, Charset.forName(charsetName), bufferSize, writeImmediately);
+ checkIbmJdkWithBrokenUTF16( decoder.charset());
+ this.writer = writer;
+ this.decoder = decoder;
+ this.writeImmediately = writeImmediately;
+ decoderOut = CharBuffer.allocate(bufferSize);
}
/**
@@ -192,60 +223,33 @@ public class WriterOutputStream extends OutputStream {
}
/**
- * Constructs a new {@link WriterOutputStream} that uses the default character encoding and with a default output
- * buffer size of {@value #BUFFER_SIZE} characters. The output buffer will only be flushed when it overflows or when
- * {@link #flush()} or {@link #close()} is called.
+ * Constructs a new {@link WriterOutputStream}.
*
* @param writer the target {@link Writer}
- * @deprecated 2.5 use {@link #WriterOutputStream(Writer, Charset)} instead
- */
- @Deprecated
- public WriterOutputStream(final Writer writer) {
- this(writer, Charset.defaultCharset(), BUFFER_SIZE, false);
- }
-
- /**
- * Write bytes from the specified byte array to the stream.
- *
- * @param b the byte array containing the bytes to write
- * @param off the start offset in the byte array
- * @param len the number of bytes to write
- * @throws IOException if an I/O error occurs.
- */
- @Override
- public void write(final byte[] b, int off, int len) throws IOException {
- while (len > 0) {
- final int c = Math.min(len, decoderIn.remaining());
- decoderIn.put(b, off, c);
- processInput(false);
- len -= c;
- off += c;
- }
- if (writeImmediately) {
- flushOutput();
- }
- }
-
- /**
- * Write bytes from the specified byte array to the stream.
- *
- * @param b the byte array containing the bytes to write
- * @throws IOException if an I/O error occurs.
+ * @param charsetName the name of the charset encoding
+ * @param bufferSize the size of the output buffer in number of characters
+ * @param writeImmediately If {@code true} the output buffer will be flushed after each
+ * write operation, i.e. all available data will be written to the
+ * underlying {@link Writer} immediately. If {@code false}, the
+ * output buffer will only be flushed when it overflows or when
+ * {@link #flush()} or {@link #close()} is called.
*/
- @Override
- public void write(final byte[] b) throws IOException {
- write(b, 0, b.length);
+ public WriterOutputStream(final Writer writer, final String charsetName, final int bufferSize,
+ final boolean writeImmediately) {
+ this(writer, Charset.forName(charsetName), bufferSize, writeImmediately);
}
/**
- * Write a single byte to the stream.
- *
- * @param b the byte to write
+ * Close the stream. Any remaining content accumulated in the output buffer
+ * will be written to the underlying {@link Writer}. After that
+ * {@link Writer#close()} will be called.
* @throws IOException if an I/O error occurs.
*/
@Override
- public void write(final int b) throws IOException {
- write(new byte[] {(byte) b}, 0, 1);
+ public void close() throws IOException {
+ processInput(true);
+ flushOutput();
+ writer.close();
}
/**
@@ -261,16 +265,15 @@ public class WriterOutputStream extends OutputStream {
}
/**
- * Close the stream. Any remaining content accumulated in the output buffer
- * will be written to the underlying {@link Writer}. After that
- * {@link Writer#close()} will be called.
+ * Flush the output.
+ *
* @throws IOException if an I/O error occurs.
*/
- @Override
- public void close() throws IOException {
- processInput(true);
- flushOutput();
- writer.close();
+ private void flushOutput() throws IOException {
+ if (decoderOut.position() > 0) {
+ writer.write(decoderOut.array(), 0, decoderOut.position());
+ decoderOut.rewind();
+ }
}
/**
@@ -300,49 +303,46 @@ public class WriterOutputStream extends OutputStream {
}
/**
- * Flush the output.
+ * Write bytes from the specified byte array to the stream.
*
+ * @param b the byte array containing the bytes to write
* @throws IOException if an I/O error occurs.
*/
- private void flushOutput() throws IOException {
- if (decoderOut.position() > 0) {
- writer.write(decoderOut.array(), 0, decoderOut.position());
- decoderOut.rewind();
- }
+ @Override
+ public void write(final byte[] b) throws IOException {
+ write(b, 0, b.length);
}
/**
- * Check if the JDK in use properly supports the given charset.
+ * Write bytes from the specified byte array to the stream.
*
- * @param charset the charset to check the support for
+ * @param b the byte array containing the bytes to write
+ * @param off the start offset in the byte array
+ * @param len the number of bytes to write
+ * @throws IOException if an I/O error occurs.
*/
- private static void checkIbmJdkWithBrokenUTF16(final Charset charset){
- if (!"UTF-16".equals(charset.name())) {
- return;
- }
- final String TEST_STRING_2 = "v\u00e9s";
- final byte[] bytes = TEST_STRING_2.getBytes(charset);
-
- final CharsetDecoder charsetDecoder2 = charset.newDecoder();
- final ByteBuffer bb2 = ByteBuffer.allocate(16);
- final CharBuffer cb2 = CharBuffer.allocate(TEST_STRING_2.length());
- final int len = bytes.length;
- for (int i = 0; i < len; i++) {
- bb2.put(bytes[i]);
- bb2.flip();
- try {
- charsetDecoder2.decode(bb2, cb2, i == (len - 1));
- } catch ( final IllegalArgumentException e){
- throw new UnsupportedOperationException("UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " +
- "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream");
- }
- bb2.compact();
+ @Override
+ public void write(final byte[] b, int off, int len) throws IOException {
+ while (len > 0) {
+ final int c = Math.min(len, decoderIn.remaining());
+ decoderIn.put(b, off, c);
+ processInput(false);
+ len -= c;
+ off += c;
}
- cb2.rewind();
- if (!TEST_STRING_2.equals(cb2.toString())){
- throw new UnsupportedOperationException("UTF-16 requested when running on an IBM JDK with broken UTF-16 support. " +
- "Please find a JDK that supports UTF-16 if you intend to use UF-16 with WriterOutputStream");
+ if (writeImmediately) {
+ flushOutput();
}
+ }
+ /**
+ * Write a single byte to the stream.
+ *
+ * @param b the byte to write
+ * @throws IOException if an I/O error occurs.
+ */
+ @Override
+ public void write(final int b) throws IOException {
+ write(new byte[] {(byte) b}, 0, 1);
}
}
diff --git a/src/main/java/org/apache/commons/io/output/XmlStreamWriter.java b/src/main/java/org/apache/commons/io/output/XmlStreamWriter.java
index 881f1d7..0dcdd87 100644
--- a/src/main/java/org/apache/commons/io/output/XmlStreamWriter.java
+++ b/src/main/java/org/apache/commons/io/output/XmlStreamWriter.java
@@ -41,6 +41,8 @@ import org.apache.commons.io.input.XmlStreamReader;
public class XmlStreamWriter extends Writer {
private static final int BUFFER_SIZE = IOUtils.DEFAULT_BUFFER_SIZE;
+ static final Pattern ENCODING_PATTERN = XmlStreamReader.ENCODING_PATTERN;
+
private final OutputStream out;
private final String defaultEncoding;
@@ -52,28 +54,6 @@ public class XmlStreamWriter extends Writer {
private String encoding;
/**
- * Constructs a new XML stream writer for the specified output stream
- * with a default encoding of UTF-8.
- *
- * @param out The output stream
- */
- public XmlStreamWriter(final OutputStream out) {
- this(out, null);
- }
-
- /**
- * Constructs a new XML stream writer for the specified output stream
- * with the specified default encoding.
- *
- * @param out The output stream
- * @param defaultEncoding The default encoding if not encoding could be detected
- */
- public XmlStreamWriter(final OutputStream out, final String defaultEncoding) {
- this.out = out;
- this.defaultEncoding = defaultEncoding != null ? defaultEncoding : "UTF-8";
- }
-
- /**
* Constructs a new XML stream writer for the specified file
* with a default encoding of UTF-8.
*
@@ -100,21 +80,25 @@ public class XmlStreamWriter extends Writer {
}
/**
- * Returns the detected encoding.
+ * Constructs a new XML stream writer for the specified output stream
+ * with a default encoding of UTF-8.
*
- * @return the detected encoding
+ * @param out The output stream
*/
- public String getEncoding() {
- return encoding;
+ public XmlStreamWriter(final OutputStream out) {
+ this(out, null);
}
/**
- * Returns the default encoding.
+ * Constructs a new XML stream writer for the specified output stream
+ * with the specified default encoding.
*
- * @return the default encoding
+ * @param out The output stream
+ * @param defaultEncoding The default encoding if not encoding could be detected
*/
- public String getDefaultEncoding() {
- return defaultEncoding;
+ public XmlStreamWriter(final OutputStream out, final String defaultEncoding) {
+ this.out = out;
+ this.defaultEncoding = defaultEncoding != null ? defaultEncoding : "UTF-8";
}
/**
@@ -133,18 +117,6 @@ public class XmlStreamWriter extends Writer {
}
/**
- * Flushes the underlying writer.
- *
- * @throws IOException if an error occurs flushing the underlying writer
- */
- @Override
- public void flush() throws IOException {
- if (writer != null) {
- writer.flush();
- }
- }
-
- /**
* Detects the encoding.
*
* @param cbuf the buffer to write the characters from
@@ -200,6 +172,36 @@ public class XmlStreamWriter extends Writer {
}
/**
+ * Flushes the underlying writer.
+ *
+ * @throws IOException if an error occurs flushing the underlying writer
+ */
+ @Override
+ public void flush() throws IOException {
+ if (writer != null) {
+ writer.flush();
+ }
+ }
+
+ /**
+ * Returns the default encoding.
+ *
+ * @return the default encoding
+ */
+ public String getDefaultEncoding() {
+ return defaultEncoding;
+ }
+
+ /**
+ * Returns the detected encoding.
+ *
+ * @return the detected encoding
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
* Writes the characters to the underlying writer, detecting encoding.
*
* @param cbuf the buffer to write the characters from
@@ -215,6 +217,4 @@ public class XmlStreamWriter extends Writer {
writer.write(cbuf, off, len);
}
}
-
- static final Pattern ENCODING_PATTERN = XmlStreamReader.ENCODING_PATTERN;
}
diff --git a/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java b/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java
index a7f9b28..535f94f 100644
--- a/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java
+++ b/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java
@@ -31,15 +31,6 @@ final class RegexpClassNameMatcher implements ClassNameMatcher {
private final Pattern pattern; // Class is thread-safe
/**
- * Constructs an object based on the specified regular expression.
- *
- * @param regex a regular expression for evaluating acceptable class names
- */
- public RegexpClassNameMatcher(final String regex) {
- this(Pattern.compile(regex));
- }
-
- /**
* Constructs an object based on the specified pattern.
*
* @param pattern a pattern for evaluating acceptable class names
@@ -52,6 +43,15 @@ final class RegexpClassNameMatcher implements ClassNameMatcher {
this.pattern = pattern;
}
+ /**
+ * Constructs an object based on the specified regular expression.
+ *
+ * @param regex a regular expression for evaluating acceptable class names
+ */
+ public RegexpClassNameMatcher(final String regex) {
+ this(Pattern.compile(regex));
+ }
+
@Override
public boolean matches(final String className) {
return pattern.matcher(className).matches();
diff --git a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java
index 80a99e8..f4fea5e 100644
--- a/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java
+++ b/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java
@@ -59,48 +59,6 @@ public class ValidatingObjectInputStream extends ObjectInputStream {
super(input);
}
- /** Check that the classname conforms to requirements.
- * @param name The class name
- * @throws InvalidClassException when a non-accepted class is encountered
- */
- private void validateClassName(final String name) throws InvalidClassException {
- // Reject has precedence over accept
- for (final ClassNameMatcher m : rejectMatchers) {
- if (m.matches(name)) {
- invalidClassNameFound(name);
- }
- }
-
- boolean ok = false;
- for (final ClassNameMatcher m : acceptMatchers) {
- if (m.matches(name)) {
- ok = true;
- break;
- }
- }
- if (!ok) {
- invalidClassNameFound(name);
- }
- }
-
- /**
- * Called to throw {@code InvalidClassException} if an invalid
- * class name is found during deserialization. Can be overridden, for example
- * to log those class names.
- *
- * @param className name of the invalid class
- * @throws InvalidClassException if the specified class is not allowed
- */
- protected void invalidClassNameFound(final String className) throws InvalidClassException {
- throw new InvalidClassException("Class name not accepted: " + className);
- }
-
- @Override
- protected Class<?> resolveClass(final ObjectStreamClass osc) throws IOException, ClassNotFoundException {
- validateClassName(osc.getName());
- return super.resolveClass(osc);
- }
-
/**
* Accept the specified classes for deserialization, unless they
* are otherwise rejected.
@@ -116,16 +74,26 @@ public class ValidatingObjectInputStream extends ObjectInputStream {
}
... 148 lines suppressed ...