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 2020/08/18 19:17:27 UTC

[commons-io] branch master updated: Sort methods in AB order.

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


The following commit(s) were added to refs/heads/master by this push:
     new 9a212e8  Sort methods in AB order.
9a212e8 is described below

commit 9a212e86adc1828f8ff998956a14699fe337a38f
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Aug 18 15:17:17 2020 -0400

    Sort methods in AB order.
---
 .../commons/io/input/ReversedLinesFileReader.java  | 392 ++++++++++-----------
 1 file changed, 196 insertions(+), 196 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
index d5f3fdd..872222e 100644
--- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
+++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java
@@ -43,19 +43,178 @@ import org.apache.commons.io.IOUtils;
  */
 public class ReversedLinesFileReader implements Closeable {
 
+    private class FilePart {
+        private final long no;
+
+        private final byte[] data;
+
+        private byte[] leftOver;
+
+        private int currentLastBytePos;
+
+        /**
+         * ctor
+         * @param no the part number
+         * @param length its length
+         * @param leftOverOfLastFilePart remainder
+         * @throws IOException if there is a problem reading the file
+         */
+        private FilePart(final long no, final int length, final byte[] leftOverOfLastFilePart) throws IOException {
+            this.no = no;
+            final int dataLength = length + (leftOverOfLastFilePart != null ? leftOverOfLastFilePart.length : 0);
+            this.data = new byte[dataLength];
+            final long off = (no - 1) * blockSize;
+
+            // read data
+            if (no > 0 /* file not empty */) {
+                channel.position(off);
+                final int countRead = channel.read(ByteBuffer.wrap(data, 0, length));
+                if (countRead != length) {
+                    throw new IllegalStateException("Count of requested bytes and actually read bytes don't match");
+                }
+            }
+            // copy left over part into data arr
+            if (leftOverOfLastFilePart != null) {
+                System.arraycopy(leftOverOfLastFilePart, 0, data, length, leftOverOfLastFilePart.length);
+            }
+            this.currentLastBytePos = data.length - 1;
+            this.leftOver = null;
+        }
+
+        /**
+         * Creates the buffer containing any left over bytes.
+         */
+        private void createLeftOver() {
+            final int lineLengthBytes = currentLastBytePos + 1;
+            if (lineLengthBytes > 0) {
+                // create left over for next block
+                leftOver = new byte[lineLengthBytes];
+                System.arraycopy(data, 0, leftOver, 0, lineLengthBytes);
+            } else {
+                leftOver = null;
+            }
+            currentLastBytePos = -1;
+        }
+
+        /**
+         * Finds the new-line sequence and return its length.
+         *
+         * @param data buffer to scan
+         * @param i start offset in buffer
+         * @return length of newline sequence or 0 if none found
+         */
+        private int getNewLineMatchByteCount(final byte[] data, final int i) {
+            for (final byte[] newLineSequence : newLineSequences) {
+                boolean match = true;
+                for (int j = newLineSequence.length - 1; j >= 0; j--) {
+                    final int k = i + j - (newLineSequence.length - 1);
+                    match &= k >= 0 && data[k] == newLineSequence[j];
+                }
+                if (match) {
+                    return newLineSequence.length;
+                }
+            }
+            return 0;
+        }
+
+        /**
+         * Reads a line.
+         *
+         * @return the line or null
+         * @throws IOException if there is an error reading from the file
+         */
+        private String readLine() throws IOException {
+
+            String line = null;
+            int newLineMatchByteCount;
+
+            final boolean isLastFilePart = no == 1;
+
+            int i = currentLastBytePos;
+            while (i > -1) {
+
+                if (!isLastFilePart && i < avoidNewlineSplitBufferSize) {
+                    // avoidNewlineSplitBuffer: for all except the last file part we
+                    // take a few bytes to the next file part to avoid splitting of newlines
+                    createLeftOver();
+                    break; // skip last few bytes and leave it to the next file part
+                }
+
+                // --- check for newline ---
+                if ((newLineMatchByteCount = getNewLineMatchByteCount(data, i)) > 0 /* found newline */) {
+                    final int lineStart = i + 1;
+                    final int lineLengthBytes = currentLastBytePos - lineStart + 1;
+
+                    if (lineLengthBytes < 0) {
+                        throw new IllegalStateException("Unexpected negative line length="+lineLengthBytes);
+                    }
+                    final byte[] lineData = new byte[lineLengthBytes];
+                    System.arraycopy(data, lineStart, lineData, 0, lineLengthBytes);
+
+                    line = new String(lineData, encoding);
+
+                    currentLastBytePos = i - newLineMatchByteCount;
+                    break; // found line
+                }
+
+                // --- move cursor ---
+                i -= byteDecrement;
+
+                // --- end of file part handling ---
+                if (i < 0) {
+                    createLeftOver();
+                    break; // end of file part
+                }
+            }
+
+            // --- last file part handling ---
+            if (isLastFilePart && leftOver != null) {
+                // there will be no line break anymore, this is the first line of the file
+                line = new String(leftOver, encoding);
+                leftOver = null;
+            }
+
+            return line;
+        }
+
+        /**
+         * Handles block rollover
+         *
+         * @return the new FilePart or null
+         * @throws IOException if there was a problem reading the file
+         */
+        private FilePart rollOver() throws IOException {
+
+            if (currentLastBytePos > -1) {
+                throw new IllegalStateException("Current currentLastCharPos unexpectedly positive... "
+                        + "last readLine() should have returned something! currentLastCharPos=" + currentLastBytePos);
+            }
+
+            if (no > 1) {
+                return new FilePart(no - 1, blockSize, leftOver);
+            }
+            // NO 1 was the last FilePart, we're finished
+            if (leftOver != null) {
+                throw new IllegalStateException("Unexpected leftover of the last block: leftOverOfThisFilePart="
+                        + new String(leftOver, encoding));
+            }
+            return null;
+        }
+    }
     private static final String EMPTY_STRING = "";
-    private static final int DEFAULT_BLOCK_SIZE = IOUtils.DEFAULT_BUFFER_SIZE;
 
+    private static final int DEFAULT_BLOCK_SIZE = IOUtils.DEFAULT_BUFFER_SIZE;
     private final int blockSize;
+
     private final Charset encoding;
 
     private final SeekableByteChannel channel;
-
     private final long totalByteLength;
-    private final long totalBlockCount;
 
+    private final long totalBlockCount;
     private final byte[][] newLineSequences;
     private final int avoidNewlineSplitBufferSize;
+
     private final int byteDecrement;
 
     private FilePart currentFilePart;
@@ -91,17 +250,20 @@ public class ReversedLinesFileReader implements Closeable {
     }
 
     /**
-     * Creates a ReversedLinesFileReader with default block size of 4KB and the
-     * specified encoding.
+     * Creates a ReversedLinesFileReader with the given block size and encoding.
      *
      * @param file
      *            the file to be read
-     * @param charset the charset to use
+     * @param blockSize
+     *            size of the internal buffer (for ideal performance this should
+     *            match with the block size of the underlying file system).
+     * @param encoding
+     *            the encoding of the file
      * @throws IOException  if an I/O error occurs
-     * @since 2.7
+     * @since 2.3
      */
-    public ReversedLinesFileReader(final Path file, final Charset charset) throws IOException {
-        this(file, DEFAULT_BLOCK_SIZE, charset);
+    public ReversedLinesFileReader(final File file, final int blockSize, final Charset encoding) throws IOException {
+        this(file.toPath(), blockSize, encoding);
     }
 
     /**
@@ -115,13 +277,28 @@ public class ReversedLinesFileReader implements Closeable {
      * @param encoding
      *            the encoding of the file
      * @throws IOException  if an I/O error occurs
-     * @since 2.3
+     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link UnsupportedEncodingException} in
+     * version 2.2 if the encoding is not supported.
      */
-    public ReversedLinesFileReader(final File file, final int blockSize, final Charset encoding) throws IOException {
+    public ReversedLinesFileReader(final File file, final int blockSize, final String encoding) throws IOException {
         this(file.toPath(), blockSize, encoding);
     }
 
     /**
+     * Creates a ReversedLinesFileReader with default block size of 4KB and the
+     * specified encoding.
+     *
+     * @param file
+     *            the file to be read
+     * @param charset the charset to use
+     * @throws IOException  if an I/O error occurs
+     * @since 2.7
+     */
+    public ReversedLinesFileReader(final Path file, final Charset charset) throws IOException {
+        this(file, DEFAULT_BLOCK_SIZE, charset);
+    }
+
+    /**
      * Creates a ReversedLinesFileReader with the given block size and encoding.
      *
      * @param file
@@ -197,33 +374,25 @@ public class ReversedLinesFileReader implements Closeable {
      * @param blockSize
      *            size of the internal buffer (for ideal performance this should
      *            match with the block size of the underlying file system).
-     * @param encoding
+     * @param charsetName
      *            the encoding of the file
      * @throws IOException  if an I/O error occurs
      * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link UnsupportedEncodingException} in
      * version 2.2 if the encoding is not supported.
+     * @since 2.7
      */
-    public ReversedLinesFileReader(final File file, final int blockSize, final String encoding) throws IOException {
-        this(file.toPath(), blockSize, encoding);
+    public ReversedLinesFileReader(final Path file, final int blockSize, final String charsetName) throws IOException {
+        this(file, blockSize, Charsets.toCharset(charsetName));
     }
 
     /**
-     * Creates a ReversedLinesFileReader with the given block size and encoding.
+     * Closes underlying resources.
      *
-     * @param file
-     *            the file to be read
-     * @param blockSize
-     *            size of the internal buffer (for ideal performance this should
-     *            match with the block size of the underlying file system).
-     * @param charsetName
-     *            the encoding of the file
      * @throws IOException  if an I/O error occurs
-     * @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link UnsupportedEncodingException} in
-     * version 2.2 if the encoding is not supported.
-     * @since 2.7
      */
-    public ReversedLinesFileReader(final Path file, final int blockSize, final String charsetName) throws IOException {
-        this(file, blockSize, Charsets.toCharset(charsetName));
+    @Override
+    public void close() throws IOException {
+        channel.close();
     }
 
     /**
@@ -283,173 +452,4 @@ public class ReversedLinesFileReader implements Closeable {
         return arrayList;
     }
 
-    /**
-     * Closes underlying resources.
-     *
-     * @throws IOException  if an I/O error occurs
-     */
-    @Override
-    public void close() throws IOException {
-        channel.close();
-    }
-
-    private class FilePart {
-        private final long no;
-
-        private final byte[] data;
-
-        private byte[] leftOver;
-
-        private int currentLastBytePos;
-
-        /**
-         * ctor
-         * @param no the part number
-         * @param length its length
-         * @param leftOverOfLastFilePart remainder
-         * @throws IOException if there is a problem reading the file
-         */
-        private FilePart(final long no, final int length, final byte[] leftOverOfLastFilePart) throws IOException {
-            this.no = no;
-            final int dataLength = length + (leftOverOfLastFilePart != null ? leftOverOfLastFilePart.length : 0);
-            this.data = new byte[dataLength];
-            final long off = (no - 1) * blockSize;
-
-            // read data
-            if (no > 0 /* file not empty */) {
-                channel.position(off);
-                final int countRead = channel.read(ByteBuffer.wrap(data, 0, length));
-                if (countRead != length) {
-                    throw new IllegalStateException("Count of requested bytes and actually read bytes don't match");
-                }
-            }
-            // copy left over part into data arr
-            if (leftOverOfLastFilePart != null) {
-                System.arraycopy(leftOverOfLastFilePart, 0, data, length, leftOverOfLastFilePart.length);
-            }
-            this.currentLastBytePos = data.length - 1;
-            this.leftOver = null;
-        }
-
-        /**
-         * Handles block rollover
-         *
-         * @return the new FilePart or null
-         * @throws IOException if there was a problem reading the file
-         */
-        private FilePart rollOver() throws IOException {
-
-            if (currentLastBytePos > -1) {
-                throw new IllegalStateException("Current currentLastCharPos unexpectedly positive... "
-                        + "last readLine() should have returned something! currentLastCharPos=" + currentLastBytePos);
-            }
-
-            if (no > 1) {
-                return new FilePart(no - 1, blockSize, leftOver);
-            }
-            // NO 1 was the last FilePart, we're finished
-            if (leftOver != null) {
-                throw new IllegalStateException("Unexpected leftover of the last block: leftOverOfThisFilePart="
-                        + new String(leftOver, encoding));
-            }
-            return null;
-        }
-
-        /**
-         * Reads a line.
-         *
-         * @return the line or null
-         * @throws IOException if there is an error reading from the file
-         */
-        private String readLine() throws IOException {
-
-            String line = null;
-            int newLineMatchByteCount;
-
-            final boolean isLastFilePart = no == 1;
-
-            int i = currentLastBytePos;
-            while (i > -1) {
-
-                if (!isLastFilePart && i < avoidNewlineSplitBufferSize) {
-                    // avoidNewlineSplitBuffer: for all except the last file part we
-                    // take a few bytes to the next file part to avoid splitting of newlines
-                    createLeftOver();
-                    break; // skip last few bytes and leave it to the next file part
-                }
-
-                // --- check for newline ---
-                if ((newLineMatchByteCount = getNewLineMatchByteCount(data, i)) > 0 /* found newline */) {
-                    final int lineStart = i + 1;
-                    final int lineLengthBytes = currentLastBytePos - lineStart + 1;
-
-                    if (lineLengthBytes < 0) {
-                        throw new IllegalStateException("Unexpected negative line length="+lineLengthBytes);
-                    }
-                    final byte[] lineData = new byte[lineLengthBytes];
-                    System.arraycopy(data, lineStart, lineData, 0, lineLengthBytes);
-
-                    line = new String(lineData, encoding);
-
-                    currentLastBytePos = i - newLineMatchByteCount;
-                    break; // found line
-                }
-
-                // --- move cursor ---
-                i -= byteDecrement;
-
-                // --- end of file part handling ---
-                if (i < 0) {
-                    createLeftOver();
-                    break; // end of file part
-                }
-            }
-
-            // --- last file part handling ---
-            if (isLastFilePart && leftOver != null) {
-                // there will be no line break anymore, this is the first line of the file
-                line = new String(leftOver, encoding);
-                leftOver = null;
-            }
-
-            return line;
-        }
-
-        /**
-         * Creates the buffer containing any left over bytes.
-         */
-        private void createLeftOver() {
-            final int lineLengthBytes = currentLastBytePos + 1;
-            if (lineLengthBytes > 0) {
-                // create left over for next block
-                leftOver = new byte[lineLengthBytes];
-                System.arraycopy(data, 0, leftOver, 0, lineLengthBytes);
-            } else {
-                leftOver = null;
-            }
-            currentLastBytePos = -1;
-        }
-
-        /**
-         * Finds the new-line sequence and return its length.
-         *
-         * @param data buffer to scan
-         * @param i start offset in buffer
-         * @return length of newline sequence or 0 if none found
-         */
-        private int getNewLineMatchByteCount(final byte[] data, final int i) {
-            for (final byte[] newLineSequence : newLineSequences) {
-                boolean match = true;
-                for (int j = newLineSequence.length - 1; j >= 0; j--) {
-                    final int k = i + j - (newLineSequence.length - 1);
-                    match &= k >= 0 && data[k] == newLineSequence[j];
-                }
-                if (match) {
-                    return newLineSequence.length;
-                }
-            }
-            return 0;
-        }
-    }
-
 }