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 2023/12/22 21:22:29 UTC

(commons-io) branch master updated (cae58ff4 -> 7d41cb1a)

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

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


    from cae58ff4 Javadoc
     new d5898c1c Add FileTimes.isUnixTime(FileTime)
     new 1db65f59 Sort members
     new 7d41cb1a Use final

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/changes/changes.xml                            |  3 ++
 src/main/java/org/apache/commons/io/FileUtils.java |  6 ++--
 .../java/org/apache/commons/io/file/PathUtils.java |  4 +--
 .../commons/io/file/attribute/FileTimes.java       | 41 ++++++++++++++++++++++
 .../commons/io/filefilter/AbstractFileFilter.java  |  2 +-
 .../org/apache/commons/io/function/IOStream.java   |  2 +-
 .../commons/io/input/BoundedInputStream.java       | 20 +++++------
 .../apache/commons/io/input/BrokenInputStream.java | 20 +++++------
 .../org/apache/commons/io/input/BrokenReader.java  | 20 +++++------
 .../commons/io/input/CharSequenceInputStream.java  |  2 +-
 .../input/UnsynchronizedByteArrayInputStream.java  |  2 +-
 .../commons/io/output/BrokenOutputStream.java      | 20 +++++------
 .../org/apache/commons/io/output/BrokenWriter.java | 20 +++++------
 .../org/apache/commons/io/EndianUtilsTest.java     |  4 +--
 .../java/org/apache/commons/io/FileUtilsTest.java  |  4 +--
 .../commons/io/file/attribute/FileTimesTest.java   | 37 +++++++++++++++++--
 .../io/input/CharSequenceInputStreamTest.java      |  2 +-
 .../UnsynchronizedByteArrayInputStreamTest.java    |  6 ++--
 .../io/jmh/PathUtilsContentEqualsBenchmark.java    |  2 +-
 19 files changed, 147 insertions(+), 70 deletions(-)


(commons-io) 03/03: Use final

Posted by gg...@apache.org.
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 7d41cb1a0ac95895226b2924ca02a868bc3be061
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Dec 22 16:22:15 2023 -0500

    Use final
    
    - Use 'L' for long literal
    - Use compact array declaration
---
 src/main/java/org/apache/commons/io/FileUtils.java                  | 6 +++---
 src/main/java/org/apache/commons/io/file/PathUtils.java             | 4 ++--
 .../java/org/apache/commons/io/filefilter/AbstractFileFilter.java   | 2 +-
 src/main/java/org/apache/commons/io/function/IOStream.java          | 2 +-
 .../java/org/apache/commons/io/input/CharSequenceInputStream.java   | 2 +-
 .../apache/commons/io/input/UnsynchronizedByteArrayInputStream.java | 2 +-
 src/test/java/org/apache/commons/io/EndianUtilsTest.java            | 4 ++--
 .../org/apache/commons/io/input/CharSequenceInputStreamTest.java    | 2 +-
 .../commons/io/input/UnsynchronizedByteArrayInputStreamTest.java    | 6 +++---
 .../org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java  | 2 +-
 10 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java
index 5865d834..b983bb8b 100644
--- a/src/main/java/org/apache/commons/io/FileUtils.java
+++ b/src/main/java/org/apache/commons/io/FileUtils.java
@@ -2820,7 +2820,7 @@ public class FileUtils {
             // null guards are not needed; BasicFileAttributes.setTimes(...) is null safe
             destAttrView.setTimes(srcAttr.lastModifiedTime(), srcAttr.lastAccessTime(), srcAttr.creationTime());
             return true;
-        } catch (IOException ignored) {
+        } catch (final IOException ignored) {
             // Fallback: Only set modified time to match source file
             return targetFile.setLastModified(sourceFile.lastModified());
         }
@@ -2895,7 +2895,7 @@ public class FileUtils {
     public static long sizeOfDirectory(final File directory) {
         try {
             requireDirectoryExists(directory, "directory");
-        } catch (FileNotFoundException e) {
+        } catch (final FileNotFoundException e) {
             throw new UncheckedIOException(e);
         }
         return Uncheck.get(() -> PathUtils.sizeOfDirectory(directory.toPath()));
@@ -2913,7 +2913,7 @@ public class FileUtils {
     public static BigInteger sizeOfDirectoryAsBigInteger(final File directory) {
         try {
             requireDirectoryExists(directory, "directory");
-        } catch (FileNotFoundException e) {
+        } catch (final FileNotFoundException e) {
             throw new UncheckedIOException(e);
         }
         return Uncheck.get(() -> PathUtils.sizeOfDirectoryAsBigInteger(directory.toPath()));
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 29af5800..64ca294a 100644
--- a/src/main/java/org/apache/commons/io/file/PathUtils.java
+++ b/src/main/java/org/apache/commons/io/file/PathUtils.java
@@ -770,7 +770,7 @@ public final class PathUtils {
         try (RandomAccessFile raf1 = RandomAccessFileMode.READ_ONLY.create(path1.toRealPath(linkOptions));
                 RandomAccessFile raf2 = RandomAccessFileMode.READ_ONLY.create(path2.toRealPath(linkOptions))) {
             return RandomAccessFiles.contentEquals(raf1, raf2);
-        } catch (UnsupportedOperationException e) {
+        } catch (final UnsupportedOperationException e) {
             // Slower:
             // Handle
             // java.lang.UnsupportedOperationException
@@ -877,7 +877,7 @@ public final class PathUtils {
      * @see Path#getFileName()
      * @since 2.16.0
      */
-    public static <R> R getFileName(final Path path, Function<Path, R> function) {
+    public static <R> R getFileName(final Path path, final Function<Path, R> function) {
         final Path fileName = path != null ? path.getFileName() : null;
         return fileName != null ? function.apply(fileName) : null;
     }
diff --git a/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java
index 4bc6dcf4..e1359c96 100644
--- a/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java
+++ b/src/main/java/org/apache/commons/io/filefilter/AbstractFileFilter.java
@@ -120,7 +120,7 @@ public abstract class AbstractFileFilter implements IOFileFilter, PathVisitor {
     FileVisitResult get(final IOSupplier<FileVisitResult> supplier) {
         try {
             return supplier.get();
-        } catch (IOException e) {
+        } catch (final IOException e) {
             return handle(e);
         }
     }
diff --git a/src/main/java/org/apache/commons/io/function/IOStream.java b/src/main/java/org/apache/commons/io/function/IOStream.java
index 3eac5bfb..99065f62 100644
--- a/src/main/java/org/apache/commons/io/function/IOStream.java
+++ b/src/main/java/org/apache/commons/io/function/IOStream.java
@@ -97,7 +97,7 @@ public interface IOStream<T> extends IOBaseStream<T, IOStream<T>, Stream<T>> {
             public T next() throws NoSuchElementException {
                 try {
                     return t = t == IOStreams.NONE ? seed : f.apply(t);
-                } catch (IOException e) {
+                } catch (final IOException e) {
                     final NoSuchElementException nsee = new NoSuchElementException();
                     nsee.initCause(e);
                     throw nsee;
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 e5680fb0..5b53f5d2 100644
--- a/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/CharSequenceInputStream.java
@@ -182,7 +182,7 @@ public class CharSequenceInputStream extends InputStream {
         this.bBufMark = NO_MARK;
         try {
             fillBuffer();
-        } catch (CharacterCodingException ex) {
+        } catch (final CharacterCodingException ex) {
             // Reset everything without filling the buffer
             // so the same exception can be thrown again later.
             this.bBuf.clear();
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 0b5c1145..fdaafc74 100644
--- a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java
@@ -219,7 +219,7 @@ public class UnsynchronizedByteArrayInputStream extends InputStream {
         this.markedOffset = minPosLen(data, offset);
     }
 
-    private UnsynchronizedByteArrayInputStream(byte[] data, int eod, int offset, int markedOffset) {
+    private UnsynchronizedByteArrayInputStream(final byte[] data, final int eod, final int offset, final int markedOffset) {
         this.data = Objects.requireNonNull(data, "data");
         this.eod = eod;
         this.offset = offset;
diff --git a/src/test/java/org/apache/commons/io/EndianUtilsTest.java b/src/test/java/org/apache/commons/io/EndianUtilsTest.java
index 98a72c6a..54abb414 100644
--- a/src/test/java/org/apache/commons/io/EndianUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/EndianUtilsTest.java
@@ -45,7 +45,7 @@ public class EndianUtilsTest  {
 
     @Test
     public void testInvalidOffset() throws IOException {
-        final byte[] bytes = new byte[0];
+        final byte[] bytes = {};
 
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedInteger(bytes, 0));
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedLong(bytes, 0));
@@ -53,7 +53,7 @@ public class EndianUtilsTest  {
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedInteger(bytes, 0));
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedShort(bytes, 0));
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedInteger(bytes, 0, 0));
-        assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedLong(bytes, 0, 0l));
+        assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedLong(bytes, 0, 0L));
         assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedShort(bytes, 0, (short) 0));
     }
 
diff --git a/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java b/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java
index 8ad0db8e..848f41c5 100644
--- a/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java
@@ -352,7 +352,7 @@ public class CharSequenceInputStreamTest {
         final String sequenceEnglish = "Test Sequence";
         final String sequenceCJK = "\u4e01\u4f23\u5045\u5167\u5289\u53ab"; // Kanji text
         final String[] sequences = {sequenceEnglish, sequenceCJK};
-        for (String testSequence : sequences) {
+        for (final String testSequence : sequences) {
             final CharsetEncoder charsetEncoder = Charset.forName(csName).newEncoder();
             final ByteBuffer byteBuffer = ByteBuffer.allocate(testSequence.length() * 3);
             final CharBuffer charBuffer = CharBuffer.wrap(testSequence);
diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStreamTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStreamTest.java
index 866c833b..a436f8f8 100644
--- a/src/test/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStreamTest.java
@@ -36,7 +36,7 @@ public class UnsynchronizedByteArrayInputStreamTest {
     private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer) {
         try {
             return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).get();
-        } catch (IOException e) {
+        } catch (final IOException e) {
             fail("Should never happen because no conversion is needed.", e);
             return null;
         }
@@ -45,7 +45,7 @@ public class UnsynchronizedByteArrayInputStreamTest {
     private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer, final int offset) {
         try {
             return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).setOffset(offset).get();
-        } catch (IOException e) {
+        } catch (final IOException e) {
             fail("Should never happen because no conversion is needed.", e);
             return null;
         }
@@ -54,7 +54,7 @@ public class UnsynchronizedByteArrayInputStreamTest {
     private UnsynchronizedByteArrayInputStream newStream(final byte[] buffer, final int offset, final int length) {
         try {
             return UnsynchronizedByteArrayInputStream.builder().setByteArray(buffer).setOffset(offset).setLength(length).get();
-        } catch (IOException e) {
+        } catch (final IOException e) {
             fail("Should never happen because no conversion is needed.", e);
             return null;
         }
diff --git a/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java b/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java
index 20e49e71..5a63f5ed 100644
--- a/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java
+++ b/src/test/java/org/apache/commons/io/jmh/PathUtilsContentEqualsBenchmark.java
@@ -72,7 +72,7 @@ public class PathUtilsContentEqualsBenchmark {
             Arrays.fill(bytes1, (byte) 1);
             Files.write(bigFile1, bytes1);
             Files.copy(bigFile1, bigFile2, StandardCopyOption.REPLACE_EXISTING);
-        } catch (IOException e) {
+        } catch (final IOException e) {
             throw new UncheckedIOException(e);
         }
     }


(commons-io) 01/03: Add FileTimes.isUnixTime(FileTime)

Posted by gg...@apache.org.
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 d5898c1cd599bb8053f26d3b4c95906283d04521
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Dec 22 16:06:24 2023 -0500

    Add FileTimes.isUnixTime(FileTime)
    
    - Add FileTimes.isUnixTime(long)
    - Add FileTimes.toUnixTime(FileTime)
---
 src/changes/changes.xml                            |  3 ++
 .../commons/io/file/attribute/FileTimes.java       | 41 ++++++++++++++++++++++
 .../commons/io/file/attribute/FileTimesTest.java   | 37 +++++++++++++++++--
 3 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 7addfdb6..be111b51 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -86,6 +86,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add BoundedInputStream.getRemaining().</action>
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add FileTimes.toNtfsTime(long).</action>
       <action dev="ggregory" type="add"                due-to="Gary Gregory">Add FileTimes.fromUnixTime(long).</action>
+      <action dev="ggregory" type="add"                due-to="Gary Gregory">Add FileTimes.isUnixTime(FileTime).</action>
+      <action dev="ggregory" type="add"                due-to="Gary Gregory">Add FileTimes.isUnixTime(long).</action>
+      <action dev="ggregory" type="add"                due-to="Gary Gregory">Add FileTimes.toUnixTime(FileTime).</action>
       <!--  UPDATE -->
       <action dev="ggregory" type="fix"                due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.14.10 to 1.14.11 #534.</action>
     </release>
diff --git a/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java b/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java
index 6ddf0675..1ec3f32a 100644
--- a/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java
+++ b/src/main/java/org/apache/commons/io/file/attribute/FileTimes.java
@@ -72,6 +72,32 @@ public final class FileTimes {
         return FileTime.from(time, TimeUnit.SECONDS);
     }
 
+    /**
+     * Tests whether a FileTime can be safely represented in the standard UNIX time.
+     * <p>
+     * If the FileTime is null, this method returns true.
+     * </p>
+     *
+     * @param time the FileTime to evaluate, can be null.
+     * @return true if the time exceeds the minimum or maximum UNIX time, false otherwise.
+     * @since 2.16.0
+     */
+    public static boolean isUnixTime(final FileTime time) {
+        return isUnixTime(toUnixTime(time));
+    }
+
+    /**
+     * Tests whether a given number of seconds (since Epoch) can be safely represented in the standard UNIX time.
+     *
+     * @param seconds the number of seconds (since Epoch) to evaluate.
+     * @return true if the time can be represented in the standard UNIX time, false otherwise.
+     * @since 2.16.0
+     */
+    public static boolean isUnixTime(final long seconds) {
+        return Integer.MIN_VALUE <= seconds && seconds <= Integer.MAX_VALUE;
+    }
+
+
     /**
      * Subtracts milliseconds from a source FileTime.
      *
@@ -243,6 +269,21 @@ public final class FileTimes {
         return Math.subtractExact(javaHundredNanos, WINDOWS_EPOCH_OFFSET);
     }
 
+    /**
+     * Converts {@link FileTime} to standard UNIX time in seconds.
+     * <p>
+     * The returned seconds value may lie out of bounds of UNIX time. Check with {@link FileTimes#isUnixTime(long)}.
+     * </p>
+     *
+     * @param fileTime the original FileTime.
+     * @return the UNIX timestamp or 0 if the input is null.
+     * @see #isUnixTime(long)
+     * @since 2.16.0
+     */
+    public static long toUnixTime(final FileTime fileTime) {
+        return fileTime != null ? fileTime.to(TimeUnit.SECONDS) : 0;
+    }
+
     private FileTimes() {
         // No instances.
     }
diff --git a/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java b/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
index 2df06921..8b29bd03 100644
--- a/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
+++ b/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
@@ -19,6 +19,7 @@ package org.apache.commons.io.file.attribute;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.nio.file.attribute.FileTime;
 import java.time.Instant;
@@ -76,6 +77,18 @@ public class FileTimesTest {
         // @formatter:on
     }
 
+    public static Stream<Arguments> isUnixFileTimeProvider() {
+        // @formatter:off
+        return Stream.of(
+            Arguments.of("2022-12-27T12:45:22Z", true),
+            Arguments.of("2038-01-19T03:14:07Z", true),
+            Arguments.of("1901-12-13T23:14:08Z", true),
+            Arguments.of("1901-12-13T03:14:08Z", false),
+            Arguments.of("2038-01-19T03:14:08Z", false),
+            Arguments.of("2099-06-30T12:31:42Z", false));
+        // @formatter:on
+    }
+
     @ParameterizedTest
     @MethodSource("dateToNtfsProvider")
     public void testDateToFileTime(final String instant, final long ignored) {
@@ -115,8 +128,6 @@ public class FileTimesTest {
         assertEquals(ntfsTime, FileTimes.toNtfsTime(parsed));
     }
 
-    //
-
     @ParameterizedTest
     @MethodSource("dateToNtfsProvider")
     public void testFromUnixTime(final String instant, final long ntfsTime) {
@@ -124,6 +135,28 @@ public class FileTimesTest {
         assertEquals(epochSecond, FileTimes.fromUnixTime(epochSecond).to(TimeUnit.SECONDS));
     }
 
+    @ParameterizedTest
+    @MethodSource("isUnixFileTimeProvider")
+    public void testIsUnixTime(final String instant, final boolean isUnixTime) {
+        assertEquals(isUnixTime, FileTimes.isUnixTime(FileTime.from(Instant.parse(instant))));
+    }
+
+    @ParameterizedTest
+    @MethodSource("isUnixFileTimeProvider")
+    public void testIsUnixTimeLong(final String instant, final boolean isUnixTime) {
+        assertEquals(isUnixTime, FileTimes.isUnixTime(Instant.parse(instant).getEpochSecond()));
+    }
+
+    @ParameterizedTest
+    @MethodSource("isUnixFileTimeProvider")
+    public void testToUnixTime(final String instant, final boolean isUnixTime) {
+        assertEquals(isUnixTime, FileTimes.isUnixTime(FileTimes.toUnixTime(FileTime.from(Instant.parse(instant)))));
+    }
+
+    public void testIsUnixTimeFileTimeNull() {
+        assertTrue(FileTimes.isUnixTime(null));
+    }
+
     @Test
     public void testMinusMillis() {
         final int millis = 2;


(commons-io) 02/03: Sort members

Posted by gg...@apache.org.
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 1db65f599c5f09fa06e65080f16d98e005007b08
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Dec 22 16:07:12 2023 -0500

    Sort members
---
 .../apache/commons/io/input/BoundedInputStream.java  | 20 ++++++++++----------
 .../apache/commons/io/input/BrokenInputStream.java   | 20 ++++++++++----------
 .../org/apache/commons/io/input/BrokenReader.java    | 20 ++++++++++----------
 .../apache/commons/io/output/BrokenOutputStream.java | 20 ++++++++++----------
 .../org/apache/commons/io/output/BrokenWriter.java   | 20 ++++++++++----------
 .../java/org/apache/commons/io/FileUtilsTest.java    |  4 ++--
 .../commons/io/file/attribute/FileTimesTest.java     | 20 ++++++++++----------
 7 files changed, 62 insertions(+), 62 deletions(-)

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 b5c1d179..e1fcf905 100644
--- a/src/main/java/org/apache/commons/io/input/BoundedInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BoundedInputStream.java
@@ -105,16 +105,6 @@ public class BoundedInputStream extends FilterInputStream {
         return count;
     }
 
-    /**
-     * Gets how many bytes remain to read.
-     *
-     * @return bytes how many bytes remain to read.
-     * @since 2.16.0
-     */
-    public long getRemaining() {
-        return getMaxLength() - getCount();
-    }
-
     /**
      * Gets the max count of bytes to read.
      *
@@ -125,6 +115,16 @@ public class BoundedInputStream extends FilterInputStream {
         return maxCount;
     }
 
+    /**
+     * Gets how many bytes remain to read.
+     *
+     * @return bytes how many bytes remain to read.
+     * @since 2.16.0
+     */
+    public long getRemaining() {
+        return getMaxLength() - getCount();
+    }
+
     private boolean isMaxLength() {
         return maxCount >= 0 && count >= maxCount;
     }
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 1679430f..4130d3fa 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
@@ -62,16 +62,6 @@ public class BrokenInputStream extends InputStream {
         this(() -> exception);
     }
 
-    /**
-     * Constructs a new stream that always throws the given exception.
-     *
-     * @param exception the exception to be thrown.
-     * @since 2.16.0
-     */
-    public BrokenInputStream(final Throwable exception) {
-        this(() -> exception);
-    }
-
     /**
      * Constructs a new stream that always throws the supplied exception.
      *
@@ -82,6 +72,16 @@ public class BrokenInputStream extends InputStream {
         this.exceptionSupplier = exceptionSupplier;
     }
 
+    /**
+     * Constructs a new stream that always throws the given exception.
+     *
+     * @param exception the exception to be thrown.
+     * @since 2.16.0
+     */
+    public BrokenInputStream(final Throwable exception) {
+        this(() -> exception);
+    }
+
     /**
      * Throws the configured exception.
      *
diff --git a/src/main/java/org/apache/commons/io/input/BrokenReader.java b/src/main/java/org/apache/commons/io/input/BrokenReader.java
index 96557dd4..1b28408a 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenReader.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenReader.java
@@ -62,16 +62,6 @@ public class BrokenReader extends Reader {
         this(() -> exception);
     }
 
-    /**
-     * Constructs a new reader that always throws the given exception.
-     *
-     * @param exception the exception to be thrown.
-     * @since 2.16.0
-     */
-    public BrokenReader(final Throwable exception) {
-        this(() -> exception);
-    }
-
     /**
      * Constructs a new reader that always throws the supplied exception.
      *
@@ -82,6 +72,16 @@ public class BrokenReader extends Reader {
         this.exceptionSupplier = exceptionSupplier;
     }
 
+    /**
+     * Constructs a new reader that always throws the given exception.
+     *
+     * @param exception the exception to be thrown.
+     * @since 2.16.0
+     */
+    public BrokenReader(final Throwable exception) {
+        this(() -> exception);
+    }
+
     /**
      * Throws the configured exception.
      *
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 eaef8d12..5b1dad04 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
@@ -62,16 +62,6 @@ public class BrokenOutputStream extends OutputStream {
         this(() -> exception);
     }
 
-    /**
-     * Constructs a new stream that always throws the given exception.
-     *
-     * @param exception the exception to be thrown.
-     * @since 2.16.0
-     */
-    public BrokenOutputStream(final Throwable exception) {
-        this(() -> exception);
-    }
-
     /**
      * Constructs a new stream that always throws the supplied exception.
      *
@@ -82,6 +72,16 @@ public class BrokenOutputStream extends OutputStream {
         this.exceptionSupplier = exceptionSupplier;
     }
 
+    /**
+     * Constructs a new stream that always throws the given exception.
+     *
+     * @param exception the exception to be thrown.
+     * @since 2.16.0
+     */
+    public BrokenOutputStream(final Throwable exception) {
+        this(() -> exception);
+    }
+
     /**
      * Throws the configured 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 241e8dd1..800d669e 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenWriter.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenWriter.java
@@ -62,16 +62,6 @@ public class BrokenWriter extends Writer {
         this(() -> exception);
     }
 
-    /**
-     * Constructs a new writer that always throws the given exception.
-     *
-     * @param exception the exception to be thrown.
-     * @since 2.16.0
-     */
-    public BrokenWriter(final Throwable exception) {
-        this(() -> exception);
-    }
-
     /**
      * Constructs a new writer that always throws the supplied exception.
      *
@@ -82,6 +72,16 @@ public class BrokenWriter extends Writer {
         this.exceptionSupplier = exceptionSupplier;
     }
 
+    /**
+     * Constructs a new writer that always throws the given exception.
+     *
+     * @param exception the exception to be thrown.
+     * @since 2.16.0
+     */
+    public BrokenWriter(final Throwable exception) {
+        this(() -> exception);
+    }
+
     /**
      * Throws the configured exception.
      *
diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java
index 67f4c26e..45ef7a41 100644
--- a/src/test/java/org/apache/commons/io/FileUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java
@@ -98,8 +98,6 @@ import org.junit.jupiter.params.provider.ValueSource;
 @SuppressWarnings({"deprecation", "ResultOfMethodCallIgnored"}) // unit tests include tests of many deprecated methods
 public class FileUtilsTest extends AbstractTempDirTest {
 
-    private static final Path DIR_SIZE_1 = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1");
-
     /**
      * DirectoryWalker implementation that recursively lists all files and directories.
      */
@@ -128,6 +126,8 @@ public class FileUtilsTest extends AbstractTempDirTest {
         }
     }
 
+    private static final Path DIR_SIZE_1 = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1");
+
     private static final String UTF_8 = StandardCharsets.UTF_8.name();
 
     /** Test data. */
diff --git a/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java b/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
index 8b29bd03..d2ef1638 100644
--- a/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
+++ b/src/test/java/org/apache/commons/io/file/attribute/FileTimesTest.java
@@ -141,20 +141,14 @@ public class FileTimesTest {
         assertEquals(isUnixTime, FileTimes.isUnixTime(FileTime.from(Instant.parse(instant))));
     }
 
-    @ParameterizedTest
-    @MethodSource("isUnixFileTimeProvider")
-    public void testIsUnixTimeLong(final String instant, final boolean isUnixTime) {
-        assertEquals(isUnixTime, FileTimes.isUnixTime(Instant.parse(instant).getEpochSecond()));
+    public void testIsUnixTimeFileTimeNull() {
+        assertTrue(FileTimes.isUnixTime(null));
     }
 
     @ParameterizedTest
     @MethodSource("isUnixFileTimeProvider")
-    public void testToUnixTime(final String instant, final boolean isUnixTime) {
-        assertEquals(isUnixTime, FileTimes.isUnixTime(FileTimes.toUnixTime(FileTime.from(Instant.parse(instant)))));
-    }
-
-    public void testIsUnixTimeFileTimeNull() {
-        assertTrue(FileTimes.isUnixTime(null));
+    public void testIsUnixTimeLong(final String instant, final boolean isUnixTime) {
+        assertEquals(isUnixTime, FileTimes.isUnixTime(Instant.parse(instant).getEpochSecond()));
     }
 
     @Test
@@ -221,4 +215,10 @@ public class FileTimesTest {
         assertEquals(Instant.EPOCH.plusSeconds(seconds), FileTimes.plusSeconds(FileTimes.EPOCH, seconds).toInstant());
         assertEquals(Instant.EPOCH, FileTimes.plusSeconds(FileTimes.EPOCH, 0).toInstant());
     }
+
+    @ParameterizedTest
+    @MethodSource("isUnixFileTimeProvider")
+    public void testToUnixTime(final String instant, final boolean isUnixTime) {
+        assertEquals(isUnixTime, FileTimes.isUnixTime(FileTimes.toUnixTime(FileTime.from(Instant.parse(instant)))));
+    }
 }