1 / 25

Streams and File I/O in Java

Streams and File I/O in Java. Eric Allen Rice University. Streams and Lazy Evaluation. Java I/O is based on the notion of streams Streams are sequences of data (whose elements may be computed on demand) Streams originated from functional programming, as an alternative to mutation.

betty_james
Download Presentation

Streams and File I/O in Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Streams and File I/O in Java Eric Allen Rice University

  2. Streams and Lazy Evaluation • Java I/O is based on the notion of streams • Streams are sequences of data (whose elements may be computed on demand) • Streams originated from functional programming, as an alternative to mutation

  3. A Very Simple Stream class OneStream extends IntStream { public int next() { return 1; } }

  4. A Slightly More Complex Stream public class NatStream { private int current = 0; public int next() { return current++; } }

  5. Streams And Computation • Streams can be composed and filtered to produce more complex streams • Let’s apply the Union, Composite, and Command Patterns to construct composable streams of ints…

  6. abstract class IntStream { public abstract int next(); } class NatStream extends IntStream { private int current = 0; public int next() { return current++; } }

  7. abstract class ComposableIntStream extends IntStream { private Operator op; private IntStream left; private IntStream right; public ComposableIntStream(Operator _op, IntStream _left, IntStream _right) { op = _op; left = _left; right = _right; } public int next() { return op.apply(left.next(), right.next()); } }

  8. abstract class Operator { public abstract int apply(int left, int right); } // for example, class Adder extends Operator { public int apply(int left, int right) { return left + right; } } // and class Multiplier extends Operator { public int apply(int left, int right) { return left * right; } }

  9. Now we can construct all sorts of nifty composable IntStreams: class EvenStream extends ComposableIntStream { public EvenStream() { super(new Adder(), new NatStream(), new NatStream()); } } class SquareStream extends ComposableIntStream { public SquareStream() { super(new Multiplier(), new NatStream(), new NatStream()); } }

  10. Building the Natural Numbers class ZeroStream extends IntStream { public int next() { return 0; } } class AdderStream extends ComposableIntStream { public AdderStream(IntStream left, IntStream right) { super(new Adder(), left, right); } }

  11. Building the Natural Numbers class AlternateNatStream extends IntStream { IntStream value = new ZeroStream(); public int next() { value = new AdderStream(new OneStream(), value); return value.next(); } }

  12. In fact, streams can be used as a foundation for all of number theory! • Exercise (optional/not for credit): Extend IntStreams to include a stream of prime numbers • Hint: define the notion of filtered streams, as a subtype of ComposableIntStreams

  13. Applications of Streams • Streams are natural models of many real-world systems: • Stock prices • Mouse/keyboard/monitor input • Radio signals • Human input to a program (DrJava interactions) • Contents of a file

  14. Output Streams Model Systems That Take Input • Just as we can read from sources, we can write to destinations • Output streams take input as it’s computed

  15. I/O Streams in Java • java.io.InputStream, java.io.OutputStream • Readers, writers are adapters to streams, to make certain sorts of I/O easier

  16. Reading from a File > FileReader fReader = new FileReader(fn); > fReader.read() 97 > (char)fReader.read() b

  17. Writing to a File > FileWriter fWriter = new FileWriter(fn); > fWriter.write()

  18. Testing Writers • Readers/Writers can be composed using PipedReaders and PipedWriters PipedReader pReader = new PipedReader(); PipedWriter pWriter = new PipedWriter(pReader);

  19. Testing Writers • By always writing to a Writer field (as opposed to hard-wired System.out, etc.), you can test your classes more easily • Pass in PipedWriters in your test cases and check what’s sent to a corresponding PipedReader

  20. Stream Tokenization • Often we want to view elements of a stream as structures larger than the elements themselves

  21. Stream Tokenization • Consider the syntactic components of a Java program: keywords, vars, etc. class C extends D implements E {…} • These elements are more complex than just characters

  22. Stream Tokenization In such cases, we can place a Façade stream over the original s.t. the elements of the Façade are sequences of the original elements

  23. Stream Tokenizer • Java provides a built-in StreamTokenizer class • Warning: The design of this class is ugly • Always put an Adapter class over it first (or write your own!) • This class is very powerful, but it’s biased toward parsing Java code

  24. Using StreamTokenizer • > Reader r = new BufferedReader(new InputStreamReader(si));  > StreamTokenizer tokenizer = new StreamTokenizer(r); > tokenizer.nextToken() 42

More Related