All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.io.LineIterator Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.io;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;

/**
 * An Iterator over the lines in a Reader.
 * 

* LineIterator holds a reference to an open Reader. * When you have finished with the iterator you should close the reader * to free internal resources. This can be done by closing the reader directly, * or by calling the {@link #close()} or {@link #closeQuietly(LineIterator)} * method on the iterator. *

* The recommended usage pattern is: *

 * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
 * try {
 *   while (it.hasNext()) {
 *     String line = it.nextLine();
 *     // do something with line
 *   }
 * } finally {
 *   it.close();
 * }
 * 
* * @since 1.2 */ public class LineIterator implements Iterator, Closeable { // N.B. This class deliberately does not implement Iterable, see https://issues.apache.org/jira/browse/IO-181 /** The reader that is being read. */ private final BufferedReader bufferedReader; /** The current line. */ private @Nullable String cachedLine; /** A flag indicating if the iterator has been fully read. */ private boolean finished = false; /** * Constructs an iterator of the lines for a Reader. * * @param reader the Reader to read from, not null * @throws IllegalArgumentException if the reader is null */ public LineIterator(final Reader reader) throws IllegalArgumentException { if (reader == null) { throw new IllegalArgumentException("Reader must not be null"); } if (reader instanceof BufferedReader) { bufferedReader = (BufferedReader) reader; } else { bufferedReader = new BufferedReader(reader); } } //----------------------------------------------------------------------- /** * Indicates whether the Reader has more lines. * If there is an IOException then {@link #close()} will * be called on this instance. * * @return {@code true} if the Reader has more lines * @throws IllegalStateException if an IO exception occurs */ @Override @EnsuresNonNullIf(expression = "cachedLine", result = true) public boolean hasNext() { if (cachedLine != null) { return true; } else if (finished) { return false; } else { try { while (true) { final String line = bufferedReader.readLine(); if (line == null) { finished = true; return false; } else if (isValidLine(line)) { cachedLine = line; return true; } } } catch(final IOException ioe) { IOUtils.closeQuietly(this, e -> ioe.addSuppressed(e)); throw new IllegalStateException(ioe); } } } /** * Overridable method to validate each line that is returned. * This implementation always returns true. * @param line the line that is to be validated * @return true if valid, false to remove from the iterator */ protected boolean isValidLine(final String line) { return true; } /** * Returns the next line in the wrapped Reader. * * @return the next line from the input * @throws NoSuchElementException if there is no line to return */ @Override public String next() { return nextLine(); } /** * Returns the next line in the wrapped Reader. * * @return the next line from the input * @throws NoSuchElementException if there is no line to return */ public String nextLine() { if (!hasNext()) { throw new NoSuchElementException("No more lines"); } final String currentLine = cachedLine; cachedLine = null; return currentLine; } /** * 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 */ @Override public void remove() { throw new UnsupportedOperationException("Remove unsupported on LineIterator"); } //----------------------------------------------------------------------- /** * 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 @Nullable LineIterator iterator) { IOUtils.closeQuietly(iterator); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy