On Fri, Jan 28, 2011 at 2:48 PM, Jörn Kottmann <[email protected]> wrote:
> On 1/28/11 11:06 AM, Steven Bethard wrote:
>> Again, I'm not asking for Iterators*instead of*  whatever custom
>> protocol you want to design. I'm asking for them*in addition to*  your
>> protocol.
[snip]
> // The created Iterator also implements Iterable
> ObjectStreamUtils.toIterator(ObjectStream)

Sure, I guess you could make it a static method, though I don't see
why you couldn't just add the method to AbstractEventStream (or
whatever the equivalent for ObjectStreams is). Here's what I would
really like to write:

InputStream in = new FileInputStream("your-file.train);
PlainTextByLineStream stream = new PlainTextByLineStream(in, "UTF-8")
for (String line: stream) {
    ...
}
stream.close();

This would appear in the body of a function declared as "throws
IOException" since I can't do anything useful if the IO fails here.
But see below for how someone who wants to handle such exceptions
could.

> How do you want to get around the exception handling
> the java IO interface forces you to do ?

You mean, how do I implement iterator() when read() throws an
IOException? Here's the code:

public abstract class AbstractObjectStream<T> implements
ObjectStream<T>, Iterable<T> {
  public Iterator<T> iterator() {
    return new Iterator<T>() {

      private T next = this.readNext();

      @Override
      public boolean hasNext() {
        return this.next != null;
      }

      @Override
      public T next() {
        T result = this.next;
        this.next = this.readNext();
        return result;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException();
      }

      private T readNext() {
        try {
          return read(); // calling ObjectStream.read() here
        } catch (IOException e) {
          throw new RuntimeIOException(e);
        }
      }
    };
  }
}

That's it. Now just have PlainTextByLineStream subclass
AbstractObjectStream and the earlier code snippet will work perfectly.

> Would you bother to close the stream ? Or do you do not
> want to do this also ?

The iterator shouldn't close the stream. That's the responsibility of
whoever opened in the IO stream. In the code sample above, you can see
that I close the PlainTextByLineStream at the end of the code snippet.
The Iterator is just wrapping the read() method with the standard Java
Iterator API.

> In the end you somehow have to handle the IOExceptions, thats
> just how the Java API is made.

Sure. See above. Or perhaps you meant, how would a user who wanted to
use the Iterator API and also wanted to handle the IOExceptions write
the code? Well, I'd contend that a user who is working with this kind
of low level detail probably wants to use the ObjectStream API.
(Remember, we're talking about both APIs being available at the same
time, so you can choose whichever is most appropriate).

But someone really wants to use the Iterator API and handle
exceptions, they would do something like:

InputStream in = new FileInputStream("your-file.train);
PlainTextByLineStream stream = new PlainTextByLineStream(in, "UTF-8")
try {
    for (String line: stream) {
        ...
    }
} catch (RuntimeIOException e) {
    ... handle exception during iteration ...
}
try {
    stream.close();
} catch (RuntimeIOException e) {
    ... handle exception during close ...
}

On Sat, Jan 29, 2011 at 12:37 AM, James Kosin <[email protected]> wrote:
> Lets even take your argument to the level you are talking about.... then
> why doesn't Java implement all file I/O as an Iterator and get rid of
> the implementation they already have for file I/O?

Let me say it again, I'm not asking for an Iterator *instead of* the
ObjectStream (or any other IO API). I'm asking for it *in addition to*
the current API. So the "get rid of" above doesn't make any sense in
the context we're talking about.

Let me answer a slightly different question that is appropriate to the
current discussion: "Why don't the Java I/O streams provide iterator()
methods?" The answer is pretty simple - Iterator didn't really become
important until Java 5 when it became part of Iterable and the
enhanced for loop. All the IO code (even the "new" java.nio) is older
than that.

> File I/O isn't nice to be iterating through; because (1) in order for
> you to know if there is a next you would have to read the stream... and
> save the result somewhere....

It's not too hard. See AbstractObjectStream.iterator() above.

> (2) iterators were never meant to be closed

Yep, that's right - you still need to call .close() on the stream.
Iterators are not a replacement for streams.

Steve
-- 
Where did you get that preposterous hypothesis?
Did Steve tell you that?
        --- The Hiphopopotamus

Reply via email to