Tải bản đầy đủ - 0 (trang)
3 Byte Streams: Input Streams and Output Streams

3 Byte Streams: Input Streams and Output Streams

Tải bản đầy đủ - 0trang

476

Figure 11.1



CHAPTER 11: FILES AND STREAMS



Partial Byte Stream Inheritance Hierarchies

«interface»

DataInput

«interface»

ObjectInput



InputStream

...



ObjectInputStream



FilterInputStream



FileInputStream



...



BufferedInputStream



DataInputStream

«interface»

DataOutput

«interface»

ObjectOutput



OutputStream

...



ObjectOutputStream



FilterOutputStream



FileOutputStream

...



DataOutputStream



BufferedOutputStream



void close() throws IOException

void flush() throws IOException



PrintStream



Only for OutputStream



A stream should be closed when no longer needed, to free system resources.

Closing an output stream automatically flushes the stream, meaning that any

data in its internal buffer is written out. An output stream can also be manually

flushed by calling the second method.

Read and write operations on streams are synchronous (blocking) operations, i.e., a

call to a read or write method does not return before a byte has been read or written.

Many methods in the classes contained in the java.io package throw the checked

IOException. A calling method must therefore either catch the exception explicitly,

or specify it in a throws clause.



www.it-ebooks.info



11.3: BYTE STREAMS: INPUT STREAMS AND OUTPUT STREAMS



477



Table 11.1 and Table 11.2 give an overview of the byte streams. Usually an output

stream has a corresponding input stream of the same type.

Table 11.1



Selected Input Streams

FileInputStream



Data is read as bytes from a file. The file acting as the input

stream can be specified by a File object, a FileDescriptor or a

String file name.



FilterInputStream



Superclass of all input stream filters. An input filter must be

chained to an underlying input stream.

A filter that allows the binary representation of Java primitive

values to be read from an underlying input stream. The

underlying input stream must be specified.



DataInputStream



ObjectInputStream



Table 11.2



Allows binary representations of Java objects and Java

primitive values to be read from a specified input stream.



Selected Output Streams

FileOutputStream



Data is written as bytes to a file. The file acting as the output

stream can be specified by a File object, a FileDescriptor or a

String file name.



FilterOutputStream



Superclass of all output stream filters. An output filter must be

chained to an underlying output stream.



DataOutputStream



A filter that allows the binary representation of Java primitive

values to be written to an underlying output stream. The

underlying output stream must be specified.



ObjectOutputStream



Allows the binary representation of Java objects and Java primitive values to be written to a specified underlying output stream.



File Streams

The classes FileInputStream and FileOutputStream define byte input and output

streams that are connected to files. Data can only be read or written as a sequence

of bytes.

An input stream for reading bytes can be created using the following constructors:

FileInputStream(String name) throws FileNotFoundException

FileInputStream(File file) throws FileNotFoundException

FileInputStream(FileDescriptor fdObj)



The file can be specified by its name, through a File object, or using a FileDescriptor object.



If the file does not exist, a FileNotFoundException is thrown. If it exists, it is set

to be read from the beginning. A SecurityException is thrown if the file does not

have read access.



www.it-ebooks.info



478



CHAPTER 11: FILES AND STREAMS



An output stream for writing bytes can be created using the following constructors:

FileOutputStream(String name) throws FileNotFoundException

FileOutputStream(String name, boolean append) throws FileNotFoundException

FileOutputStream(File file) throws IOException

FileOutputStream(FileDescriptor fdObj)



The file can be specified by its name, through a File object, or using a File

Descriptor object.



If the file does not exist, it is created. If it exists, its contents are reset, unless the

appropriate constructor is used to indicate that output should be appended to

the file. A SecurityException is thrown if the file does not have write access or

it cannot be created.

The FileInputStream class provides an implementation for the read() methods in its

superclass InputStream. Similarly, the FileOutputStream class provides an implementation for the write() methods in its superclass OutputStream.

Example 11.2 demonstrates usage of writing and reading bytes to and from file

streams. It copies the contents of one file to another file. The input and the output

file names are specified on the command line. The streams are created at (1) and

(2). The input file is read one byte at a time and written straight to the output file,

as shown in the try block at (3). The end of file is reached when the read() method

returns the value -1. The streams are explicitly closed, as shown at (4). Note that

most of the code consists of try-catch constructs to handle the various exceptions.

The example could be optimized by using buffering for reading and writing several bytes at a time.

Example 11.2



Copy a File

/* Copy a file.

Command syntax: java CopyFile

*/

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

class CopyFile {

public static void main(String[] args) {

FileInputStream fromFile;

FileOutputStream toFile;

// Assign the files

try {

fromFile = new FileInputStream(args[0]);

// (1)

toFile = new FileOutputStream(args[1]);

// (2)

} catch(FileNotFoundException e) {

System.err.println("File could not be copied: " + e);



www.it-ebooks.info



479



11.3: BYTE STREAMS: INPUT STREAMS AND OUTPUT STREAMS

return;

} catch(ArrayIndexOutOfBoundsException e) {

System.err.println("Usage: CopyFile ");

return;

}

// Copy bytes

try {

// (3)

while (true) {

int i = fromFile.read();

if(i == -1) break;

// check end of file

toFile.write(i);

}

} catch(IOException e) {

System.err.println("Error reading/writing.");

}

// Close the files

try {

fromFile.close();

toFile.close();

} catch(IOException e) {

System.err.println("Error closing file.");

}



// (4)



}

}



Filter Streams

A filter is a high-level stream that provides additional functionality to an underlying stream to which it is chained. The data from the underlying stream is manipulated in some way by the filter. The FilterInputStream and FilterOutputStream

classes, together with their subclasses, define input and output filter streams. The

subclasses BufferedInputStream and BufferedOutputStream implement filters that

buffer input from and output to the underlying stream, respectively. The subclasses DataInputStream and DataOutputStream implement filters that allow binary

representation of Java primitive values to be read and written, respectively, to and

from an underlying stream.



Reading and Writing Binary Values

The java.io package contains the two interfaces DataInput and DataOutput, that

streams can implement to allow reading and writing of binary representations of

Java primitive values (boolean, char, byte, short, int, long, float, double). The methods for writing binary representations of Java primitive values are named writeX,

where X is any Java primitive data type. The methods for reading binary representations of Java primitive values are similarly named readX. Table 11.3 gives an

overview of the readX() and writeX() methods found in these two interfaces. A file



www.it-ebooks.info



480



CHAPTER 11: FILES AND STREAMS



containing binary values (i.e., binary representation of Java primitive vales) is usually called a binary file.

Note the methods provided for reading and writing strings. Whereas the methods

readChar() and writeChar() handle a single character, the methods readLine() and

writeChars() handle a string of characters. The methods readUTF() and writeUTF()



also read and write characters, but use the UTF-8 character encoding. However, the

recommended practice for reading and writing characters is to use character

streams, called readers and writers, that are discussed in Section 11.4.

The filter streams DataOutputStream and DataInputStream implement DataOutput and

DataInput interfaces, respectively, and can be used to read and write binary representations of Java primitive values to and from an underlying stream. Both the

writeX() and readX() methods throw an IOException in the event of an I/O error.

In particular, the readX() methods throw an EOFException (a subclass of IOEXception) if the input stream does not contain the correct number of bytes to read. Bytes

can also be skipped from a DataInput stream, using the skipBytes(int n) method

which skips n bytes. The following constructors can be used to set up filters for

reading and writing Java primitive values, respectively, from an underlying

stream:

DataInputStream(InputStream in)

DataOutputStream(OutputStream out)



Table 11.3



The DataInput and DataOutput Interfaces

Methods in the DataInput

Interface



Methods in the DataOutput

interface



boolean



readBoolean()



writeBoolean(boolean b)



char



readChar()



writeChar(int c)



byte



readByte()



writeByte(int b)



short



readShort()



writeShort(int s)



int



readInt()



writeInt(int i)



long



readLong()



writeLong(long l)



float



readFloat()



writeFloat(float f)



double



readDouble()



writeDouble(double d)



String



readLine()



writeChars(String str)



String



readUTF()



writeUTF(String str)



Type



Writing Binary Values to a File

To write the binary representation of Java primitive values to a binary file, the following procedure can be used, which is also depicted in Figure 11.2.



www.it-ebooks.info



481



11.3: BYTE STREAMS: INPUT STREAMS AND OUTPUT STREAMS



1.



Create a FileOutputStream:

FileOutputStream outputFile = new FileOutputStream("primitives.data");



2.



Create a DataOutputStream which is chained to the FileOutputStream:

DataOutputStream outputStream = new DataOutputStream(outputFile);



3.



Write Java primitive values using relevant writeX() methods:

outputStream.writeBoolean(true);

outputStream.writeChar('A');

outputStream.writeByte(Byte.MAX_VALUE);

outputStream.writeShort(Short.MIN_VALUE);

outputStream.writeInt(Integer.MAX_VALUE);

outputStream.writeLong(Long.MIN_VALUE);

outputStream.writeFloat(Float.MAX_VALUE);

outputStream.writeDouble(Math.PI);



// int written as Unicode char

// int written as 8-bits byte

// int written as 16-bits short



Note that in the case of char, byte, and short data types, the int argument to the

writeX() method is converted to the corresponding type, before it is written

(see Table 11.3).

4.



Close the filter stream, which also closes the underlying stream:

outputStream.close();



Figure 11.2



Stream Chaining for Reading and Writing Binary Values to a File

Object of class

DataOutputStream



Object of class

Object of class

FileOutputStream FileInputStream



writeBoolean()

writeByte()

writeChar()

writeDouble()

writeFloat()

writeInt()

writeLong()

writeShort()

writeChars()

writeUTF()



bytes



bytes

asflhslfsdf lk j`sl ;lk

dfgvz dfhglkjfg zdrg

zz dfghdlrgjpzkdfjg`z

zd fg;ladgrz d;fgj;o

z dsflgkfdg

z sdrgoj`d;fg

` s;dflgkjz`z dfg[`zdifg[`

sjd fgh`ljfg

` dfg`fgz`df;gojp` sdoif



file



Object of class

DataInputStream



readBoolean()

readByte()

readChar()

readDouble()

readFloat()

readInt()

readLong()

readShort()

readLine()

readUTF()



Reading Binary Values From a File

To read the binary representation of Java primitive values from a binary file the following procedure can be used, which is also depicted in Figure 11.2.

1.



Create a FileInputStream:

FileInputStream inputFile = new FileInputStream("primitives.data");



www.it-ebooks.info



482



CHAPTER 11: FILES AND STREAMS



2.



Create a DataInputStream which is chained to the FileInputStream:

DataInputStream inputStream = new DataInputStream(inputFile);



3.



Read the (exact number of) Java primitive values in the same order they were

written out, using relevant readX() methods:

boolean

char

byte

short

int

long

float

double



4.



v

c

b

s

i

l

f

d



=

=

=

=

=

=

=

=



inputStream.readBoolean();

inputStream.readChar();

inputStream.readByte();

inputStream.readShort();

inputStream.readInt();

inputStream.readLong();

inputStream.readFloat();

inputStream.readDouble();



Close the filter stream, which also closes the underlying stream:

inputStream.close();



Example 11.3 uses both procedures described above: first to write and then to read

some Java primitive values to and from a file. It also checks to see if the end of the

stream has been reached, signalled by an EOFException. The values are also written

to the standard input stream.

Example 11.3



Reading and Writing Binary Values

import

import

import

import

import

import



java.io.DataInputStream;

java.io.DataOutputStream;

java.io.EOFException;

java.io.FileInputStream;

java.io.FileOutputStream;

java.io.IOException;



public class BinaryValuesIO {

public static void main(String[] args) throws IOException {

// Create a FileOutputStream.

FileOutputStream outputFile = new FileOutputStream("primitives.data");

// Create a DataOutputStream which is chained to the FileOutputStream.

DataOutputStream outputStream = new DataOutputStream(outputFile);

// Write Java primitive values in binary representation:

outputStream.writeBoolean(true);

outputStream.writeChar(’A’);

// int written as Unicode char

outputStream.writeByte(Byte.MAX_VALUE);

// int written as 8-bits byte

outputStream.writeShort(Short.MIN_VALUE); // int written as 16-bits short

outputStream.writeInt(Integer.MAX_VALUE);

outputStream.writeLong(Long.MIN_VALUE);

outputStream.writeFloat(Float.MAX_VALUE);

outputStream.writeDouble(Math.PI);

// Close the output stream, which also closes the underlying stream.

outputStream.flush();

outputStream.close();



www.it-ebooks.info



11.3: BYTE STREAMS: INPUT STREAMS AND OUTPUT STREAMS

// Create a FileInputStream.

FileInputStream inputFile = new FileInputStream("primitives.data");

// Create a DataInputStream which is chained to the FileInputStream.

DataInputStream inputStream = new DataInputStream(inputFile);

// Read the binary representation of Java primitive values

// in the same order they were written out:

boolean v = inputStream.readBoolean();

char

c = inputStream.readChar();

byte

b = inputStream.readByte();

short

s = inputStream.readShort();

int

i = inputStream.readInt();

long

l = inputStream.readLong();

float

f = inputStream.readFloat();

double d = inputStream.readDouble();

// Check for end of stream:

try {

int value = inputStream.readByte();

System.out.println("More input: " + value);

} catch (EOFException eofe) {

System.out.println("End of stream");

} finally {

// Close the input stream, which also closes the underlying stream.

inputStream.close();

}

// Write the values read to the standard input stream:

System.out.println("Values read:");

System.out.println(v);

System.out.println(c);

System.out.println(b);

System.out.println(s);

System.out.println(i);

System.out.println(l);

System.out.println(f);

System.out.println(d);

}

}



Output from the program:

End of stream

Values read:

true

A

127

-32768

2147483647

-9223372036854775808

3.4028235E38

3.141592653589793



www.it-ebooks.info



483



484



CHAPTER 11: FILES AND STREAMS



Review Questions

11.1



Which of these can act both as the source of an input stream and as the destination

of an output stream, based on the classes provided by the java.io package?

Select the four correct answers.

(a)

(b)

(c)

(d)

(e)



11.2



A file

A network connection

A pipe

A string

An array of chars



Which of these statements about the constant named separator of the File class are

true?

Select the two correct answers.

(a)

(b)

(c)

(d)

(e)



11.3



The variable is of type char.

The variable is of type String.

It can be assumed that the value of the variable always is the character '/'.

It can be assumed that the value of the variable always is one of '/', '\' or ':'.

The separator can consist of more than one character.



Which one of these methods in the File class will return the name of the entry,

excluding the specification of the directory in which it resides?

Select the one correct answer.

(a) getAbsolutePath()

(b) getName()

(c) getParent()

(d) getPath()

(e) None of the above.



11.4



What will the method length() in the class File return?

Select the one correct answer.

(a)

(b)

(c)

(d)

(e)



11.5



The number of characters in the file.

The number of kilobytes in the file.

The number of lines in the file.

The number of words in the file.

None of the above.



Given the following program:

import java.io.File;

import java.io.IOException;

public final class Filing {



www.it-ebooks.info



11.3: BYTE STREAMS: INPUT STREAMS AND OUTPUT STREAMS



485



public static void main (String[] args) throws IOException {

File file = new File("./documents","../book/../chapter1");

System.out.println(file.getPath());

System.out.println(file.getAbsolutePath());

System.out.println(file.getCanonicalPath());

System.out.println(file.getName());

System.out.println(file.getParent());

}

}



Assume that the current or working directory has the absolute path "/wrk". Which

lines below will not be included in the output from the program?

Select the two correct answers.

(a) ./documents/../book/../chapter1

(b) ./documents/book/chapter1

(c) /wrk/./documents/../book/../chapter1

(d) /wrk/documents/book/chapter1

(e) /wrk/chapter1

(f) chapter1

(g) ./documents/../book/..

11.6



Given the following program:

import java.io.File;

public class ListingFiles {

public static void main(String[] args) {

File currentDirectory = new File(".");

printFiles1(currentDirectory);

printFiles2(currentDirectory);

printFiles3(currentDirectory);

}

public static void printFiles1(File currentDirectory) {

String[] entryNames = currentDirectory.list();

for (String entryName : entryNames) {

System.out.println(entryName);

}

}

public static void printFiles2(File currentDirectory) {

File[] entries = currentDirectory.listFiles();

for (File entry : entries) {

System.out.println(entry);

}

}

public static void printFiles3(File currentDirectory) {

File[] entries = currentDirectory.listFiles();

for (File entry : entries) {

System.out.println(entry.getPath());

}

}

}



www.it-ebooks.info



486



CHAPTER 11: FILES AND STREAMS



Assume that the current or working directory has the absolute path "/wrk" and

contains only one file with the name "ListingFiles.class".

Which statement is true about the program?

Select the one correct answer.

(a) All three methods printFiles1(), printFiles2(), and printFiles3() will produce the same output.

(b) Only the methods printFiles1() and printFiles2(), will produce the same

output.

(c) Only the methods printFiles2() and printFiles3(), will produce the same

output.

(d) Only the methods printFiles1() and printFiles3(), will produce the same

output.

(e) The program does not compile because the list() method does not exist in

the File class.

11.7



A file is readable but not writable on the file system of the host platform. What will

be the result of calling the method canWrite() on a File object representing this file?

Select the one correct answer.

(a)

(b)

(c)

(d)

(e)



11.8



A SecurityException is thrown.

The boolean value false is returned.

The boolean value true is returned.

The file is modified from being unwritable to being writable.

None of the above.



What is the type of the parameter given to the method renameTo() in the class File?

Select the one correct answer.

(a) File

(b) FileDescriptor

(c) FileNameFilter

(d) String

(e) char[]



11.9



If write(0x01234567) is called on an instance of OutputStream, what will be written to

the destination of the stream?

Select the one correct answer.

(a)

(b)

(c)

(d)

(e)



The bytes 0x01, 0x23, 0x34, 0x45, and 0x67, in that order.

The bytes 0x67, 0x45, 0x34, 0x23, and 0x01, in that order.

The byte 0x01.

The byte 0x67.

None of the above.



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

3 Byte Streams: Input Streams and Output Streams

Tải bản đầy đủ ngay(0 tr)

×