You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sa...@apache.org on 2006/03/07 01:49:20 UTC

svn commit: r383730 - in /jakarta/commons/proper/io/trunk/src: java/org/apache/commons/io/ test/org/apache/commons/io/

Author: sandymac
Date: Mon Mar  6 16:49:18 2006
New Revision: 383730

URL: http://svn.apache.org/viewcvs?rev=383730&view=rev
Log:
Cleaned up LineIterator changes include:
* Removed the IOIterator interface, it can be added back later when there is more than one
Iterator implementations with a close method.
* Doesn't automatically close the Reader at EOF.
* made LineIterator final because the hasNext method isn't implemented in a subclassable way.
* constructor throws an IllegaArgumentException, not a NPE when the argument is bogus.

Removed:
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOIterator.java
Modified:
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java
    jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java
    jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java

Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java?rev=383730&r1=383729&r2=383730&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java (original)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileUtils.java Mon Mar  6 16:49:18 2006
@@ -24,6 +24,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.io.FileReader;
+import java.io.Reader;
 import java.net.URL;
 import java.util.Collection;
 import java.util.Date;
@@ -923,22 +925,9 @@
 
     /**
      * Return an Iterator for the lines in a <code>File</code>.
-     * Please read the javadoc of {@link LineIterator} to understand
-     * whether you should close the iterator.
-     * The file is closed if an exception is thrown during this method.
-     * <p>
-     * The recommended usage patterm is:
-     * <pre>
-     * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
-     * try {
-     *   while (it.hasNext()) {
-     *     String line = it.nextLine();
-     *     /// do something with line
-     *   }
-     * } finally {
-     *   LineIterator.closeQuietly(iterator);
-     * }
-     * </pre>
+     * This neccessitates creating an InputStream for the file. The only ways
+     * to close this stream are to call {@link LineIterator#close()} or let
+     * the <code>LineIterator</code> be garbage collected.
      * <p>
      * There is no lineIterator method without encoding parameter because
      * the default encoding can differ between platforms and will have

Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java?rev=383730&r1=383729&r2=383730&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java (original)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/IOUtils.java Mon Mar  6 16:49:18 2006
@@ -509,21 +509,9 @@
     //-----------------------------------------------------------------------
     /**
      * Return an Iterator for the lines in a <code>Reader</code>.
-     * Please read the javadoc of {@link LineIterator} to understand
-     * whether you should close the iterator.
-     * <p>
-     * The recommended usage pattern is:
-     * <pre>
-     * LineIterator it = IOUtils.lineIterator(reader);
-     * try {
-     *   while (it.hasNext()) {
-     *     String line = it.nextLine();
-     *     /// do something with line
-     *   }
-     * } finally {
-     *   LineIterator.closeQuietly(iterator);
-     * }
-     * </pre>
+     * Unless you keep a reference to the <code>InputStream</code> the
+     * only way to close it is to call {@link LineIterator#close()} or
+     * wait for the garbage collector.
      *
      * @param reader  the <code>Reader</code> to read from, not null
      * @return an Iterator of the lines in the reader, never null
@@ -537,21 +525,9 @@
     /**
      * Return an Iterator for the lines in an <code>InputStream</code>, using
      * the character encoding specified (or default encoding if null).
-     * Please read the javadoc of {@link LineIterator} to understand
-     * whether you should close the iterator.
-     * <p>
-     * The recommended usage pattern is:
-     * <pre>
-     * LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
-     * try {
-     *   while (it.hasNext()) {
-     *     String line = it.nextLine();
-     *     /// do something with line
-     *   }
-     * } finally {
-     *   LineIterator.closeQuietly(iterator);
-     * }
-     * </pre>
+     * Unless you keep a reference to the <code>InputStream</code> the
+     * only way to close it is to call {@link LineIterator#close()} or
+     * wait for the garbage collector.
      *
      * @param input  the <code>InputStream</code> to read from, not null
      * @param encoding  the encoding to use, null means platform default
@@ -562,7 +538,7 @@
      */
     public static LineIterator lineIterator(InputStream input, String encoding) 
                      throws IOException {
-        InputStreamReader reader = null;
+        Reader reader = null;
         if (encoding == null) {
             reader = new InputStreamReader(input);
         } else {

Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java?rev=383730&r1=383729&r2=383730&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java (original)
+++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/LineIterator.java Mon Mar  6 16:49:18 2006
@@ -22,32 +22,23 @@
 
 /**
  * An Iterator over the lines in a <code>Reader</code>.
+ *
  * <p>
- * This iterator must be closed after use to avoid a resource leak.
- * If you read every line, then the final {@link #hasNext()} method
- * will close the iterator. If you do not fully read the iterator
- * then you must call the {@link #close()} method.
- * <p>
- * However, since the iterator methods can throw exception, we recommend
- * always calling close in a finally block:
- * <pre>
- * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
- * try {
- *   while (it.hasNext()) {
- *     String line = it.nextLine();
- *     /// do something with line
- *   }
- * } finally {
- *   LineIterator.closeQuietly(iterator);
- * }
- * </pre>
+ * If you do not wish to maintain a reference to the <code>Reader</code>
+ * you can call {@link #close()} to close the backing <code>Reader</code>
+ * and free an interal resources.
  *
  * @author Niall Pemberton
  * @author Stephen Colebourne
+ * @author Sandy McArthur
  * @version $Id$
  * @since Commons IO 1.2
  */
-public class LineIterator implements IOIterator {
+/*
+ * XXX: hasNext() should be reworked so this class can be
+ * meaningfully subclassed before the final below is removed.
+ */
+public final class LineIterator {
 
     /** The reader that is being read. */
     private final BufferedReader bufferedReader;
@@ -60,22 +51,24 @@
      * Constructs an iterator of the lines for a <code>Reader</code>.
      *
      * @param reader the <code>Reader</code> to read from, not null
-     * @throws NullPointerException if the reader is null
+     * @throws IllegalArgumentException if the reader is null
      */
-    public LineIterator(Reader reader) {
+    public LineIterator(final Reader reader) throws IllegalArgumentException {
         if (reader == null) {
-            throw new NullPointerException("Reader must not be null");
+            throw new IllegalArgumentException("Reader must not be null.");
         }
         if (reader instanceof BufferedReader) {
-            this.bufferedReader = (BufferedReader) reader;
+            bufferedReader = (BufferedReader) reader;
         } else {
-            this.bufferedReader = new BufferedReader(reader);
+            bufferedReader = new BufferedReader(reader);
         }
     }
 
     //-----------------------------------------------------------------------
     /**
      * Indicates whether the <code>Reader</code> has more lines.
+     * If there is an <code>IOException</code> then {@link #close()} will
+     * be called on this instance.
      *
      * @return <code>true</code> if the Reader has more lines
      * @throws IllegalStateException if an IO exception occurs
@@ -89,7 +82,7 @@
             try {
                 cachedLine = bufferedReader.readLine();
                 if (cachedLine == null) {
-                    close();
+                    finished = true;
                     return false;
                 } else {
                     return true;
@@ -130,15 +123,13 @@
      * Closes the underlying <code>Reader</code> quietly.
      * 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</code> remains open and is a resource leak.
+     * then the <code>Reader</code> remains open.
      * This method can safely be called multiple times.
      */
     public void close() {
-        if (!finished) {
-            IOUtils.closeQuietly(bufferedReader);
-            finished = true;
-            cachedLine = null;
-        }
+        finished = true;
+        IOUtils.closeQuietly(bufferedReader);
+        cachedLine = null;
     }
 
     /**

Modified: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java?rev=383730&r1=383729&r2=383730&view=diff
==============================================================================
--- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java (original)
+++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/LineIteratorTestCase.java Mon Mar  6 16:49:18 2006
@@ -74,7 +74,7 @@
         try {
             new LineIterator((Reader) null);
             fail();
-        } catch (NullPointerException ex) {
+        } catch (IllegalArgumentException ex) {
             // expected
         }
     }
@@ -116,11 +116,10 @@
         LineIterator iterator = null;
         try {
             iterator = FileUtils.lineIterator(testFile, "UTF-8");
+            iterator.close();
             fail("Expected FileNotFoundException");
         } catch(FileNotFoundException expected) {
             // ignore, expected result
-        } finally {
-            LineIterator.closeQuietly(iterator);
         }
     }
 
@@ -134,16 +133,13 @@
         createFile(testFile, encoding, 3);
         
         LineIterator iterator = FileUtils.lineIterator(testFile, encoding);
-        try {
-            int count = 0;
-            while (iterator.hasNext()) {
-                assertTrue(iterator.next() instanceof String);
-                count++;
-            }
-            assertEquals(3, count);
-        } finally {
-            LineIterator.closeQuietly(iterator);
+        int count = 0;
+        while (iterator.hasNext()) {
+            assertTrue(iterator.next() instanceof String);
+            count++;
         }
+        iterator.close();
+        assertEquals(3, count);
     }
 
     /**
@@ -158,11 +154,10 @@
         LineIterator iterator = null;
         try {
             iterator = FileUtils.lineIterator(testFile, encoding);
+            iterator.close();
             fail("Expected UnsupportedEncodingException");
         } catch(UnsupportedEncodingException expected) {
             // ignore, expected result
-        } finally {
-            LineIterator.closeQuietly(iterator);
         }
     }
 
@@ -176,15 +171,12 @@
         List lines = createFile(testFile, encoding, 3);
         
         LineIterator iterator = FileUtils.lineIterator(testFile, encoding);
-        try {
-            for (int i = 0; i < lines.size(); i++) {
-                String line = (String) iterator.next();
-                assertEquals("next() line " + i, lines.get(i), line);
-            }
-            assertEquals("No more expected", false, iterator.hasNext());
-        } finally {
-            LineIterator.closeQuietly(iterator);
+        for (int i = 0; i < lines.size(); i++) {
+            String line = (String)iterator.next();
+            assertEquals("next() line " + i, lines.get(i), line);
         }
+        assertEquals("No more expected", false, iterator.hasNext());
+        iterator.close();
     }
 
     /**
@@ -197,15 +189,12 @@
         List lines = createFile(testFile, encoding, 3);
         
         LineIterator iterator = FileUtils.lineIterator(testFile, encoding);
-        try {
-            for (int i = 0; i < lines.size(); i++) {
-                String line = iterator.nextLine();
-                assertEquals("nextLine() line " + i, lines.get(i), line);
-            }
-            assertFalse("No more expected", iterator.hasNext());
-        } finally {
-            LineIterator.closeQuietly(iterator);
+        for (int i = 0; i < lines.size(); i++) {
+            String line = iterator.nextLine();
+            assertEquals("nextLine() line " + i, lines.get(i), line);
         }
+        assertFalse("No more expected", iterator.hasNext());
+        iterator.close();
     }
 
     /**
@@ -218,47 +207,44 @@
         File testFile = new File(getTestDirectory(), "LineIterator-closeEarly.txt");
         createFile(testFile, encoding, 3);
         
-        LineIterator iterator = null;
+        LineIterator iterator = FileUtils.lineIterator(testFile, encoding);
+
+        // get
+        assertTrue("Line expected", iterator.next() instanceof String);
+        assertTrue("More expected", iterator.hasNext());
+
+        // close
+        iterator.close();
+        assertFalse("No more expected", iterator.hasNext());
+        try {
+            iterator.next();
+            fail();
+        } catch (NoSuchElementException ex) {
+            // expected
+        }
         try {
-            iterator = FileUtils.lineIterator(testFile, encoding);
-            
-            // get
-            assertTrue("Line expected", iterator.next() instanceof String);
-            assertTrue("More expected", iterator.hasNext());
-            
-            // close
-            iterator.close();
-            assertFalse("No more expected", iterator.hasNext());
-            try {
-                iterator.next();
-                fail();
-            } catch (NoSuchElementException ex) {
-                // expected
-            }
-            try {
-                iterator.nextLine();
-                fail();
-            } catch (NoSuchElementException ex) {
-                // expected
-            }
-            
-            // try closing again
-            iterator.close();
-            try {
-                iterator.next();
-                fail();
-            } catch (NoSuchElementException ex) {
-                // expected
-            }
-            try {
-                iterator.nextLine();
-                fail();
-            } catch (NoSuchElementException ex) {
-                // expected
-            }
-        } finally {
-            LineIterator.closeQuietly(iterator);
+            iterator.nextLine();
+            fail();
+        } catch (NoSuchElementException ex) {
+            // expected
+        }
+
+        // try closing again
+        iterator.close();
+        try {
+            iterator.next();
+            fail();
+        } catch (NoSuchElementException ex) {
+            // expected
         }
+        try {
+            iterator.nextLine();
+            fail();
+        } catch (NoSuchElementException ex) {
+            // expected
+        }
+
+        iterator.close();
     }
 
     /**
@@ -272,42 +258,39 @@
         File testFile = new File(getTestDirectory(), fileName);
         List lines = createFile(testFile, encoding, lineCount);
         
-        LineIterator iterator = null;
+        LineIterator iterator = FileUtils.lineIterator(testFile, encoding);
+
         try {
-            iterator = FileUtils.lineIterator(testFile, encoding);
-            
-            try {
-                iterator.remove();
-                fail("Remove is unsupported");
-            } catch (UnsupportedOperationException ex) {
-                // expected
-            }
-            
-            int idx = 0;
-            while (iterator.hasNext()) {
-                String line = (String)iterator.next();
-                assertEquals("Comparing line " + idx, lines.get(idx), line);
-                assertTrue("Exceeded expected idx=" + idx + " size=" + lines.size(), idx < lines.size());
-                idx++;
-            }
-            assertEquals("Line Count doesn't match", idx, lines.size());
-            
-            // try calling next() after file processed
-            try {
-                iterator.next();
-                fail("Expected NoSuchElementException");
-            } catch (NoSuchElementException expected) {
-                // ignore, expected result
-            }
-            try {
-                iterator.nextLine();
-                fail("Expected NoSuchElementException");
-            } catch (NoSuchElementException expected) {
-                // ignore, expected result
-            }
-        } finally {
-            LineIterator.closeQuietly(iterator);
+            iterator.remove();
+            fail("Remove is unsupported");
+        } catch (UnsupportedOperationException ex) {
+            // expected
+        }
+
+        int idx = 0;
+        while (iterator.hasNext()) {
+            String line = (String)iterator.next();
+            assertEquals("Comparing line " + idx, lines.get(idx), line);
+            assertTrue("Exceeded expected idx=" + idx + " size=" + lines.size(), idx < lines.size());
+            idx++;
+        }
+        assertEquals("Line Count doesn't match", idx, lines.size());
+
+        // try calling next() after file processed
+        try {
+            iterator.next();
+            fail("Expected NoSuchElementException");
+        } catch (NoSuchElementException expected) {
+            // ignore, expected result
         }
+        try {
+            iterator.nextLine();
+            fail("Expected NoSuchElementException");
+        } catch (NoSuchElementException expected) {
+            // ignore, expected result
+        }
+
+        iterator.close();
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org