Topic 3: Advanced Java –collections,
streams, persistence Sub Topic 2: Streams and Persistence
ICT373: Software Architectures
Copyright By PowCoder代写 加微信 powcoder
• Java overview • Objects
• Java revision
• O-O design and Unified Modelling Language (UML)
• Streams, Input, Output
• Persistence and Serialization • RTTI
• Passing, Returning and Cloning Objects
Textbook (11th Ed.) Chapter 15, 17
Objectives (1/2)
• Explain the concept of a stream and describe the main types of stream available in Java.
• Give an example of how streams can be used for –
(i) buffering input, (ii) implementing pipes, (iii) extracting tokens, (iv) compressing data, and (v) archiving classes.
• Describe the decorator pattern approach to the creation of streams.
• Explain the concept of Random Access file, and how this is implemented in Java.
• Explain the concept of persistence of objects and how this is implemented using Serialization. Give some uses for it.
Objectives (2/2)
• Explain the use of RTTI and the Class object to determine the types of serialized objects.
• What is meant by Reflection and how is it used?
• Explain the method used by functions to pass objects as
parameters and return values.
• Explain the uses and dangers of aliasing.
• Explain whether Java uses pass by value or pass by reference.
• How is a clone (a deep-copy) of an object created?
• Explain, using the String class as an example, the difference between mutable and immutable objects.
Streams, Input and Output
• Java uses streams for I/O. A stream is just a source or sink of bytes (generally external to a program).
• Managing I/O is complicated because:
• there are many combinations of choices to make about:
• ultimatesourceordestination
• buffering
• formatting(e.g.,sequential,random,binary,character,bylines, by words)
• there are many and varied types of source/destination:
• TheConsole:System.in,System.out
• arraysorStrings(bytearraystreams)
• pipestoandfromotherpartsoftheprogram(pipedstreams) • files
• networkconnections
Streams, Input and Output
• In the change from Java 1.0 to Java 1.1, IO was internationalized (many new alphabets were added via the Unicode system) and this affected all basic IO facilities.
• formatting of output was initially neglected but has got better (e.g. with the availability of printf and format methods and the Formatter class).
• Stream: is an object that either delivers data to its destination (screen, file, etc.) or that takes data from a source (keyboard, file, etc.) and delivers it to your program.
• it acts as a buffer between the data source and destination
• Input stream: a stream that provides input to a program, eg
• Output stream: a stream that accepts output from a program, eg System.out
• A stream connects a program to an I/O object
• System.in connects a program to the keyboard
• System.out connects a program to the screen
java.io package
• The java.io package contains a collection of stream classes.
• The stream classes are divided in two class hierarchies
• Byte streams: to read and write binary data
• Character streams: to read and write textual info
• The Base Classes in java.io package:
• (abstract superclasses)
• Byte-based super classes:
• Programs use byte streams to perform input and output of 8-bit
• InputStream – an abstract superclass that contains the basic methods (read, skip, mark, reset, close, etc) for reading raw bytes of data from a stream
• OutputStream –sends raw bytes of data to a target such as the console or a network server (methods include: write, flush, close)
java.io package
• Character-based classes:
• The Java platform stores character values using Unicode conventions. Character stream I/O automatically translates this internal format to and from the local character set. In Western locales, the local character set is usually an 8-bit superset of ASCII.
• Reader – an abstract superclass for reading character-based input. It has basic methods deliberately similar to the methods of InputStream class.
• Writer – an abstract superclass for writing out character-based output. It has basic methods deliberately similar to the methods of OutputStream class.
Byte Stream Subclasses
• Derived from the abstract classes InputStream and
OutputStream
• Typically used to read and write binary data such as images and sounds
BufferedInputStream BufferedOutputStream
ByteArrayOutputStream FileInputStream FilterOutputStream PipedInputStream PushbackInputStream LineNumberInputStream
http://docs.oracle.com/javase/7/docs/technotes/guides/io/io.html
DataInputStream FileOutputStream ObjectInputStream PipedOutputStream SequenceInputStream StringBufferInputStream
ByteArrayInputStream DataOutputStream FilterInputStream ObjectOutputStream PrintStream
Character Stream Subclasses
• Derived from the abstract classes Reader and Writer
BufferedReader
CharArrayWriter
FilterReader
LineNumberReader PipedReader
PrintWriter PushbackReader StringReader StringWriter
• Other streams from java.nio, java.util.zip, java.util.jar, java.security, and javax.crypto packages are also available. See Java API documentation.
http://docs.oracle.com/javase/7/docs/technotes/guides/io/io.html
BufferedWriter FileReader FilterWriter
CharArrayReader FileWriter InputStreamReader PipedWriter
Files: Why?
• Use files on disk to store data which is:
• needed before or after program runs
• needs to be transported
• too large to be handled by a program all at once
• needed several times when you don’t want to type it into your program more than once
• All files (data and programs) are stored as 0s and 1s but there are two general types of encodings which you choose between depending on your purposes.
• A stream is like a real stream. It is a flow of bytes.
• A file may be the ‘source’ of a stream or the ‘destination’ of a stream.
Binary vs Text Files
• Binary Files,
• different types of values coded differently to maximize efficient use of space (eg, each integer takes 4 bytes)
• can only be written and read by programs (eg Java programs) which know the types of values being stored
• are transportable (esp. in Java)
• Slow/less efficient (byte-at-a-time read/write)
• Text Files,
• stores characters, one at a time, (2 bytes each)
• not efficient (storage space) for other types of values (eg, integer 1832, stored as “1832” takes 8 bytes)
• can be written, read and edited by programs and text editors
• are very transportable (eg send by email)
• Fast/efficient (buffer-at-a-time read and write)
Open – Loop – Close
• I/O in Java consists of
o OPENING = creating a stream object for each input source or output destination and associating the object with the external entity
o LOOPING getting values in or sending values out by calling methods on the stream object and then
o CLOSING the file or connection by calling a close method on the stream.
• Open once. You will need to create a stream object and say what external entity it corresponds to. In doing the main work of the program, just refer to the stream object.
• At the end make sure that you close the stream.
• There are different classes (available in java.io package and the subpackages of java.nio) of stream objects appropriate to the task.
Classes Scanner and Formatter
• (in java.util package)
• The class Scanner can be used to easily read data from a text file, eg
• Scanner input= new Scanner(new File(“data.txt”));
• System.out.println(input.nextLine());
• The class File is useful for retrieving information about files and directories
• Objects of class File do not open files or provide any file-processing capabilities
• The class Formatter can be used to easily write data to a text file, eg
• Formatter output = new Formatter(“data.txt”);
• output.format(“%s”, “Hello class”);
• output.close(); //output.flush();
• A Formatter object outputs formatted strings to the specified stream using the same formatting capabilities as the System.out.printf method.
The Decorator Pattern Approach
• Because of all the combinations of choices needed in managing a particular IO operation, the Java IO library designers chose to use a general pattern of design called the decorator pattern. This allows a basic stream object (input or output) to be successively decorated by layers of extra facilities.
• Here’s an example (for output to a binary file): DataOutputStream outputStream =
new DataOutputStream(
new FileOutputStream(“numbers.dat”));
• Here the file name is fed to the FileOutputStream constructor to make a new FileOutputStream object. This object is fed to the DataOutputStream constructor and hence we get our DataOutputStream.
• DataInputStream/DataOutputStream enables us to perform I/O for primitive type values and strings.
File I/O Reference Table
new DataInputStream(new FileInputStream(“name”))
use ObjectInputStream class
new DataOutputStream(new FileOutputStream(“name” ))
use ObjectOutputStream class
new BufferedReader(new FileReader(“name”))
input=new Scanner(new File(“name”))
new PrintWriter(new FileOutputStream(name))
output=new Formatter(“name”)
Constructors
End of File
Keyboa rd In
stdin=new BufferedReader(n ew InputStreamRead er(System.in))
Alternatively,
input=new Scanner(System.i n)
s=stdin.r eadLine() int n=stdin.r ead()
s=input.n extLine() int n=input. nextInt() double d=input. nextDoub le()
and other similar methods
s==null etc
input.has NextLine( ) input.has Next() input.has NextInt() input.has NextDou ble()
Screen out
just use System.out.print or, System.out.println
Binary Out
Constructors
n=is.readInt() s=is.readUTF( ) f=is.readFloat () d=is.readDou ble()
os.writeInt(n) os.writeUTF(s ) os.writeFloat(f ) os.writeDoubl e(d)
s=br.readLine ()
int n=br.read()
s=input.readLi ne()
pw.println(s)
output.format (“%s”, str)
End of File
EOFException
Alternatively,
Alternatively,
Alternatively,
(not “”) n==-1
NO EXCEPTIONS!
input.hasNext Line()
Alternatively,
Random Access Files (1/4)
• Random access files allow non-sequential access to a file’s contents. To access a file randomly involves opening the file, seeking a particular location, and reading from or writing to that file.
• The java.io.RandomAccessFile class implements a random access file
• Unlike the input and output stream classes in java.io, RandomAccessFile is used for both reading and writing files
• You create a RandomAccessFile object with different arguments depending on whether you intend to read or write
Random Access Files (2/4)
• RandomAccessFile input = new RandomAccessFile(“myfile.txt”, “r”);
• RandomAccessFile update = new RandomAccessFile(“oldfile.txt”, “rw”);
• A random access file consists of a sequence of bytes. A special marker called file pointer is positioned at one of these bytes.
• A read or write operation takes place at the location of the file pointer. When a file is opened, the file pointer is set at the beginning of the file. When you read or write data to the file, the file pointer moves forward to the next data.
o Eg, if you read an int value using readInt(), the JVM reads four bytes from the file pointer and now the file pointer is four bytes ahead of the previous location.
Random Access Files (3/4)
• In addition to the normal file I/O methods (eg, read/write methods for writing text and binary files such as readInt(), readDouble(), readLine(), writeInt(), writeDouble() etc) that implicitly move the file pointer when the operation occurs, RandomAccessFile contains three methods for explicitly manipulating the file pointer:
• int skipBytes(int)- moves the file pointer offset forward the specified number of bytes
• void seek(long) – positions the file pointer offset (from the beginning of the file) just before the specified byte
• long getFilePointer() – returns the current byte location of the file pointer (i.e. the current offset from the beginning of the file)
Random Access Files (4/4)
Other methods include:
• long length() – returns the length of the file.
• setLength (Long newLength) – sets new length of this file
• read(byte[] b) – reads up to b.length bytes of data from this file into an array of bytes
• write(byte[] b) – writes b.length bytes of data from the specified byte array to this file, starting at the current file pointer. See the Java API documentation for further details.
Other Streamy things
• local directories: to get a list of Strings being the names of the files in a particular directory, see the File class (java.io.File) and its list() method. Some useful methods of File class include canRead(), canWrite(), exists(), isFile(), isDirectory(), getName(), getPath() .
• redirection of standard input/output: System.in is an InputStream object being the standard input. To use it, decorate it with buffering. System.setIn(X) allows redirection of standard input stream so it comes from a given InputStream X. Similarly System.setOut (Y) reassigns the standard output stream to PrintStream Y. See the System class Java documentation for further details. Also see the Scanner class (jdk1.5 and later)
• Deprecation: Note that while using the IO facilities you might accidently use Java 1.0 library classes. You may get a warning from the compiler that such a class is “deprecated”. This means that it is thought likely that that code will no longer work in future versions of Java.
Other Streamy things
• tokenizers: StreamTokenizer class can be used to split an InputStream up into its separate words (it has a nextToken() method). There is a similar StringTokenizer class.
• Pipes: Pipes are synchronized communication channels between threads or processes. You can create byte-based pipes between objects in your program using PipedInputStream and PipedOutputStream, or char-based pipes using PipedReader and PipedWriter.
• line numbering: use the decorator class LineNumberReader to keep track of where you are up to. You can call getLineNumber() and setLineNumber(int) methods.
• Compression: you can add decorators to allow your program to directly read or write compressed data, i.e. in a Zipped or Gzipped format. See java.util.zip package documentation for ZipOutputStream, ZipInputStream, GZipOutputStream, GZipInputStream classes.
Other Streamy things
• jars: JAR (Java ARchive) file format is another compression format which, like Zip, allows many files to be compressed into one compressed file. JAR is platform independent.
• You can compress any files into Jars if you want but the main use is for Java internet programming.
• Jarring allows all the class files needed for a particular applet (or, as we will see, part of an applet) to be collected in one server request from a browser.
• The classes for this are in the java.util.jar package.
java.nio.file package
• Java SE 7 introduced the java.nio.file package which provides extensive support for interacting with files and directories. Its key entry points are the 3 classes:
• The Path class has methods for manipulating files paths (eg creating a path, retrieving info about a path, comparing two paths etc).
• The Files class has methods for file operations, such as moving, copying, deleting files, and also methods for retrieving and setting file attributes.
• The FileSystem class has a variety of methods for obtaining information about the file system.
java.nio.file package
• The java SE 7 Path and Files classes are much more convenient to use than the File class which is available since jdk1.0.
• Whilst File class provided both file location and file system operations, the new API splits this into two. Path class provides just a file location and supports additional path related operations. Files class supports file manipulation with a number of new methods not available in File.
• See the java SE 8 API documentation for further information. Also, see the online tutorial at the following site:http://docs.oracle.com/javase/tutorial/essential/io/fileio.html
Persistence
Serialization
• The process of reading and writing objects is called object
serialization (turning an object into a sequence of bytes).
• This allows an object (at a particular moment) to be frozen and kept or sent somewhere (eg, across a network) and then later restored to its previous state.
• We say that serialization allows the implementation of persistent objects, i.e. objects which can live/survive outside of programs.
• Java’s serialization is only said to provide lightweight persistence because the programmer (as opposed to the system) has to do some of the work.
Serialization – why important?
• RMI= remote method invocation, i.e. sending messages (method calling) to objects on other machines – involves communication between objects via sockets
• Java Beans = objects, usually GUI components, which can be easily put into a program and immediately sprung to life.
• An object is serializable only if its class implements the Serializable interface.
Serialization – how?
• (write to an ObjectOutputStream)
1. Declare that the class of the object, O say, implements Serializable (this is easy as this interface has no methods – it is a marker interface and enables the java serialization mechanism to automate the process of storing objects)
import java.io.*;
public class MyClass implements Serializable{
2. Take the desired OutputStream and decorate it to an ObjectOutputStream to get X, say.
ObjectOutputStream X = new ObjectOutputStream(new
FileOutputStream(“myObjectFile.dat”)); ……
Serialization – how?
3. call X.writeObject(O); ……
MyClass O = new MyClass();
X.writeObject(O);
X.writeObject(“13 April 2015”); // write a string object ……
X.close(); ……
How to de-serialize
(read from an ObjectInputStream)
1. Decorate the InputStream to an ObjectInputStream, Y.
ObjectInputStream Y = new ObjectInputStream(new FileInputStream(“myObjectFile.dat”));
2. call var = Y.readObject(); Eg,
MyClass var1 = (MyClass)Y.readObject(); String var2 = (String)Y.readObject();
How to de-serialize
• Note 1: The objects must be read from the stream in the same order in which they were written.
• Note 2: what you get back from readObject() is just an Object. To use it you usually will need to downcast it to a more specific type. This means that the de-serializing program must have access to the class.
• Note 3: serializing automatically takes care of all the objects which are part of the serialized object and their parts and their parts etc (but their classes must all implement Serializable).
• All those objects are serialized too and encoded in the byte stream for the big object so that it can be put back together as good as new.
• The encoding is good enough to allow full restoration of the object without any need for the use of a constructor.
Controlling/Customising Serialization
• With a Serializable object, all serialization happens automatically.
• Sometimes you need finer control (e.g., do not want to serialize portions of an object due to security issues – passwords etc) …
• Implement the Externlizable interface (instead of the Serializable interface) and supplying writeExternal() and readExternal() methods which will be (automatically) called during serialization and deserialization.
• Then nothing is automatically serialized and you can explicitly serialize only the necessary parts inside the writeExternal() method.
Controlling/Customising Serialization
• Another way to control automatic Serialization is to have those parts of your object that are not to be serialised declared as transient. Then they will not be encoded during deserialization. (This is useful for secret parts.). Eg
public class MyClass implements Serializable{ ……
private Date today = new Date();
private string username;
private transient String password;
// password will not be stored on disk because it is
// declared transient. ……
Serialization of several objects
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com