FileDocCategorySizeDatePackage
LogFileHandle.javaAPI DocGlassfish v2 API17740Fri May 04 22:36:38 BST 2007com.sun.jts.CosTransactions

LogFileHandle

public class LogFileHandle extends Object
This class encapsulates file I/O operations and the file handle.
version
0.01
author
Simon Holdsworth, IBM Corporation
see

Fields Summary
static final int
OPEN_RDONLY
The log file should be accessed in read only mode.
static final int
OPEN_RDWR
The log file should be accessed in read/write mode.
static final int
OPEN_CREAT
The log file should be opened as a new file if necessary.
static final int
OPEN_SYNC
The log file should be synchronized with the file system.
static final int
SEEK_RELATIVE
Seek relative location to the current position.
static final int
SEEK_ABSOLUTE
Seek absolute location in the file.
static final String
MODE_READONLY
Open options string for file read only.
static String
MODE_READWRITEOLD
Open options string for file read/write, old file.
static String
MODE_READWRITENEW
open options string for file read/write, new file.
static String
dsyncProp
static final String
DSYNC_PROPERTY
static final int
LOG_FNAME_MAX
The maximum length of a file name.
static final int
FILESYSTEM_BLOCKSIZE
The size of a block in the file system.
private RandomAccessFile
fhandle
Instance information.
private FileDescriptor
fd
private byte[]
bufferData
boolean
buffered
int
bufferUpdateStart
int
bufferUpdateEnd
int
buffPos
Constructors Summary
LogFileHandle()
Default LogFileHandle constructor.

param
return
see


     
        dsyncProp = System.getProperty(DSYNC_PROPERTY);
        if (dsyncProp != null) {
            MODE_READWRITEOLD = "rwd";   
            MODE_READWRITENEW = "rwd"; 
        }
    
        fhandle = null;
        fd      = null;                                                       //@MA

    
LogFileHandle(File file, int openOptions)
Creates a new file handle for the given file.

param
file The File to be opened.
param
int Open options
return
exception
LogException Opening the file failed.
see


        // Perform buffering depending on the flag.

        if (dsyncProp == null) {
            if( (openOptions & OPEN_SYNC) == 0 )
                buffered = true;
        }

        // Change the OpenOptions to the format expected by CLOSE

        if( (openOptions & OPEN_RDONLY) != 0 )
            fileOpen(file,MODE_READONLY);
        else
            try {
                fileOpen(file,MODE_READWRITEOLD);
            } catch( LogException e ) {
                if( (openOptions & OPEN_CREAT) != 0 )
                    fileOpen(file,MODE_READWRITENEW);
            }
    
Methods Summary
voidallocFileStorage(int bytesToClear)
Allocates more storage for the file.

param
bytesToClear Number of bytes to allocate for the file.
return
exception
LogException The allocation failed.
see

        int numberOfBlocks;                     // Number of blocks to write
        int bytesRemaining;                     // Remaining bytes
        //byte[] singleChar1 = new byte[1];
        byte[] singleChar2 = new byte[1];
        long bytesWritten;


        if( bytesToClear == 0 ) {
            return;
        }
        /* Don't bother with the compilcated version.  Just write out a byte at the
           appropriate place.

           // Calculate the number of blocks and remaining bytes

           numberOfBlocks = bytesToClear / FILESYSTEM_BLOCKSIZE;
           bytesRemaining = bytesToClear % FILESYSTEM_BLOCKSIZE;

           // Initialise the single characters to be written to force allocation.

           singleChar1[0] = (byte)0x01;
           singleChar2[0] = (byte)0xff;

           // For each block, write a single char and seek to the next block
           // multiple from the current position

           for( int i = 1; i <= numberOfBlocks; i++ )
           {

           // Write the single char at start of the file block

           fileWrite(singleChar1);

           // Now seek to the end of block

           fileSeek(FILESYSTEM_BLOCKSIZE-2,SEEK_RELATIVE);

           // Write the single char at end of the file block

           fileWrite(singleChar2);
           }

           // If there are still bytes remaining, get them allocated too.

           if( bytesRemaining > 0 )
           {

           // Now write out a byte at the beginning and end of the remaining
           // area to be allocated

           fileWrite(singleChar1);
           if( --bytesRemaining > 0 )
           {

           // Seek to end of area and write the last char

           fileSeek(bytesRemaining-1,SEEK_RELATIVE);

           // Now write a byte at the end of the remaining area to be allocated.

           fileWrite(singleChar2);
           }
           }

           This is the quick version which only does one write.
        */

        fileSeek(bytesToClear-1,SEEK_RELATIVE);
        fileWrite(singleChar2);

        // Move the file pointer back to its original location on the file
        // by seeking -BytesToClear

        fileSeek(-bytesToClear,SEEK_RELATIVE);

        // If the file is buffered, make sue the space is really allocated.

        if( buffered )
            fileSync();

    
voidfileClose()
Closes the file.

param
return
exception
LogException The close failed
see


        try {

            // If buffered, then ensure that the buffer is stored and synced with the
            // file system.

            if( bufferUpdateStart != -1 )
                fileSync();

            // Close the file.

            fhandle.close();
        } catch( Throwable e ) {
            throw new LogException(null,LogException.LOG_CLOSE_FAILURE,1);
        }

        // Reset the file handle and descriptor values.

        fhandle = null;
        fd = null;                                                            //@MA

    
voidfileOpen(java.io.File file, java.lang.String fileMode)
Opens the given file.

param
file The name of the file.
param
fileMode The mode to open in.
return
exception
LogException The open failed.
see

        fhandle = null;
        try {
            fhandle = new RandomAccessFile(file,fileMode);
            fd = fhandle.getFD();

            // If buffering, and the opened file has contents, then allocate the buffer
            // and read the file contents in.  Otherwise make the buffer an empty array.

            if( buffered )
                if( fhandle.length() > 0 ) {
                    bufferData = new byte[(int)fhandle.length()];
                    fhandle.readFully(bufferData);
                }
                else
                    bufferData = new byte[0];
        } catch( Throwable e ) {
            throw new LogException(null,LogException.LOG_OPEN_FAILURE,1);
        }

    
intfileRead(byte[] buffer)
Reads from the file.

param
buffer Buffer for file read.
return
Number of bytes read.
exception
LogException The read failed.
see


        int bytesRead = 0;

        if( buffer.length > 0 )
            try {

                // If buffered, then copy the file buffer into the required array.

                if( buffered ) {

                    // If the current position is beyond the end of the buffer then the read fails.

                    if( buffPos >= bufferData.length )
                        bytesRead = -1;

                    // Otherwise if the buffer is not big enough for all the bytes, return those that
                    // it does contain, else return all the bytes asked for.

                    else {
                        if( buffPos + buffer.length >= bufferData.length )
                            bytesRead = bufferData.length - buffPos;
                        else
                            bytesRead = buffer.length;

                        System.arraycopy(bufferData,buffPos,buffer,0,bytesRead);
                        buffPos += bytesRead;
                    }
                }

                // Otherwise read the data from the file.

                else {
                    bytesRead = fhandle.read(buffer);
                    if( bytesRead == -1 ) bytesRead = 0;
                }
            } catch( Throwable exc ) {
                throw new LogException(null,LogException.LOG_READ_FAILURE,1);
            }

        return bytesRead;
    
voidfileSeek(long position, int seekMode)
Seeks the given position in the file.

param
position Position to seek.
param
seekMode Mode of seek.
return
exception
LogException The seek failed.
see


        // Adjust the position being sought if it is relative to the current position.

        long absPos = position;
        try {

            // If buffered, then simply set the buffer position.
            // If the position is beyond the end of the buffer, then the buffer will be
            // extended when the next write occurs.

            if( buffered ) {
                if( seekMode == SEEK_RELATIVE )
                    absPos = buffPos + position;
                buffPos = (int)absPos;
            }

            // Otherwise seek the position in the file.

            else {
                if( seekMode == SEEK_RELATIVE )
                    absPos = fhandle.getFilePointer() + position;
                fhandle.seek(absPos);
            }
        } catch( Throwable e ) {
            throw new LogException(null,LogException.LOG_READ_FAILURE,1);
        }
    
voidfileSync()
Synchronises (flushes) the file to the file system.

param
return
exception
LogException The sync failed
see


        // Synchronization is only done for buffered files which have been updated.
        // Non-buffered files have every write synchronized with the file system.

        if( bufferUpdateStart != -1 )
            try {
                fhandle.seek(bufferUpdateStart);
                fhandle.write(bufferData,bufferUpdateStart,bufferUpdateEnd-bufferUpdateStart);
                if (dsyncProp == null)
                    fd.sync();

                bufferUpdateStart = -1;
                bufferUpdateEnd   = -1;
            } catch (Throwable e) {
                throw new LogException(null,LogException.LOG_READ_FAILURE,1);
            }

    
intfileWrite(byte[] buffer)
Writes to the file.

param
buffer The bytes to write.
return
The number of bytes written.
exception
LogException The write failed.
see


        if( buffer.length > 0 )
            try {

                // If buffered, then copy the array into the file buffer.

                if( buffered ) {

                    // If the array copy requires more bytes than exist in the buffer, then the
                    // buffer must be extended to the required size.

                    if( buffPos + buffer.length >= bufferData.length ) {
                        byte[] newBufferData = new byte[buffPos+buffer.length];
                        if( bufferData.length > 0 )
                            System.arraycopy(bufferData,0,newBufferData,0,bufferData.length);
                        bufferData = newBufferData;
                    }

                    // Copy the data.

                    System.arraycopy(buffer,0,bufferData,buffPos,buffer.length);

                    // Remember how much of the buffer has been updated, and increase the current
                    // buffer position.

                    if( bufferUpdateStart == -1 ||
                        buffPos < bufferUpdateStart )
                        bufferUpdateStart = buffPos;

                    buffPos += buffer.length;

                    if( buffPos > bufferUpdateEnd )
                        bufferUpdateEnd = buffPos;
                }

                // Otherwise write the data to the file.
                // For non-buffered writes, we always sync to the file system.

                else {
                    fhandle.write(buffer);
                    if (dsyncProp == null)
                        fd.sync();
                }
            } catch( Throwable e ) {
                int errCode = LogException.LOG_WRITE_FAILURE;
                //$     if( errno == ENOSPC )
                //$       retCode = LogControl.LOG_NO_SPACE;
                throw new LogException(null,errCode,1);
            }

        return buffer.length;
    
public voidfinalize()
Destroys the FileHandle, closing the file, if open.

param
return
exception
LogException The close of the file failed.
see


        // Ensure that the file is closed.
        // If the file is buffered, this ensures that the buffer is written out
        // if necessary.

        if( fhandle != null )
            fileClose();

        // Discard the buffer.

        bufferData = null;

    
intreadVector(byte[][] vector)
Reads a vector of records from the file.

param
vector The vector to contain the records to be read.
return
The total number of bytes read.
exception
LogException The read failed.
see

        int bytesRead = 0;
        for( int i = 0; i < vector.length; i++ )
            bytesRead += fileRead(vector[i]);

        return bytesRead;