org.entityfs.util.io
Class TempFileBackedRandomAccess

java.lang.Object
  extended by org.entityfs.util.io.TempFileBackedRandomAccess
All Implemented Interfaces:
DataSink, DataSource, RandomAccess

public class TempFileBackedRandomAccess
extends Object
implements RandomAccess

This object can be used to open a RandomAccess on a file from a file system that does not support the FSCRandomAccessFiles capability. It copies the master file's contents to a temporary file in another file system that supports FSCRandomAccessFiles and lets the client use a RandomAccess from that file. If the client writes to the RandomAccess, changes are flushed to the master file when this object is closed or whenever flush() is called.

Until this object is close():d, it holds a read or a write lock on the master file, depending on the RandomAccessMode used for opening it. The temporary file is also locked. Since this object keeps those locks internally, it can only be used from the thread that created it.

For read only files, InputStreamBackedRandomAccess may be faster.

Since:
1.0
Author:
Karl Gustafsson
See Also:
InputStreamBackedRandomAccess

Constructor Summary
TempFileBackedRandomAccess(EFile f, DirectoryView tmpDir, RandomAccessMode mode)
          Create a new temporary file-backed RandomAccess object.
TempFileBackedRandomAccess(EFile f, DirectoryView tmpDir, String tmpFileName, RandomAccessMode mode)
          Create a new temporary file-backed RandomAccess object.
TempFileBackedRandomAccess(EFile f, FileSystem fs, RandomAccessMode mode)
          Create a new temporary file-backed RandomAccess object.
 
Method Summary
 void addCloseObserver(RandomAccessCloseObserver raco)
          Add an observer that is notified when this RandomAccess is closed.
 int available()
          Returns an estimate of the number of bytes that can be read from this data source without blocking by the next invocation of a method for this data source.
 void close()
          Close the RandomAccess and flush changes to the master file, if there has been any.
protected  void finalize()
           
 void flush()
          If the temporary file has been written to, flush changes to the master file.
 long getFilePointer()
          Get the current offset in the file.
 RandomAccessMode getMode()
          Get the mode that this RandomAccess was opened in.
 long length()
          Get the file's current length.
 int read()
          Read a byte of data from the source.
 int read(byte[] barr)
          Read up to b.length bytes of data from the source into the array.
 int read(byte[] barr, int off, int len)
          Read up to len bytes of data from the source into the array.
 void seek(long pos)
          Set the file pointer offset, measured from the beginning of the file.
 void setLength(long l)
          Set the length of the file.
 long skipBytes(long n)
          Attempt to skip over n bytes in the source.
 void write(byte[] barr)
          Write the contents of the array to the sink, starting at the current file pointer.
 void write(byte[] barr, int off, int len)
          Write len bytes from the array, starting at the offset off to this sink.
 void write(int b)
          Write a byte to the sink.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TempFileBackedRandomAccess

public TempFileBackedRandomAccess(EFile f,
                                  FileSystem fs,
                                  RandomAccessMode mode)
                           throws IllegalArgumentException,
                                  FileSystemException
Create a new temporary file-backed RandomAccess object.

Parameters:
f - The file to get a RandomAccess for.
fs - The file system in whose temporary files directory the temporary file should be created. The file system must support the FSCRandomAccessFiles capability. See FileSystem.setTemporaryFilesDirectory(org.entityfs.Directory) .
mode - The mode to open the file in.
Throws:
IllegalArgumentException - If the supplied file system does not have its temporary files directory set.
FileSystemException - On other errors when initializing the temporary file.

TempFileBackedRandomAccess

public TempFileBackedRandomAccess(EFile f,
                                  DirectoryView tmpDir,
                                  RandomAccessMode mode)
                           throws FileSystemException
Create a new temporary file-backed RandomAccess object.

Parameters:
f - The file to get a RandomAccess for.
tmpDir - The directory where the temporary file should be created. This directory must be in a file system that supports the FSCRandomAccessFiles capability.
mode - The mode to open the file in.
Throws:
FileSystemException - On errors when initializing the temporary file.

TempFileBackedRandomAccess

public TempFileBackedRandomAccess(EFile f,
                                  DirectoryView tmpDir,
                                  String tmpFileName,
                                  RandomAccessMode mode)
                           throws FileSystemException
Create a new temporary file-backed RandomAccess object.

Parameters:
f - The file to get a RandomAccess for.
tmpDir - The directory where the temporary file should be put. This directory must be in a file system that supports the FSCRandomAccessFiles capability.
tmpFileName - The name of the temporary file. If null, a unique temporary file name is created by calling DirectoryView.getUniqueEntityName(String, String) on the temporary directory.
mode - The mode to open the file in.
Throws:
FileSystemException - On errors setting up the temporary file.
Method Detail

available

public int available()
Description copied from interface: DataSource
Returns an estimate of the number of bytes that can be read from this data source without blocking by the next invocation of a method for this data source.

Specified by:
available in interface DataSource
Returns:
An estimate of the number of bytes that can be read without blocking.
See Also:
InputStream.available()

length

public long length()
Description copied from interface: RandomAccess
Get the file's current length.

Specified by:
length in interface RandomAccess
Returns:
The file's current length.

getFilePointer

public long getFilePointer()
Description copied from interface: RandomAccess
Get the current offset in the file.

Specified by:
getFilePointer in interface RandomAccess
Returns:
The offset from the beginning of the file.

read

public int read()
         throws IllegalStateException
Description copied from interface: DataSource
Read a byte of data from the source. The byte is returned as an integer in the range 0 to 255 (0x00-0x0ff).

Specified by:
read in interface DataSource
Returns:
The next byte of data, or -1 if the end of the source has been reached.
Throws:
IllegalStateException - If the source is closed.

read

public int read(byte[] barr)
         throws IllegalStateException
Description copied from interface: DataSource
Read up to b.length bytes of data from the source into the array.

Specified by:
read in interface DataSource
Parameters:
barr - The byte array into which data is read.
Returns:
The total number of bytes read into the array, or -1 if no data could be read because the the end of the source was reached before the read started.
Throws:
IllegalStateException - If the source is closed.

read

public int read(byte[] barr,
                int off,
                int len)
         throws IllegalStateException
Description copied from interface: DataSource
Read up to len bytes of data from the source into the array.

Specified by:
read in interface DataSource
Parameters:
barr - The byte array into which data is read.
off - The start offset in the array b at which data is written.
len - The maximum number of bytes to read.
Returns:
The total number of bytes read into the array, or -1 if no data could be read because the end of the source was reached before the read started.
Throws:
IllegalStateException - If the source is closed.

seek

public void seek(long pos)
          throws FileSystemException,
                 IllegalStateException
Description copied from interface: RandomAccess
Set the file pointer offset, measured from the beginning of the file. If the offset is set beyond the end of the file does not change the file length until something is written to it.

Specified by:
seek in interface RandomAccess
Parameters:
pos - The new file pointer offset, measured from the beginning of the file.
Throws:
FileSystemException - If pos < 0.
IllegalStateException - If the random access file is closed.
See Also:
DataSource.skipBytes(long)

setLength

public void setLength(long l)
               throws ReadOnlyException,
                      IllegalStateException
Description copied from interface: RandomAccess
Set the length of the file.

If the present length of the file is greater than the l argument, the file will be truncated.

If the new length is bigger than the current length of the file, the file will be extended. The contents of the extended portion of the file are not defined.

The current file pointer is not changed, unless the file pointer offset is greater than the new file length. If so, it will be set to the new length.

Specified by:
setLength in interface RandomAccess
Parameters:
l - The new length of the file.
Throws:
ReadOnlyException - If the file is opened read only.
IllegalStateException - If the random access file is closed.

skipBytes

public long skipBytes(long n)
               throws IllegalStateException
Description copied from interface: DataSource
Attempt to skip over n bytes in the source. If n is negative, no bytes are skipped.

The pointer in the source cannot be moved beyond EOF using this method (unlike RandomAccess.seek(long)).

Specified by:
skipBytes in interface DataSource
Parameters:
n - The number of bytes to increment the source pointer with.
Returns:
The number of bytes actually skipped.
Throws:
IllegalStateException - If the source is closed.
See Also:
RandomAccess.seek(long)

write

public void write(byte[] barr)
           throws ReadOnlyException,
                  IllegalStateException
Description copied from interface: DataSink
Write the contents of the array to the sink, starting at the current file pointer.

Specified by:
write in interface DataSink
Parameters:
barr - The array to write.
Throws:
ReadOnlyException - If the sink is opened read only.
IllegalStateException - If the sink is closed.

write

public void write(byte[] barr,
                  int off,
                  int len)
           throws ReadOnlyException,
                  IllegalStateException
Description copied from interface: DataSink
Write len bytes from the array, starting at the offset off to this sink.

Specified by:
write in interface DataSink
Parameters:
barr - The byte array.
off - The starting offset in the array.
len - The number of bytes to write.
Throws:
ReadOnlyException - If the sink is opened read only.
IllegalStateException - If the sink file is closed.

write

public void write(int b)
           throws ReadOnlyException,
                  IllegalStateException
Description copied from interface: DataSink
Write a byte to the sink.

Specified by:
write in interface DataSink
Parameters:
b - The byte to write.
Throws:
ReadOnlyException - If the sink is opened read only.
IllegalStateException - If the random access file is closed.

flush

public void flush()
           throws WrappedIOException,
                  IllegalStateException
If the temporary file has been written to, flush changes to the master file.

Specified by:
flush in interface DataSink
Throws:
WrappedIOException - On I/O errors.
IllegalStateException - If the sink is closed.

getMode

public RandomAccessMode getMode()
Description copied from interface: RandomAccess
Get the mode that this RandomAccess was opened in.

This method does not throw an IllegalStateException if it is called after the RandomAccess has been closed.

Specified by:
getMode in interface RandomAccess
Returns:
The mode that this RandomAccess was opened in.

addCloseObserver

public void addCloseObserver(RandomAccessCloseObserver raco)
Description copied from interface: RandomAccess
Add an observer that is notified when this RandomAccess is closed. The observers are called just after the RandomAccess has been closed.

Specified by:
addCloseObserver in interface RandomAccess
Parameters:
raco - The observer.

close

public void close()
           throws FileSystemException
Close the RandomAccess and flush changes to the master file, if there has been any. Deletes the temporary file and releases all locks on the master file.

This method acquires a temporary write lock on the temporary file's parent directory.

If the flushing fails, this object is not closed.

Specified by:
close in interface DataSink
Specified by:
close in interface DataSource
Throws:
FileSystemException - On errors. If the flushing fails, this object is not closed.

finalize

protected void finalize()
                 throws Throwable
Overrides:
finalize in class Object
Throws:
Throwable