Chapter 18. Advanced Input Output

  • Random Access File

  • Running Commands and Getting Output From Them

  • Formatted String Output

  • Writing Objects to Disk

  • New I/O Package

  • Memory Mapped I/O

  • File Locking

  • Charsets and Endian-ness

  • Exercises

  • Some Light Relief—The Illegal T-shirt!

I-O!

I-O!

It's off to work we go!

I-O, I/O, I/O.

This chapter follows on from the basic I/O chapter and provides information on more advanced I/O techniques in about a half-dozen sections, mostly independent. The section on the new I/O package (new in JDK 1.4 that is, with the name java.nio) is needed to understand the three other JDK 1.4 features of pattern matching, file locking, and character sets. You can read other sections in any order, or indeed skip the entire chapter now and return when you need information on any one of these topics.

Random Access File

Until now we have seen how input and output is done in a serial mode. However, sometimes we want to be able to move around inside a file and write to different locations, or read from different locations, without having to scan all the data. Traveling in a file stream in such a manner is called “random access”.

Java has a random access file class that can do these operations. This is not an indexed sequential file or a direct access file of the kind supported by data processing languages. Those two techniques require the creation and maintenance of special indexes to address the file. The class java.io.RandomAccessFile does not use indices, but lets you access a file as though it were an array of bytes. There is an index or pointer that says where the next read or write will take place. You set the position of the file pointer with the method seek(), giving an argument that is the absolute offset into the file. When you set the file pointer, the next access will take place at the offset indicated. Because of the way operating systems store file contents, moving around in a file does not necessarily involve inefficient reading and rereading.

class java.io.RandomAccessFile

public class RandomAccessFile implements java.io.DataOutput, java.io.DataInput {
    public RandomAccessFile(java.lang.String,java.lang.String) throws
         java.io.FileNotFoundException;
    public RandomAccessFile(java.io.File,java.lang.String) throws java.io.FileNotFoundException;
    public final java.nio.channels.FileChannel getChannel();  // used for locking file
    public final java.io.FileDescriptor getFD() throws java.io.IOException;
    public native int read() throws java.io.IOException;
    public int read(byte[], int, int) throws java.io.IOException;
    public int read(byte[]) throws java.io.IOException;
    public final void readFully(byte[]) throws java.io.IOException;
    public final void readFully(byte[], int, int) throws java.io.IOException;
    public int skipBytes(int) throws java.io.IOException;
    public native void write(int) throws java.io.IOException;
    public void write(byte[]) throws java.io.IOException;
    public void write(byte[], int, int) throws java.io.IOException;

    public native long getFilePointer() throws java.io.IOException;
    public native void seek(long) throws java.io.IOException;
    public native long length() throws java.io.IOException;
    public native void setLength(long) throws java.io.IOException;
    public native void close() throws java.io.IOException;

    public final boolean readBoolean() throws java.io.IOException;
    public final byte readByte() throws java.io.IOException;
    public final int readUnsignedByte() throws java.io.IOException;
    public final short readShort() throws java.io.IOException;
    public final int readUnsignedShort() throws java.io.IOException;
    public final char readChar() throws java.io.IOException;
    public final int readInt() throws java.io.IOException;
    public final long readLong() throws java.io.IOException;
    public final float readFloat() throws java.io.IOException;
    public final double readDouble() throws java.io.IOException;
    public final java.lang.String readLine() throws java.io.IOException;
    public final java.lang.String readUTF() throws java.io.IOException;
    public final void writeBoolean(boolean) throws java.io.IOException;
    public final void writeByte(int) throws java.io.IOException;
    public final void writeShort(int) throws java.io.IOException;
    public final void writeChar(int) throws java.io.IOException;
    public final void writeInt(int) throws java.io.IOException;
    public final void writeLong(long) throws java.io.IOException;
    public final void writeFloat(float) throws java.io.IOException;
    public final void writeDouble(double) throws java.io.IOException;
    public final void writeBytes(java.lang.String) throws java.io.IOException;
    public final void writeChars(java.lang.String) throws java.io.IOException;
    public final void writeUTF(java.lang.String) throws java.io.IOException;
}

You instantiate a random access file with a mode string that says whether you plan to read the file or both read and write it. The mode string is “r” for reading, and “rw” for reading and writing. Throughout Java I/O, although there is a notion of closing files, there is no notion of opening a file. More precisely, when you instantiate of file object, that automatically opens the file for I/O. When you open for read/write access, if the file does not exist, it is created.

The following is an example of opening a random access file, seeking to the end, and then writing some more data. You should run this program and check that you get the expected output. When you run the program repeatedly, you will see it is appending to its output file.

import java.io.*;
public class Raf {
    public static void main(String args[]) throws IOException {
       RandomAccessFile myRAF = new RandomAccessFile("myfile.dat", "rw");
       myRAF.seek( myRAF.length() ); // append to end of file
       myRAF.writeInt(5);
       myRAF.writeInt(0xBEEF);
       myRAF.writeBytes("at end.");
       myRAF.close();
       System.out.println("file myfile.dat written ok");
    }
}

You can use the program Dump.java from the previous chapter to look at the hex values written. You can run it and see something like this:

java Raf
file myfile.dat written ok
java Dump myfile.dat
type myfile.dat.hex
Hex dump of file myfile.dat 2004-04-29 15:02:11.093

00000000:  00000005  0000BEEF  61742065  6E642E

RandomAccessFile doesn't fit very well into the rest of the I/O framework, but nonetheless provides some useful features, including being able to read a line of data. It's in the Java API because it's in the underlying Unix API.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.242