Performing IO

Paid Online Writing Jobs

Get Paid to Write at Home

Get Instant Access

1. The purpose of the File class is to offer access to the underlying platform's available filesystem(s).

2. Instances of the File class contain the pathnames of files and directories that may or may not exist in their filesystems.

3. File's listRoots() method returns an array of File objects denoting the root directories (roots) of available filesystems.

4. A path is a hierarchy of directories that must be traversed to locate a file or a directory. A pathname is a string representation of a path; a platform-dependent separator character (such as the Windows backslash [\] character) appears between consecutive names.

5. The difference between an absolute pathname and a relative pathname is as follows: an absolute pathname is a pathname that starts with the root directory symbol, whereas a relative pathname is a pathname that does not start with the root directory symbol; it is interpreted via information taken from some other pathname.

6. You obtain the current user (also known as working) directory by specifying System.getProperty("user.dir").

7. A parent pathname is a string that consists of all pathname components except for the last name.

8. Normalize means to replace separator characters with the default name-separator character so that the pathname is compliant with the underlying filesystem.

9. You obtain the default name-separator character by accessing File's separator and separatorChar static fields. The first field stores the character as a char and the second field stores it as a String.

10. A canonical pathname is a pathname that is absolute and unique.

11. The difference between File's getParent() and getName() methods is that getParent() returns the parent pathname and getName() returns the last name in the pathname's name sequence.

12. The answer is false: File's exists() method determines whether or not a file or directory exists.

13. A normal file is a file that is not a directory and satisfies other platform-dependent criteria: it is not a symbolic link or named pipe, for example. Any nondirectory file created by a Java application is guaranteed to be a normal file.

14. File's lastModified() method returns the time that the file denoted by this File object's pathname was last modified, or 0 when the file does not exist or an I/O error occurred during this method call. The returned value is measured in milliseconds since the Unix epoch (00:00:00 GMT, January 1, 1970).

15. The answer is true: File's list() method returns an array of Strings where each entry is a filename rather than a complete path.

16. The difference between the FilenameFilter and FileFilter interfaces is as follows: FilenameFilter declares a single boolean accept(File dir, String name) method, whereas FileFilter declares a single boolean accept(String pathname) method. Either method accomplishes the same task of accepting (by returning true) or rejecting (by returning false) the inclusion of the file or directory identified by the argument(s) in a directory listing.

17. The answer is false: File's createNewFile() method checks for file existence and creates the file if it does not exist in a single operation that is atomic with respect to all other filesystem activities that might affect the file.

18. The default temporary directory where File's createTempFile(String, String) method creates temporary files can be located by reading the java.io.tmpdir system property.

19. You ensure that a temporary file is removed when the virtual machine ends normally (it does not crash or the power is not lost) by registering the temporary file for deletion through a call to File's deleteOnExit() method.

20. You would accurately compare two File objects by first calling File's getCanonicalFile() method on each File object and then comparing the returned File objects.

21. The purpose of the RandomAccessFile class is to create and/or open files for random access in which a mixture of write and read operations can occur until the file is closed.

22. The purpose of the "rwd" and "rws" mode arguments is to ensure than any writes to a file located on a local storage device are written to the device, which guarantees that critical data is not lost when the system crashes. No guarantee is made when the file does not reside on a local device.

23. A file pointer is a cursor that identifies the location of the next byte to write or read. When an existing file is opened, the file pointer is set to its first byte, at offset 0. The file pointer is also set to 0 when the file is created.

24. The answer is false: when you call RandomAccessFile's seek(long) method to set the file pointer's value, and if this value is greater than the length of the file, the file's length does not change. The file length will only change by writing after the offset has been set beyond the end of the file.

25. A flat file database is a single file organized into records and fields. A record stores a single entry (such as a part in a parts database) and a field stores a single attribute of the entry (such as a part number).

26. A stream is an ordered sequence of bytes of arbitrary length. Bytes flow over an output stream from an application to a destination, and flow over an input stream from a source to an application.

27. The purpose of OutputStream's flush() method is to write any buffered output bytes to the destination. If the intended destination of this output stream is an abstraction provided by the underlying platform (for example, a file), flushing the stream only guarantees that bytes previously written to the stream are passed to the underlying platform for writing; it does not guarantee that they are actually written to a physical device such as a disk drive.

28. The answer is true: OutputStream's close() method automatically flushes the output stream. If an application ends before close() is called, the output stream is automatically closed and its data is flushed.

29. The purpose of InputStream's mark(int) and reset() methods is to reread a portion of a stream. mark(int) marks the current position in this input stream. A subsequent call to reset() repositions this stream to the last marked position so that subsequent read operations reread the same bytes. Do not forget to call markSupported() to find out if the subclass supports mark() and reset().

30. You would access a copy of a ByteArrayOutputStream instance's internal byte array by calling ByteArrayOutputStream's toByteArray() method.

31. The answer is false: FileOutputStream and FileInputStream do not provide internal buffers to improve the performance of write and read operations.

32. You would use PipedOutputStream and PipedInputStream to communicate data between a pair of executing threads.

33. A filter stream is a stream that buffers, compresses/uncompresses, encrypts/decrypts, or otherwise manipulates an input stream's byte sequence before it reaches its destination.

34. Two streams are chained together when a stream instance is passed to another stream class's constructor.

35. You improve the performance of a file output stream by chaining a BufferedOutputStream instance to a FileOutputStream instance and calling the BufferedOutputStream instance's write() methods so that data is buffered before flowing to the file output stream. You improve the performance of a file input stream by chaining a BufferedInputStream instance to a FileInputStream instance so that data flowing from a file input stream is buffered before being returned from the BufferedInputStream instance by calling this instance's read() methods.

36. DataOutputStream and DataInputStream support FileOutputStream and FileInputStream by providing methods to write and read primitive type values and strings in a platform-independent way. In contrast, FileOutputStream and FileInputStream provide methods for writing/reading bytes and arrays of bytes only.

37. Object serialization is a virtual machine mechanism for serializing object state into a stream of bytes. Its deserialization counterpart is a virtual machine mechanism for deserializing this state from a byte stream.

38. The three forms of serialization and deserialization that Java supports are default serialization and deserialization, custom serialization and deserialization, and externalization.

39. The purpose of the Serializable interface is to tell the virtual machine that it is okay to serialize objects of the implementing class.

40. When the serialization mechanism encounters an object whose class does not implement Serializable, it throws an instance of the NotSerializableException class.

41. The three stated reasons for Java not supporting unlimited serialization are as follows: security, performance, and objects not amenable to serialization.

42. You initiate serialization by creating an ObjectOutputStream instance and calling its writeObject() method. You initialize deserialization by creating an ObjectlnputStream instance and calling its readObject() method.

43. The answer is false: class fields are not automatically serialized.

44. The purpose of the transient reserved word is to mark instance fields that do not participate in default serialization and default deserialization.

45. The deserialization mechanism causes readObject() to throw an instance of the InvalidClassException class when it attempts to deserialize an object whose class has changed.

46. The deserialization mechanism detects that a serialized object's class has changed as follows: Every serialized object has an identifier. The deserialization mechanism compares the identifier of the object being deserialized with the serialized identifier of its class (all serializable classes are automatically given unique identifiers unless they explicitly specify their own identifiers) and causes InvalidClassException to be thrown when it detects a mismatch.

47. You can add an instance field to a class and avoid trouble when deserializing an object that was serialized before the instance field was added by introducing a long serialVersionUID = long integer value; declaration into the class. The long integer value must be unique and is known as a stream unique identifier (SUID). You can use the JDK's serialver tool to help with this task.

48. You customize the default serialization and deserialization mechanisms without using externalization by declaring private void writeObject(ObjectOutputStream) and void readObject(ObjectlnputStream) methods in the class.

49. You tell the serialization and deserialization mechanisms to serialize or deserialize the object's normal state before serializing or deserializing additional data items by first calling ObjectOutputStream's defaultWriteObject() method in writeObject(ObjectOutputStream) and by first calling ObjectlnputStream's defaultReadObject() method in readObject(ObjectlnputStream).

50. Externalization differs from default and custom serialization and deserialization in that it offers complete control over the serialization and deserialization tasks.

51. A class indicates that it supports externalization by implementing the Externalizable interface instead of Serializable, and by declaring void writeExternal(ObjectOutput) and void readExternal(ObjectInput in) methods instead of void writeObject(ObjectOutputStream) and void readObject(ObjectInputStream) methods.

52. The answer is true: during externalization, the deserialization mechanism throws InvalidClassException with a "no valid constructor" message when it does not detect a public noargument constructor.

53. The difference between PrintStream's print() and println() methods is that the print() methods do not append a line terminator to their output, whereas the println() methods append a line terminator.

54. PrintStream's noargument void println() method outputs the line.separator system property's value to ensure that lines are terminated in a portable manner (such as a carriage return followed by a newline/line feed on Windows, or only a newline/line feed on Unix/Linux).

55. The answer is true: PrintStream's %tR format specifier is used to format a Calendar object's time as HH:MM.

56. Java's stream classes are not good at streaming characters because bytes and characters are two different things: a byte represents an 8-bit data item and a character represents a 16-bit data item. Also, byte streams have no knowledge of character sets and their character encodings.

57. Java provides writer and reader classes as the preferred alternative to stream classes when it comes to character I/O.

58. The answer is false: Reader does not declare an available() method.

59. The purpose of the OutputStreamWriter class is to serve as a bridge between an incoming sequence of characters and an outgoing stream of bytes. Characters written to this writer are encoded into bytes according to the default or specified character encoding. The purpose of the InputStreamReader class is to serve as a bridge between an incoming stream of bytes and an outgoing sequence of characters. Characters read from this reader are decoded from bytes according to the default or specified character encoding.

60. You identify the default character encoding by reading the value of the file.encoding system property.

61. The purpose of the FileWriter class is to conveniently connect to the underlying file output stream using the default character encoding. The purpose of the FileReader class is to conveniently connect to the underlying file input stream using the default character encoding.

62. Listing 42 presents the Touch application that was called for in Chapter 10.

Listing 42. Setting a file or directory's timestamp to the current or specified time import java.io.File;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class Touch {

public static void main(String[] args) {

if (args.length != 1 && args.length != 3) {

System.err.println("usage: java Touch [-d timestamp] pathname"); return;

SimpleDateFormat sdf;

sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); Date date = sdf.parse(args[l]); time = date.getTime();

catch (ParseException pe) {

pe.printStackTrace();

System.err.println("invalid option: " + args[0]); return;

new File(args[args.length == 1 ? 0 : 2]).setLastModified(time);

63. Listing 43 presents the Media class that was called for in Chapter 10.

Listing 43. Obtaining the data from an MP3 file's 128-byte ID3 block, and creating/populating/returning an ID3 object with this data import java.io.IOException; import java.io.RandomAccessFile;

public class Media {

public static class ID3 {

private String songTitle, artist, album, year, comment, genre; private int track; // -1 if track not present public ID3(String songTitle, String artist, String album, String year, String comment, int track, String genre)

this.songTitle = songTitle; this.artist = artist; this.album = album; this.year = year; this.comment = comment; this.track = track; this.genre = genre;

String getSongTitle() { return songTitle; } String getArtist() { return artist; } String getAlbum() { return album; } String getYear() { return year; } String getComment() { return comment; } int getTrack() { return track; } String getGenre() { return genre; }

public static ID3 getID3Info(String mp3path) throws IOException {

RandomAccessFile raf = null;

raf = new RandomAccessFile(mp3path, "r"); if (raf.length() < 128)

return null; // Not MP3 file (way too small) raf.seek(raf.length()-128); byte[] buffer = new byte[128]; raf.read(buffer); raf.close();

if (buffer[0] != (byte) 'T' && buffer[1] != (byte) 'A' && buffer[2] != (byte) 'G') return null; // No ID3 block (must start with TAG) String songTitle = new String(buffer, 3, 30); String artist = new String(buffer, 33, 30); String album = new String(buffer, 63, 30); String year = new String(buffer, 93, 4); String comment = new String(buffer, 97, 28); // buffer[126]&255 converts -128 through 127 to 0 through 255 int track = (buffer[125] == 0) ? buffer[126]&255 : -1;

"Blues",

"Classic Rock",

"Country",

"Dance",

"Disco",

"Funk",

"Grunge",

"Hip-Hop",

"Jazz",

"Metal",

"New Age",

"Oldies",

"Other",

"Reggae",

"Rock",

"Techno",

"Industrial",

"Alternative",

"Death Metal", "Pranks",

"Soundtrack",

"Euro-Techno",

"Ambient",

"Trip-Hop",

"Vocal",

"Jazz+Funk",

"Fusion",

"Trance",

"Classical",

"Instrumental",

"Acid",

"House",

"Game",

"Sound Clip",

"Gospel",

"Noise",

"AlternRock",

"Bass",

"Soul",

"Punk",

"Space",

"Meditative",

"Instrumental Pop",

"Instrumental Rock",

"Ethnic",

"Gothic",

"Darkwave",

"Techno-Industrial",

"Electronic",

"Pop-Folk",

"Eurodance",

"Dream",

"Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle",

"Native American",

"Cabaret",

"New Wave",

"Psychedelic",

"Rave",

"Showtunes",

"Trailer",

"Tribal",

"Acid Punk",

"Acid Jazz",

"Polka",

"Retro",

"Musical",

"Hard Rock",

"Folk",

"Folk-Rock",

"National-Folk",

"Swing",

"Fast Fusion",

"Bebob",

"Latin",

"Revival",

"Celtic",

"Bluegrass",

"Avantegarde",

"Gothic Rock",

"Progressive Rock",

"Psychedelic Rock",

"Symphonic Rock",

"Slow Rock",

"Big Band",

"Chorus",

"Easy Listening",

"Acoustic",

"Humour",

"Speech",

"Chanson",

"Opera",

"Chamber Music",

"Sonata",

"Symphony",

"Booty Brass",

"Primus",

"Porn Groove",

"Satire",

"Slow Jam",

"Club",

"Tango",

"Samba",

"Folklore",

"Ballad",

"Power Ballad",

"Rhythmic Soul",

"Freestyle",

"Duet",

"Punk Rock",

"Drum Solo",

"A cappella",

"Euro-House",

"Dance Hall"

assert genres.length == 126;

String genre = (buffer[l27] < 0 || buffer[l27] > 125) ? "Unknown" : genres[buffer[l27]];

return new ID3(songTitle, artist, album, year, comment, track, genre);

catch (IOException ioe) {

catch (IOException ioe2) {

ioe2.printStackTrace();

throw ioe;

64. Listing 44 presents the Split application that was called for in Chapter 10.

Listing 44. Splitting a large file into numerous smaller part flies import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;

public class Split {

static final int FILESIZE = 1400000; static byte[] buffer = new byte[FILESIZE];

public static void main(String[] args) {

System.err.println("usage: java Split pathname"); return;

long length = file.length();

int nWholeParts = (int) (length/FILESIZE);

int remainder = (int) (length%FILESIZE);

System.out.printf("Splitting %s into %d parts%n", args[0],

(remainder == 0) ? nWholeParts : nWholeParts+1); BufferedInputStream bis = null; BufferedOutputStream bos = null;

FileInputStream fis = new FileInputStream(args[0]); bis = new BufferedInputStream(fis);

bis.read(buffer);

System.out.println("Writing part " + i);

FileOutputStream fos = new FileOutputStream("part" + i);

bos = new BufferedOutputStream(fos);

bos.write(buffer);

System.err.println("Last part mismatch: expected " + remainder + " bytes");

System.exit(o);

System.out.println("Writing part " + nWholeParts);

FileOutputStream fos = new FileOutputStream("part" + nWholeParts);

bos = new BufferedOutputStream(fos);

bos.write(buffer, 0, remainder);

catch (IOException ioe) {

catch (IOException ioe2) {

ioe2.printStackTrace();

catch (IOException ioe2) {

ioe2.printStackTrace();

65. Listing 45 presents the CircleInfo application that was called for in Chapter 10.

Listing 45. Reading lines of text from standard input that represent circle radii, and outputting circumference and area based on the current radius import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException;

public class CircleInfo {

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

InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr);

System.out.print("Enter circle's radius: "); String str = br.readLine(); double radius;

radius = Double.valueOf(str).doubleValue(); if (radius <= 0)

System.err.println("radius must not be 0 or negative");

System.out.println("Circumference: " + Math.PI*2.0*radius); System.out.println("Area: " + Math.PI*radius*radius);

catch (NumberFormatException nfe) {

nfe.printStackTrace();

Was this article helpful?

0 0

Post a comment