+ All Categories
Home > Documents > Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki...

Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki...

Date post: 31-Dec-2015
Category:
Upload: spencer-porter
View: 217 times
Download: 4 times
Share this document with a friend
40
Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki [email protected] http:// wbieniec.kis.p.lodz.pl
Transcript
Page 1: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Lecture 7 - streams

AdvancedJava

Programming

1

dr hab. Szymon Grabowskidr inż. Wojciech [email protected]://wbieniec.kis.p.lodz.pl

Page 2: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

What is a streamProgramming of I/O operationsin Java is to use streams that are class in the package java.io

Table: The ancestors of the class hierarchy stream - abstract classes

Input Output

Byte Streams InputStream OutputStream

Character sterams

Reader Writer

The data stream is a logical concept.

Means a structure similar to a queue to which the data can be added and from which data can be downloaded.

Basic operations on the stream: read and write data.

Page 3: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

3

Basic classes for reading and writing sequences of bytes are FileInputStream and FileOutputStream.

FileInputStream inp = new FileInputStream("1.dat");FileOutputStream outp = new FileOutputStream("2.dat");

Read a byte (0..255), write a byte: int read(); write(int);

Read value –1 signals the end of file.

The (main) hierarchy of input / output classes starts withabstract classes InputStream and OutputStream.

Intro to I/O

When we create a file object (eg. of any of the two just mentioned classes), the file is open.

Page 4: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

44

Don’t forgetexceptionhandling!

Byte-by-byte copy example

Page 5: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

5

We already know that read() is abstract.The methods

read(b) == read(b, 0, b.length)

If b.length == 0 (or param len == 0 in the latter method), then the methods return 0.Nothing to read (EOF)? The methods return –1.

read(...) methods from InputStream

int read(byte[ ] b),int read(byte[ ] b, int off, int len)

are non-abstract, but they internally invoke read().

Moral: any subclass of InputStreammust implement read().

Page 6: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Binding the stream with the source or receiver

Table: Subject classes (associated with a particular source / receiver)

Source/receiverCharacter streams Byte streams

Memory CharArrayReaderCharArrayWriter

ByteArrayInputStreamByteArrayOutputStream

StringReaderStringWriter

(not used because of improper byte-to-character conversion)

Pipeline (allows exchange data between two threads)

PipedReader PipedWriter

PipedInputStreamPipedOutputStream

File FileReader FileWriter

FileInputStreamFileOutputStream

Page 7: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

7

FileInputStream and FileOutputStream can read / write only bytes.

Fortunately, there are classes DataInputStream, DataOutputStream, but...their constructors obtain an abstract stream(InputStream, OutputStream, respectively).

How to work with files?

The solution is typical for Java I/O: combining filters.

FileInputStream fin = new FileInputStream("numbers.dat");DataInputStream din = new DataInputStream(fin);

double x = din.readDouble();

Combining stream functionalities

Would be useful to have classes for reading / writing int, longs, doubles...

Page 8: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

8

DataInputStream din = new DataInputStream(new BufferedInputStream(new FileInputStream("numbers.dat")));

The Decorator pattern lets us add functionality to an object at runtime.

Actually this is the Decorator design pattern

The idea. Object x from class X contains object y from Y. Object x will be called a decorator.

x forwards method calls to y.x conforms to the interface of y, which allowsthe decorator to be used as if x were an instance of Y.(But typically x has its own capabilities, not existing in y.)

Page 9: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

9

FileOutputStream(String name)FileOutputStream(String name, boolean append)FileOutputStream(File file)FileOutputStream(File file, boolean append)

append == true data are added at the end of the file(otherwise an existing file is deleted and start from scratch)

FileOutputStream constructors

Page 10: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Transforming classesIn I/O operations data transformation can be performed.

Type of processingCharacter streams Byte streams

Bufferinf BufferedReaderBufferedWriter

BufferedInputStreamBufferedOutputStream

Filtering – these classes define the methods for final filtersFinal filters are: DataInputStream & DataOutputStream, BufferedInputStream BufferedOutputStream. LineNumberInputStream, PushbackInputStream, PrintStream. You can create custom filters

FilterReaderFilterWriter

FilterInputStreamFilterOutputStream

Java has many classes specialized in automatic processing specific types of streams.

These classes implement certain types of process streams, regardless of the source / receiver

Page 11: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Transforming classesType of processing

Character streams Byte streams

Byte-to-character conversion

InputStreamReaderOutputStreamWriter

Concatenate SequenceInputStream

Object serialization ObjectInputStream ObjectOutputStream

Data conversion DataInputStream DataOutputStream

Line counting LineNumberReader LineNumberInputStream

Previewing PushbackReader PushbackInputStream

Printing PrintWriter PrintStream

To apply processing classes you must:Create an object associated with a physical source.receiverCreate an object that is overlayed on the physical stream

Page 12: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

12

Use FileReader, FileWriter classes.

FileReader: converts from the default codepage to Unicode. FileWriter: the other way around...

import java.io.*;public class ReadByReader { public static void main(String[] args) { StringBuffer cont = new StringBuffer(); try { FileReader inp = new FileReader(args[0]); int c; while ((c=inp.read()) != -1) cont.append((char)c); inp.close(); } catch(Exception e) { System.exit(1); } String s = cont.toString(); System.out.println(s); }}

Text I/O

Page 13: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

13

If the characters in the file to read adhere to non-standard encoding, don’t use FileReader.

FileInputStream fis = new FileInputStream("test.txt");InputStreamReader isr = new InputStreamReader(fis, "UTF8");

Non-standard character encoding

Use its parent class, InputStreamReader, instead.OutputStreamWriter for writing, of course.

Page 14: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

14

On slide 8, the method read(), from InputStreamReader (not FileReader), was used.

Reading a text (character) file

It reads a single char (a variant reading a number of chars into an array also exists).

For a greater flexibility, use Scanner.

Page 15: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

15

For writing to a text file, use PrintWriter

Page 16: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

BufferingBuffering reduces the number of physical references to external devices.

For example, reading large text files it should be avoided by reading the FileReader class.

Using BufferedReader class will improve the effectiveness of the program. But BufferedReader class is a processing claass, therefore can not directly

take the physical data source. This source is served to the FileReader object which is wrapped into a BufferedReader

FileReader fr = new FileReader("plik.txt");BufferedReader br = new BufferedReader(fr);String line;while ((line - br. readLine()) != null){// processinf a line}

Page 17: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Buffering find a word in a file

class Search{ public boolean hasAnyWord(String fname, Hashtable wordtab) { boolean result = false; try{ String line; FileReader fr = new FileReader(fname); BufferedReader br = new BufferedReader(fr);

br.close(); } catch (IOException e){ System.err.println(e); } return result; }}

search: while ((line = br.readLine()) != null ){ StringTokenizer st = new StringTokenizer(line, " ,.:;()\t\r\n"); while (st.hasMoreTokens()){ String word = st.nextToken(); if (wordtab.get(word) != null){ result = true; break search; } } }

Page 18: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

Buffering find a word in a file

public class Szukaj{ public static void main(String[] args){/* argumenty: nazwa_pliku slowo1 slowo2 ... */ if (args.length < 2) System.exit(1);

Search srch = new Search(); boolean result = srch.hasAnyWord(args[0], words); String msg = " nie zawiera zadnego ze slow:"; if (result) msg = " zawiera ktores ze slow:"; System.out.println("Plik "+args[0]+msg); Enumeration en = words.keys();// uzyskujemy wszystkie klucze tablicy while (en.hasMoreElements()){ // ... i przebiegamy je po kolei String word = (String) en.nextElement(); System.out.println(word); } }}

Object dummy = new Object(); Hashtable words = new Hashtable(); for (int i = 1; i<args.length; i++) words.put(args[i], dummy);

Page 19: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

encodingava uses Unicode characters. These are 16-bit size.

If the constructors of these classes do not specify an encoding, the conversions will be accepted by default.

public class DefaultEncoding{ public static void main(String args[]) { String p = System.getProperty("file.encoding") ; System.out.println(p); }}

Exemplary results: ISO8859_1, ibm-852, Cp852 (Latin 2) , Cpl252 (Windows Western Europe/Latin-1).

Character streams can - invisible to us - convert the source byte character streams, and vice versa. "Under cover" of this process, there are two classes:

InputStreamReader and OutputStreamWriter, which make the appropriate conversions when reading / writing.

Page 20: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

HTML conversionimport java.io.*;public class Convert{ public static void main(String[] args) { String infile = args[0],// plik we in_enc = args[1], // strona kodowa wejścia outfile = args[2], // plik wynikowy out_enc = args[3]; // strona kodowa wyjścia

int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } catch (IOException e){ System.err.println(e);} }}

try{ FileInputStream fis = new FileInputStream(infile); InputStreamReader in = new InputStreamReader(fis, in_enc); FileOutputStream fos = new FileOutputStream(outfile); OutputStreamWriter out = new OutputStreamWriter(fos, out_enc);

Page 21: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

21

In Java, there exists a powerful mechanism for storing arbitrary objects in files (e.g., on disk).Or, more generally, sending them to a stream.

We save objects and then can recover them.This uses object serialization.

Basically, we can use methods writeObject()and readObject() – for any objects.

myOutFile.writeObject(thisObject);val = (MyClass)myInFile.readObject(); // casting necessary

Object I/O

Page 22: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

22

We shall use classes derived from OutputStream and InputStream:

OutputStreamFileOutputStreamObjectOutputStream

InputStreamFileInputStreamObjectInputStream

Import them from java.io.

Object I/O

Page 23: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

23

For output:

ObjectOutputStream out;out = new ObjectOutputStream (

new(FileOutputStream("myFile.dat") );// use out.writeObject(...)out.close();

For input (say, we read from the same file):

ObjectInputStream inp;inp = new ObjectOutputStream (

new(FileOutputStream("myFile.dat") );// use inp.readObject()inp.close();

Object I/O

Page 24: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

24

writeObject() is powerful. It converts an object of any class into a bit sequence and then

sends it to a stream, in a way that it can be subsequently retrieved

(using readObject()) as an object of the original class.

Not surprisingly, static fields are NOT written to the stream.

Serialized objects may contain e.g. other objects as their fields.

No problem with e.g. arrays either.Even multi-dim arrays (btw, in Java a 2-d array is,

formally speaking, an array of arrays).

Object serialization

Page 25: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

25

Our class must simply implement the interfaceSerializable.

public class Tank implements Serializable { ... }

Serializable is empty (=has no methods)!Marker interfaces simply make possible to check

a data type, e.g. with instanceof operator.

That’s what the writeObject(...) method does:checks if

x instanceof Serializable == true.

If so, it sends the object to a stream, otherwise it doesn’t.

(Other marker interfaces: Clonable, RandomAccess...)

How to serialize our own class

Page 26: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

26

When we read an object with readObject(),what we get is actually an object of the class Object().

Cast examples:

Student s = (Student)inpFile.readObject();

int[] tab = (int[])inpFile.readObject();

Casting required

Page 27: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

27

The signatures are:

public final readObject() throws IOException, ClassNotFoundException;

public final void writeObject(Object obj)throws IOException;

Remember about (checked) exceptions

Page 28: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

28

public class GradStudent{ private Supervisor sv; ... }// many grad students may have the same supervisor

No problem! Each GradStudent storesa ‘reference’ to the same Supervisor.

BUT! Those refs are not just mem addresses!Instead, SERIALizable objects get unique

SERIAL numbers.

What if an object is shared by a coupleothers as part of their state?

Page 29: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

29

• each encountered object reference gets a unique serial number,

• if an object reference is encounted for the first time, the object data are saved to the output stream,

• else (object ref already saved), it is written that here we have the same object as the one already saved with serial number x.

Reading back: reversed procedure.

Serialization algorithm

Page 30: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

30

Yes.

Mark a field with keyword transient and it won’t be serialized.

E.g. (example from Core Java, vol. 2):

public class LabeledPoint implements Serializable{ . . . private String label; private transient Point2D.Double point;}

// because Point2D.Double from java.awt.geom // is not serializable and we want to avoid NonSerializableException

Can we serialize selected fields?

Page 31: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

31

Sometimes we’re not happy with the default serialization mechanism.

Cont’d previous slide example:we do want to serialize the data from the Point2D.Double field.

Shall we write the serialization routine from scratch?

First we label the Point2D.Double field as transient (of course).Then we implement

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

private void writeObject(ObjectOutputStream out) throws IOException;

A serializable class is allowed to define those methods.

Serialize on our own

Page 32: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

32

private void writeObject(ObjectOutputStream out) throws IOException{ out.defaultWriteObject(); // can be called only from writeObject(...) ! out.writeDouble(point.getX()); out.writeDouble(point.getY());}

private void readObject(ObjectInputStream in) throws IOException{ in.defaultReadObject(); // can be called only from readObject(...) ! double x = in.readDouble(); double y = in.readDouble(); point = new Point2D.Double(x, y);}

Serialize on our own, cont’d

Page 33: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

33

writeObject(...) writes several things, incl. class nameand 8-byte class fingerprint.

The fingerprint is to ensure the class definition has not changed (between serialization and deserialization).

What if it has changed?

Indicate that the new class is compatible with the old one.

Run serialver OurClass for the old class to obtain its fingerprint.

Then add as (e.g.):public static final long serialVersionUID =

-1814239825517340645L;to the new version of OurClass.

No problemif only methods

changed.

If new fields added: risky.

If field type changed: even worse.

Versioning

Page 34: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

34

The package java.util.zip contains several classes for data compression / decompression.

A few class examples:

Deflater – in-memory compression using zlib library

Inflater – in-memory decompression using zlib library

GzipOutputStream – compresses data using the GZIP format. To use it, construct a GZIPOutputStream that wraps a regular output stream and use write() to write compressed data

GzipInputStream – like above, but for reading data

ZipOutputStream, ZipInputStream – I won’t offend your intelligence

ZipEntry – represents a single element (entry) in a zip file

java.util.zip (compressed I/O)

Page 35: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

35

Writing to a stream of GZipOutStream type. Which means it’ll be compressed on-the-fly.

Compression example (using gzip format)

Page 36: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

36

Used to read the entries in a zip file. In order to create or to read these entries,

you have to pass a file as argument to the constructor:ZipFile zipfile = new ZipFile(new File("c:\\test.zip"));

This instantiation can throw a ZipException, as well as IOException.

One of the solutions is to surround it in a try/catch:

try { zipfile = new ZipFile(new File("c:\\test.zip"));} catch (ZipException e) { } catch (IOException e) { }

Now, files in a zip can be e.g. listed.

ZipFile class

Page 37: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

37

Listing a zip file

Page 38: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

38

Representation of a file or directory path name.This class contains several methods for

working with the path name, deleting and renaming files, creating new directories, listing the contents of a directory, etc.

File f1 = new File("/usr/local/bin/dog");File f2 = new File("d:/my_pets/cat1.txt");File f3 = new File("cat.txt");

File g = new File("/windows/system");File h = new File(g, "rabbit.gif");File i = new File("/windows/system", "rabbit.gif");// objects h and i refer to the same file!

File class

Page 39: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

39

Selected methods (1/2)

boolean canRead() // Returns true if the file is readableboolean exists() // Returns true if the file existsboolean isDirectory() // Returns true if the file name is a directoryboolean isFile() // Returns true if the file name

// is a "normal" file (depends on OS)long length() // Returns the file lengthboolean setReadOnly() // (since 1.2) Marks the file read-only

// (returns true if succeeded)boolean delete() // Deletes the file specified by this name.boolean mkdir() // Creates this directory.

// All parent directories must already exist.

File class

Page 40: Lecture 7 - streams Advanced Java Programming 1 dr hab. Szymon Grabowski dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl .

FileFilter: public interface with only one method:boolean accept(File pathname);

// tests if the specified pathname should be included in a pathname list FileNameFilter: similar interface

but the arg list for accept() different

Beware: JFileChooser (Swing) makes use of javax.swing.filechooser.FileFilter, not java.io.FileFilter! 40

Selected methods (2/2)

String[] list() // Returns an array of Strings with names of the // files from this directory. Returns null if not a dir.

String[] list(FileNameFilter filter)

File[] listFiles()File[] listFiles(FileFilter)File[] listFiles(FileNameFilter) // (all three since 1.2)

File class


Recommended