Io - 2

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Io - 2 as PDF for free.

More details

  • Words: 4,325
  • Pages: 19
Streams -

Java input and output is based on the use of streams.

-

Streams are sequences of bytes that travel from a source to a destination over a communication path. If your program is writing to a stream, it is the stream's source. If it is reading from a stream, it is the stream's destination.

-

The communication path is dependent on the type of I/O being performed. It can consist of memory-to-memory transfers, file system, network, and other forms of I/O.

-

A Stream is an abstract representation of an input or output device that is a source of or destination for data. The java.io package supports two types of streams, Binary Streams, which contain binary data, and character streams, which contain character data.

-

When you write data to a stream as a series of bytes, that is binary data, it is written to the stream exactly as it appears in memory. No transformation of the data takes place. Numerical values are just written as a series of bytes.

-

Character streams are used for storing and retrieving text. You can also use character streams to read a text file not written by a java program.

-

All numeric values are converted to a textual representation before written to the stream. This involves formatting the data to generate a character representation of the data value.

-

All Unicode Characters are automatically converted to the local representation of the characters as used by the host machine and then these are written to the file.

-

Unicode uses 16 bits to represent each character. If the high-order 9 bits are all zeros, then the encoding is simply standard ASCII, otherwise the bits represents a character that is not represented in 7-bit ASCII. Java’s char datatype uses Unicode Encoding.

-

Unicode’s 16-bit is sufficient to encode most alphabets but pictographic Asian Languages like Japanese, Vietnamese present a problem. The answer for this is UTF (UCS Transformation format and UCS stands for Universal Character Set).

-

UTF encoding uses as many bits as needed to encode a character: fewer bits for smaller alphabets and more bits for larger Asian alphabets.

-

A Character Encoding is a mapping between a character set and a range of binary numbers. Every Java platform has a default character encoding, which is used to interpret between internal Unicode and external bytes. The default ASCII encoding is “8859_1”.

The important classes in the io.package are a) File – An object of this class represents a pathname either to a file that you will access for input or output or to a directory. b) Output Stream – Base class for Byte Stream output. c) Input Stream – Base Class for Byte Stream Input. d) Writer – Base class for Character stream Output. e) Reader – Base class for Character stream Input. f) RandomAccessFile – Random Access to a File. -

Streams are powerful because they abstract away the details of the communication path from input and output operations. This allows all I/O to be performed using a common set of methods. The File Class

-

File class represents the name of a file or directory that might exist on the hose machine’s file system.

-

The constructors are File (String file) File(String dir, String subpath) File(File dir, String subpath) The methods are: Boolean exists() – Where the file or directory exists or not String getAbsolutePath() – This returns the absolute and not the relative path of file or directory. String getName() String getParent() – This returns the name of the directory that contains the File. Boolean isDirectory()

Boolean isFile() String [] list() – This returns an array containing the name of files and directories within the File (which should be a directory). Boolean canRead() Boolean canWrite() long length() Boolean mkdir(File f) boolean renameTo (File newname)

This Example is to show how to use the list () method. import java.awt.* import java.io.File class Lister extends Frame { TextArea ta public static void main (String arg[]) { //get path or dir to be listed. default to c:\ if no command line argument String path = “.”; if(args.length >=1) path = args[0]; // make sure the path exists and is a directory File f = new File(path) if (!f.isDirectory()) System.out.println(Does not exiss or not dir: - “ + path) System.exit(0); } //Recursively list contents Lister l = new Lister(f);

l.setVisible(true); } Lister(File f) { setSize(300,400); ta = new TextArea(); ta.setFont(new Font(“Monospaced”, Font.PLAIN, 14)); add(BorderLayout.Center,ta); recurse(f,0); } // recursively list the contents of a direfile, Indent _ 5 space for each level of depth. void recurse(File dirfile, int depth) ( String contents[] = dirfile.list(); for (int I = 0; I
“);

ta.append (contents[I] + “\n”); // Print name File child = new File(dirfile, contents[I]; if (child.isDirectory()) recurse(child, depth+1) // Recurse if dir } } } IMP: constructing or garbage collecting an instance of File has no effect on the local file system. FileDemo FileSplitter1

FileLister DirList FilenameFilter Interface -

If we want to limit the number of files returned by the list () method to include only those files that match a certain filename or filter, we have to implement this interface.

-

This interface has only one method accept () which is called once for each file in the list. boolean accept (File d, String name);

-

The accept method will return true for files in the directory specified by d that should be included in the list and returns false for files that should be excluded.

-

For using this method, we have to use the overloaded version of list () that is String [] list (FilenameFilter fnf); See TestFF

RandomAccessFile Class -

One way to ready or modify a file is to use the java.io.RamdomAccessFile class. This class represents a model of files that is imcompatible with the Stream / Writer classes.

-

With a RamdomAccessFile, you can seek a desired position within a file and then read or write a desired amount of data. The RamdomAccessFile provides method that support seeking, reading and writing Constructors RamdomAccessFile(String file, String mode // which can be ‘r’ or ‘rw’) The ‘rw” form of constructor is useful when you want to open some of the methods of the File class before opening a RAF, so that a instance of File is in hand when calling the RAF constructor.

Constructing a RAF is similar like constructing an instance of File. After a random Access file is created, you can seek to any byte position within the file and then read or write. Pre java systems have supported this seeing to a

position relative to the beginning of the file, end of the file or the current position of the file. The methods -

long getFilePointer () throws IOException – This returns the current position within the file, in bytes, Subsequent reading and writing will take place starting at this position.

-

long length() throws – length of file in bytes

-

void seek( long position) thro – This sets the current position within the file in bytes. Subsequent reading and writing will take place at this position. Files start at position 0.

The common methods that support reading and writing are: 1. int read() - this returns the next byte from the file or –1 is end of file 2. int read(byte d[]) – attempts to read enough bytes t fill array d[] 3. int read(byte d[], int o, int n) – attempts to read n number of bytes into array d[] starting at o. RamdomAccessFile supports reading and writing of all primitive data types. When RAF is no longer needed, it should be closed: void close() throws IOException Pls see: RAFExample1

Streams: a) Low Level InputStream reads bytes from an input device and returns bytes to its callers. b) High Level Filter Input Streams read bytes from a low level input stream or from another filter input stream and returns general format data to its caller. c) Low Level OutputStream receives bytes and writes bytes to an output Device.

d) High Level Filter Output Stream received general format data such as primitives and writes bytes to a low level output stream or to another filter output stream. The important Methods in the abstract InputStream class is: a)

int read() – returns the integer representation of the next available byte of input. –1 is the end of file is encountered.

b)

int read (byte b[]) – this will read the bytes in the array.

c)

int read(byte b[], int o, int no) – this will read no number of bytes starting at 0.

d)

int available() – returns the number of bytes of input currently available for reading.

e)

long skip(long no) – Ignores, the no number of bytes returning the actual number of bytes ignored. Low Level Streams

a) b) c)

FileInputStream ByteArrayInputStream SequenceInputStream

FileInputStream -

This class will enable us to create a IS that you can use to read bytes from a file.

-

The common Constructors are as under: FIS(String filename); FIS(File f);

-

Either of this will throw a checked exception and hence will have to be put in a try / catch block or the main method will have to throw this FileNotFoundException.

FileOutputStream -

FOS is used to create an OutputStream that u can use to write bytes to a file.

-

The most common used constructors are:

FOS(String s) FOS(File f) FOS(String s, boolean append) -

This class can throw IOException or SecurityException.

-

IMP: Creating of a file is not dependent on whether the file is already existing or not. This will create another file and incase there is a existing file, the same will be overwritten.

ByteArrayInputStream -

This is an implementation of an InputStream that uses byte array as the source.

-

The two constructors for this are: BAIS (byte b[]) BAIS (byte b[], int start, int noofbytes)

-

BAIS implements both mark () and reset (). However if mark () has not been called, then reset () sets the stream pointer to the start of the stream.

ByteArrayOutputStream -

This is an implementation of an output stream that uses a byte array as its destination.

-

The two constructors are: BAOS () // buffer size of 32 bytes is created. BAOS(int noofbytes) // buffer as per the noofbytes specified

-

To write normally use the write(). To write to byte array use the method toByteArray(). To write to a file use the method writeTo (OutputStream).

SequenceInputStream -

This class allows you to concatenate multiple InputStreams.

-

The two constructors for this are: SIS (IS one, IS two);

SIS (Enumeration s) -

In the case of the first constructor, the class reads requests from the first IS until it runs out and then switches to the other and so on.

-

In the case of Enumeration, it will continue through all the IS until the end of the last one is reached. HighLevelStreams

a) b) c) -

BufferedInputStream DataInputStream PushbackInputStream The High Level Streams take Low Level streams always as the parameter in the constructors.

BufferedInputStream and BufferedOutputStream -

The buffered streams allow you to attach a memory buffer to the IO. This buffer allows java to do IO operations on more than one byte at a time, hence increasing performance.

-

The BIS allows you to wrap any IS and achieve performance improvement.

PushbackInputStream -

One of the uses of buffering is the implementation of pushback.

-

Pushback is used on an InputStream to allow a byte to be read and then returned (that is pushed back) to the stream.

-

The two Constructors for this are: PBIS (IS) PBIS (IS,int n) IS

// in this case only one byte is pushed // in this case n number of bytes are returned to the

DataInputStream -

A data input stream lets an application read primitive Java data types from an underlying input stream in a machine-independent way. An

-

application uses a data output stream to write data that can later be read by a data input stream. The constructor for a DIS require InputStream as its parameter

DataInputStream( inputstream) // pass an instance of a input stream. The most commonly used input methods of DIS are readBoolean readByte -

and so on

Example try{ FIS a = new FIS(“file name”) DIS dis = new DIS(a) double d = dis.readDoube() dis.close() fis.clost() catch (Exception) // We must close the streams in the order in which we opened them. Readers & Writers -

While the Byte Stream provides all the functionality, they cannot work directly with Unicode characters.

-

use the readLine () of the BufferedReader

//The source code of the FileIOApp program import java.lang.System; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.File; import java.io.IOException; public class FileIOApp {

public static void main(String args[]) throws IOException { FileOutputStream outStream = new FileOutputStream("test.txt"); String s = "This is a test."; for(int i=0;i<s.length();++i) outStream.write(s.charAt(i)); outStream.close(); FileInputStream inStream = new FileInputStream("test.txt"); int inBytes = inStream.available(); System.out.println("inStream has "+inBytes+" available bytes"); byte inBuf[] = new byte[inBytes]; int bytesRead = inStream.read(inBuf,0,inBytes); System.out.println(bytesRead+" bytes were read"); System.out.println("They are: "+new String(inBuf,0)); inStream.close(); File f = new File("test.txt"); f.delete(); } } //The source code of the PushbackIOApp program. import java.lang.System; import java.io.PushbackInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; public class PushbackIOApp { public static void main(String args[]) throws IOException { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); String s = "This is a test."; for(int i=0;i<s.length();++i) outStream.write(s.charAt(i)); System.out.println("outstream: "+outStream); System.out.println("size: "+outStream.size()); ByteArrayInputStream inByteArray; inByteArray = new ByteArrayInputStream(outStream.toByteArray()); PushbackInputStream inStream; inStream = new PushbackInputStream(inByteArray); char ch = (char) inStream.read(); System.out.println("First character of inStream is "+ch); inStream.unread((int) 't'); int inBytes = inStream.available(); System.out.println("inStream has "+inBytes+" available bytes"); byte inBuf[] = new byte[inBytes];

for(int i=0;i
File file = new File("test.txt"); FileOutputStream outFile = new FileOutputStream(file); DataOutputStream outStream = new DataOutputStream(outFile); outStream.writeBoolean(true); outStream.writeInt(123456); outStream.writeChar('j'); outStream.writeDouble(1234.56); System.out.println(outStream.size()+" bytes were written"); outStream.close(); outFile.close(); FileInputStream inFile = new FileInputStream(file); DataInputStream inStream = new DataInputStream(inFile); System.out.println(inStream.readBoolean()); System.out.println(inStream.readInt()); System.out.println(inStream.readChar()); System.out.println(inStream.readDouble()); inStream.close(); inFile.close(); file.delete(); } } /*The RandomIOApp program provides a simple demonstration of the capabilities of random-access I/O. It writes a boolean, int, char, and double value to a file and then uses the seek() method to seek to offset location 1 within the file. This is the position after the first byte in the file. It then reads the int, char, and double values from the file and displays them to the console window. Next, it moves the file pointer to the beginning of the file and reads the boolean value that was first written to the file. This value is also written to the console window. The source code of the RandomIOApp program is shown.*/ import java.lang.System; import java.io.RandomAccessFile; import java.io.IOException; public class RandomIOApp { public static void main(String args[]) throws IOException { RandomAccessFile file = new RandomAccessFile("test.txt","rw"); file.writeBoolean(true); file.writeInt(123456); file.writeChar('j');

file.writeDouble(1234.56); file.seek(1); System.out.println(file.readInt()); System.out.println(file.readChar()); System.out.println(file.readDouble()); file.seek(0); System.out.println(file.readBoolean()); file.close(); } } /*Although the processing performed by RandomIOApp is quite simple, it illustrates how random I/O allows you to move the file pointer to various locations within a file to directly access values and objects contained within the file. */ Object Persistence Persistence is the ability of an object to record its state so that it can be reproduced in the future, perhaps in another environment. For Example, a persistent object might store its fate in a file. The file can be used to restore the object in a different runtime environmentally. It is not the object itself that persists, but rather the information necessary to construct a replica of the object. When an object is serialised all of the object’s data but not its methods or class definition is written to a stream. Serialization An object records itself by writing out the values that describe its state. This process is know as serialisation because the object is represented by an ordered series of bytes. Java provides classes that write objects to streams and restore objects from streams. The main task of serialization is to write out the values of an object’s instance variables. If a variable is a reference to another object, the referenced object must also be serialised. Serialization may involve serializing a complex tree structure that consists of the original object, the object’s object and so on. Not all classes are capable of being serialized. Only objects that implement the Serializable or Externalizable interfaces may successfully be serialized. Both the classes are in java.io package. A Serializable object can be serialized by another object, which is in practice is a type of output stream. An Externalizable object must be capable of writing its own state, rather than letting the work be done by another object.

The Serializable Interface This interface does not have any methods. When a class declares that it implements Serializable, it is declaring that it participates in the serialization protocol. When an object is Serializable and the object’s state is written to a stream, the stream must contain enough information to restore the object. This must hold true even if the class being restored has been updated to a more recent (but compatible) version. One can serialize any class as long as the class meets the following criteria: a) The class or one of its super classes, must implement the java.io.Serializable interface. b) The class can implement the writeObject () to control data that is being saved and append new data to existing saved data. c) The class can implement the readObject () to read the data that was written by the corresponding writeObject () method. If a Serializable class has variables that should not be serialized those variables must be marked with the transient keyword. The serialization process will ignore any variables marked as transient. In general, references to AWT classes that rely on System peers should be marked as transient. Many things - like static data, open file handles, socket connections and threads will not be Serializable since they represent items that are very JVM specific. Externalizable Interface The Externalizable interface identifies objects that can be saved to a stream but are responsible for their own states. When an exter object is written to a stream, the stream is responsible for storing the name of the object’s class, the object must write its own data. An exter class must adhere to this interface by providing a writeExternal () for storing its state during serialization and readExternal () for restoring its state during deserialization. Object Output Stream Objects that can serialize other objects implement the ObjectOutput Interface from the io package. This interface is implemented by output stream class and extends the DataOutput class. The essential of the interface is writeObject, which writes object to a stream. Static and transient data are not written and all other data including private are written. The DataOutput interface support writing of primitive data types and these methods are used for writing out an object’s primitive instance variables.

Serializable objects are represented as streams of bytes, rather than as characters. Therefore they are handled by streams rather than by character oriented streams. When an object is to be serialised to a file, the first step is to create an output stream that talks to the file FileOutPutStream fos = new FileOutPutStream (“obj.file”) The next step is to create an object output stream and chain it to the fos ObjectOutput oo = new ObjectOutput (fos); The object output stream automatically writes a header into the streams; the header contains a magic number and a version. This data is written automatically with the writeStreamHeader () when the object output stream is created. After writing the header; the oos will write the bit representation of an object to the oos using the writeObject method. Note: Without calling the reset () of the java.io.Serializable you cannot use the same stream to write the same object reference twice. Deserialization The obj i.s class reads serialized object data. By using the methods of this class, a program can restore a serialised object along with the entire tree of objects referred to by the primary object from the stream. Primitive data type may also be read from an obj i.s. The constructor calls the class’s readStreamHeader() method to verify the header and the version that were written into the stream by the corresponding object output stream. If a problem is detected with the header or the version a StreamCorruptedException is thrown. The primary method of the O inputstream class is readObject(), which deserializes an object from the data source stream. The deserialized object is returned as an object; the caller is responsible for casting it into the correct type. The Known Objects Table During deserialization, a list is maintained of objects that have been restored from the stream. This list is called the known objects table. If the data being written is of a primitive type, it is simply treated as a sequence of bytes and restored from the input stream. If the data being restored is a string, it is read using string UTF encoding the string will be added to the known objects table.

If the object being restored is an array, the type and length of the array are determined, Next memory for the array is allocated and each of the elements contained in the array is read using the appropriate read method. Once the array is reconstructed, it is added to the table. If it is an array of object (as opposed to primitives) then each object is deserialised and added to the table. Object Validation Once an object has been retrieved from a stream, it must be validated so it can become a full fledged object and can be used by a the program that deserialized it. The validateObject() method is called when a complete graph of objects has been retrieved from a stream. If the primary object cannot be made valid, the validation will stop and an exception will be thrown. Security for Serialized data Serialization can involve storing an object’s data on a disk file or transmitting the data across the network. In both cases, there is a potential security problem because the data is located outside the JVM – beyond the reach of java’s security mechanism. The writeExternal () is public so any object can make an externalizable or serializable object write itself into a stream. you should be careful when deciding whether or not writeExternal () should serialize sensitive private data. When an object is restored via an ordinary readExternal () call its sensitive values are restored into private variables and no harm is done. However while the serialised data is outside the system, an attacker could access the data decode its format and obtain the sensitive values. When a object is being serialised, all the reachable objects of its ownership graph are potentially exposed. The best protection for an object that has fields that should not be stored is to label those fields with the transient keyword. Serialization Exceptions: 6 Exceptions. 1)

Invalid ClassException: Typically thrown when the class type cannot be determined by the reserialization stream or when the class that is being returned cannot be represented on the system retrieving the object. This is also thrown if the deserialized class is not declared public or if it does not have a public default constructor.

2)

NotSerializableException: Typicall thrown by externalizable objects (which are not responsibl for their own reserialization) on detection of a corrupted input stream. The corruption is generally indicated by an unexpected invariant value or simply when u try to serialize a nonserialisable object.

3)

StreamCorruptedException: When the stored object’s header or control data is invalid.

4)

OptionalDataException: Thrown when a stream is supposed to contain a object, but it actually contains only primitive data.

5)

ClassNotFoundException: Thrown when the class of the deserialized object cannot be found on the read side of the stream

6)

IOException: Thrown when there is an error related to the stream that the object is being written to or read from.

It is important to note that most stream methods can throw an IOException, therefore any time you access a stream you should enclose the code within a try and catch block. The following example reads a string from the keyboard and prints it import java.io.*; class Input { public static void main (String arg[]) throws IOException { System.out,print (“Enter a String “); BufferedReader br =new BufferedReader ( new InputStreamReader (System.in))); System.out.println (“The String you have entered is: “+br.readLine)); } } By using streams, you can create java programs that read data form a source, process the data and write the results to a destination. import java.io.*; class CopyFile { public static void main (String arg[]) { InputStream m_input = null; OutputStream m_output = null; try

{ System.out.println(“Opening Files..”)’ m_input = new FileInputStream (“CopyFile.java”); m_output = new FileOutputStream (“Copyof_CopyFile.txt”); System.out.println (“Copying data...”); byte data; while ((data=(byte)m_input.read()) != -1) { m_output.write(data); } System.out.println(“File copied”); } catch (Exception e) { System.out.println(“IO Error” + e.getMessage ()); } System.exit (0); } }

Related Documents

Io - 2
November 2019 27
Io
April 2020 29
Io
November 2019 42
Io
November 2019 42
Io
May 2020 27
About Io--182-2
November 2019 11