Package nom.tam.util

Class FitsFile

All Implemented Interfaces:
Closeable, DataInput, DataOutput, Flushable, AutoCloseable, ArrayDataInput, ArrayDataOutput, FitsIO, FitsOutput, InputReader, OutputWriter, RandomAccess, ReadWriteAccess
Direct Known Subclasses:
BufferedFile

public class FitsFile extends ArrayDataFile implements FitsOutput, RandomAccess
For reading and writing FITS files. It provides buffered random access and efficient handling of arrays. Primitive arrays may be written using a single method call. Large buffers are used to minimize synchronization overheads since methods of this class are not synchronized.

Note that although this class supports most of the contract of RandomAccessFile it does not (and can not) extend that class since many of the methods of RandomAccessFile are final. In practice this method works much like the StreamFilter classes. All methods are implemented in this class but some are simply delegated to an underlying RandomAccessFile member.

Testing and timing routines are available in the nom.tam.util.test.BufferedFileTester class.

Prior versions of this class under the old BufferedFile name:

  • Version 1.1 -- October 12, 2000: Fixed handling of EOF in array reads so that a partial array will be returned when an EOF is detected. Excess bytes that cannot be used to construct array elements will be discarded (e.g., if there are 2 bytes left and the user is reading an int array).
  • Version 1.2 -- December 8, 2002: Added getChannel method.
  • Version 1.3 -- March 2, 2007: Added File based constructors.
  • Version 1.4 -- July 20, 2009: Added support for >2G Object reads. This is still a bit problematic in that we do not support primitive arrays larger than 2 GB/atomsize. However except in the case of bytes this is not currently a major issue.

Version 2.0 -- Oct 30, 2021: New hierarchy for more digestible code. Improved buffering, and renamed from BufferedFile to the more appropriate name of FitsFile. Performance is 2-4 times better than before.

Since:
1.16
See Also:
  • Constructor Details

    • FitsFile

      public FitsFile(File file) throws IOException
      Create a buffered file from a File descriptor
      Parameters:
      file - the file to open.
      Throws:
      IOException - if the file could not be opened
    • FitsFile

      public FitsFile(File file, String mode) throws IOException
      Create a buffered file from a File descriptor
      Parameters:
      file - the file to open.
      mode - the mode to open the file in
      Throws:
      IOException - if the file could not be opened
    • FitsFile

      public FitsFile(File file, String mode, int bufferSize) throws IOException
      Create a buffered file from a file descriptor
      Parameters:
      file - the file to open.
      mode - the mode to open the file in
      bufferSize - the dataBuffer.buffer size to use
      Throws:
      IOException - if the file could not be opened
    • FitsFile

      public FitsFile(RandomAccessFileIO src, int bufferSize) throws IOException
      Create a buffered file from a random access data object.
      Parameters:
      src - random access data
      bufferSize - the dataBuffer's buffer size to use
      Throws:
      IOException - if data could not be read
    • FitsFile

      public FitsFile(String filename) throws IOException
      Create a read-only buffered file
      Parameters:
      filename - the name of the file to open
      Throws:
      IOException - if the file could not be opened
    • FitsFile

      public FitsFile(String filename, String mode) throws IOException
      Create a buffered file with the given mode.
      Parameters:
      filename - The file to be accessed.
      mode - A string composed of "r" and "w" for read and write access.
      Throws:
      IOException - if the file could not be opened
    • FitsFile

      public FitsFile(String filename, String mode, int bufferSize) throws IOException
      Create a buffered file with the given mode and a specified dataBuffer.buffer size.
      Parameters:
      filename - The file to be accessed.
      mode - A string composed of "r" and "w" indicating read or write access.
      bufferSize - The dataBuffer.buffer size to be used. This should be substantially larger than 100 bytes and defaults to 32768 bytes in the other constructors.
      Throws:
      IOException - if the file could not be opened
  • Method Details

    • getEncoder

      public FitsEncoder getEncoder()
      Description copied from class: ArrayDataFile
      Returns the conversion from Java arrays to their binary representation in file. Subclass implementations can use this to access the required conversion when writing data to file.
      Overrides:
      getEncoder in class ArrayDataFile
      Returns:
      the conversion from Java arrays to their binary representation in file
      See Also:
    • getDecoder

      public FitsDecoder getDecoder()
      Description copied from class: ArrayDataFile
      Returns the conversion from the binary representation of arrays in file to Java arrays. Subclass implementeations can use this to access the required conversion when writing data to file.
      Overrides:
      getDecoder in class ArrayDataFile
      Returns:
      the conversion from the binary representation of arrays in the file to Java arrays
      See Also:
    • isAtStart

      public boolean isAtStart()
      Description copied from interface: FitsOutput
      Checks whether we are currently at the start of this output file or stream.
      Specified by:
      isAtStart in interface FitsOutput
      Returns:
      true if we are currently at the start of stream (where a primary HDU is to be written), or false if we are further along, where HDUs should be written as extensions.
      See Also:
    • readUnsignedByte

      public final int readUnsignedByte() throws IOException
      Specified by:
      readUnsignedByte in interface DataInput
      Throws:
      IOException
    • readByte

      public final byte readByte() throws IOException
      Specified by:
      readByte in interface DataInput
      Throws:
      IOException
    • readBoolean

      public boolean readBoolean() throws IOException
      Specified by:
      readBoolean in interface DataInput
      Throws:
      IOException
    • readChar

      public char readChar() throws IOException
      Specified by:
      readChar in interface DataInput
      Throws:
      IOException
    • readUnsignedShort

      public final int readUnsignedShort() throws IOException
      Specified by:
      readUnsignedShort in interface DataInput
      Throws:
      IOException
    • readShort

      public final short readShort() throws IOException
      Specified by:
      readShort in interface DataInput
      Throws:
      IOException
    • readInt

      public final int readInt() throws IOException
      Specified by:
      readInt in interface DataInput
      Throws:
      IOException
    • readLong

      public final long readLong() throws IOException
      Specified by:
      readLong in interface DataInput
      Throws:
      IOException
    • readFloat

      public final float readFloat() throws IOException
      Specified by:
      readFloat in interface DataInput
      Throws:
      IOException
    • readDouble

      public final double readDouble() throws IOException
      Specified by:
      readDouble in interface DataInput
      Throws:
      IOException
    • readLine

      public String readLine() throws IOException
      Specified by:
      readLine in interface DataInput
      Throws:
      IOException
    • read

      public int read(boolean[] b, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of boolean's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      b - array of boolean's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(Boolean[] buf, int offset, int size) throws IOException
      Description copied from interface: ArrayDataInput
      Reads into an array of booleans, possibly including legal null values. The method has a default implementation, calls DataInput.readBoolean() element by element. Classes that implement this interface might want to replace that with a more efficient block read implementation and/or to add the desired translation for null values.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      buf - array of boolean's.
      offset - start index in the array
      size - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(char[] c, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of char's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      c - array of char's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(short[] s, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of short's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      s - array of short's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(int[] i, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of int's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      i - array of int's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(long[] l, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of long's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      l - array of long's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(float[] f, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of float's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      f - array of float's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • read

      public int read(double[] d, int start, int length) throws IOException
      Description copied from interface: ArrayDataInput
      Read a segment of an array of double's.
      Specified by:
      read in interface ArrayDataInput
      Parameters:
      d - array of double's.
      start - start index in the array
      length - number of array elements to read
      Returns:
      number of bytes read, or -1 if at the end of file/stream
      Throws:
      EOFException - if already at the end of file.
      IOException - if one of the underlying read operations failed
    • readArray

      @Deprecated public final int readArray(Object o) throws IOException
      Deprecated.
      Specified by:
      readArray in interface ArrayDataInput
      Parameters:
      o - a Java array object, including heterogeneous arrays of arrays. If null, nothing will be read from the output.
      Returns:
      the number of bytes read from the input.
      Throws:
      EOFException - if already at the end of file.
      IOException - if there was an IO error, other than the end-of-file, while reading from the input
    • markSupported

      public boolean markSupported()
      Description copied from interface: ArrayDataInput
      See the general contract of the markSupported method of InputStream.
      Specified by:
      markSupported in interface ArrayDataInput
      Returns:
      true if this stream instance supports the mark and reset methods; false otherwise.
    • mark

      public void mark(int readlimit) throws IOException
      Description copied from interface: ArrayDataInput
      See the general contract of the mark method of InputStream.
      Specified by:
      mark in interface ArrayDataInput
      Parameters:
      readlimit - the maximum limit of bytes that can be read before the mark position becomes invalid.
      Throws:
      IOException - if the operation failed
      See Also:
    • reset

      public void reset() throws IOException
      Description copied from interface: ArrayDataInput
      See the general contract of the reset method of InputStream.

      If markpos is -1 (no mark has been set or the mark has been invalidated), an IOException is thrown. Otherwise, pos is set equal to markpos.

      Specified by:
      reset in interface ArrayDataInput
      Throws:
      IOException - if this stream has not been marked or, if the mark has been invalidated, or the stream has been closed by invoking its FitsIO.close() method, or an I/O error occurs.
      See Also:
    • skipBytes

      public int skipBytes(int toSkip) throws IOException
      Specified by:
      skipBytes in interface DataInput
      Throws:
      IOException
    • skipAllBytes

      public void skipAllBytes(long toSkip) throws EOFException, IOException
      Description copied from interface: ArrayDataInput
      Skips a number of bytes from the input. This differs from the ArrayDataInput.skip(long) method in that it will throw an EOF if the skip cannot be fully accomplished as requested...
      Specified by:
      skipAllBytes in interface ArrayDataInput
      Parameters:
      toSkip - the number of bytes to skip forward. Subclass implementations may support negative valued arguments for a backward skip also.
      Throws:
      EOFException - if the end (or beginning) of the stream was reached before skipping the required number of bytes. This does not happen typically with forward skips on random access files, where positioning beyond the EOF is generally allowed for writing.
      IOException - if there was an underlying IO failure.
      See Also:
    • writeByte

      public final void writeByte(int v) throws IOException
      Specified by:
      writeByte in interface DataOutput
      Throws:
      IOException
    • writeBoolean

      public void writeBoolean(boolean v) throws IOException
      Specified by:
      writeBoolean in interface DataOutput
      Throws:
      IOException
    • writeChar

      public void writeChar(int v) throws IOException
      Specified by:
      writeChar in interface DataOutput
      Throws:
      IOException
    • writeShort

      public final void writeShort(int v) throws IOException
      Specified by:
      writeShort in interface DataOutput
      Throws:
      IOException
    • writeInt

      public final void writeInt(int v) throws IOException
      Specified by:
      writeInt in interface DataOutput
      Throws:
      IOException
    • writeLong

      public final void writeLong(long v) throws IOException
      Specified by:
      writeLong in interface DataOutput
      Throws:
      IOException
    • writeFloat

      public final void writeFloat(float v) throws IOException
      Specified by:
      writeFloat in interface DataOutput
      Throws:
      IOException
    • writeDouble

      public final void writeDouble(double v) throws IOException
      Specified by:
      writeDouble in interface DataOutput
      Throws:
      IOException
    • writeBytes

      public final void writeBytes(String s) throws IOException
      Specified by:
      writeBytes in interface DataOutput
      Throws:
      IOException
    • writeChars

      public final void writeChars(String s) throws IOException
      Specified by:
      writeChars in interface DataOutput
      Throws:
      IOException
    • write

      public void write(boolean[] b, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of boolean's.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      b - array of boolean's.
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(Boolean[] buf, int offset, int size) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of booleans, possibly including legal null values. The method has a default implementation, which calls DataOutput.writeBoolean(boolean) element by element. Classes that implement this interface might want to replace that with a more efficient block read implementation/
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      buf - array of booleans.
      offset - start index in the array
      size - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(char[] c, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of char's.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      c - array of char's.
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(short[] s, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of shorts.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      s - the value to write
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(int[] i, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of int's.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      i - array of int's
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(long[] l, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of longs.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      l - array of longs
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(float[] f, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of float's.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      f - array of float's.
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(double[] d, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of double's.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      d - array of double's.
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • write

      public void write(String[] s, int start, int length) throws IOException
      Description copied from interface: ArrayDataOutput
      Write a segment of an array of Strings. Equivalent to calling writeBytes for the selected elements.
      Specified by:
      write in interface ArrayDataOutput
      Parameters:
      s - the array to write
      start - start index in the array
      length - number of array elements to write
      Throws:
      IOException - if one of the underlying write operations failed
    • seek

      public final void seek(long newPos) throws IOException
      Sets a new position in the file for subsequent reading or writing.
      Parameters:
      newPos - the new byte offset from the beginning of the file. It may be beyond the current end of the file, for example for writing more data after some 'gap'.
      Throws:
      IOException - if the position is negative or cannot be set.
    • getChannel

      public final FileChannel getChannel()
      Get the channel associated with this file. Note that this returns the channel of the associated RandomAccessFile. Note that since the BufferedFile buffers the I/O's to the underlying file, the offset of the channel may be different from the offset of the BufferedFile. This is different for a RandomAccessFile where the offsets are guaranteed to be the same.
      Returns:
      the file channel
    • getFD

      public final FileDescriptor getFD() throws IOException
      Get the file descriptor associated with this stream. Note that this returns the file descriptor of the associated RandomAccessFile.
      Returns:
      the file descriptor
      Throws:
      IOException - if the descriptor could not be accessed.
    • getFilePointer

      public final long getFilePointer()
      Gets the current read/write position in the file.
      Returns:
      the current byte offset from the beginning of the file.
    • hasAvailable

      public final boolean hasAvailable(int need) throws IOException
      Checks if there are the required number of bytes available to read from this file.
      Parameters:
      need - the number of bytes we need.
      Returns:
      true if the needed number of bytes can be read from the file or else false.
      Throws:
      IOException - if there was an IO error accessing the file.
    • length

      public final long length() throws IOException
      Returns the current length of the file.
      Returns:
      the current length of the file.
      Throws:
      IOException - if the operation failed
    • setLength

      public void setLength(long newLength) throws IOException
      Sets the length of the file. This method calls the method of the same name in RandomAccessFileIO.
      Parameters:
      newLength - The number of bytes at which the file is set.
      Throws:
      IOException - if the resizing of the underlying stream fails
    • close

      public void close() throws IOException
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException
    • flush

      public void flush() throws IOException
      Specified by:
      flush in interface Flushable
      Throws:
      IOException
    • write

      public final void write(int b) throws IOException
      Description copied from interface: OutputWriter
      Writes a byte. See the general contract of DataOutputStream.write(int).
      Specified by:
      write in interface OutputWriter
      Parameters:
      b - the (unsigned) byte value to write.
      Throws:
      IOException - if there was an underlying IO error
      See Also:
    • read

      public final int read() throws IOException
      Description copied from interface: InputReader
      Reads a byte. See the general contract of FilterInputStream.read().
      Specified by:
      read in interface InputReader
      Returns:
      the (unsigned) byte value or -1 if there is nothing left to read.
      Throws:
      IOException - if there was an underlying IO error
      See Also:
    • write

      public final void write(byte[] b, int from, int len) throws IOException
      Description copied from interface: OutputWriter
      Writes up to the specified number of bytes from a buffer to the stream. See the general contract of DataOutputStream.write(byte[], int, int).
      Specified by:
      write in interface OutputWriter
      Parameters:
      b - the buffer
      from - the starting buffer index
      len - the number of bytes to write.
      Throws:
      IOException - if there was an underlying IO error
      See Also:
    • read

      public final int read(byte[] b, int from, int len) throws IOException
      Description copied from interface: InputReader
      Reads up to the specified number of bytes into a buffer. See the general contract of DataInputStream.read(byte[], int, int).
      Specified by:
      read in interface InputReader
      Parameters:
      b - the buffer
      from - the starting buffer index
      len - the number of bytes to read.
      Returns:
      the number of bytes actually read, or -1 if there is nothing left to read.
      Throws:
      IOException - if there was an underlying IO error
      See Also:
    • readFully

      public final void readFully(byte[] b) throws EOFException, IOException
      Reads bytes to completely fill the supplied buffer. If not enough bytes are avaialable in the file to fully fill the buffer, an EOFException will be thrown.
      Parameters:
      b - the buffer
      Throws:
      EOFException - if already at the end of file.
      IOException - if there was an IO error before the buffer could be fully populated.
    • readFully

      public void readFully(byte[] b, int off, int len) throws EOFException, IOException
      Reads bytes to fill the supplied buffer with the requested number of bytes from the given starting buffer index. If not enough bytes are avaialable in the file to deliver the reqauested number of bytes the buffer, an EOFException will be thrown.
      Parameters:
      b - the buffer
      off - the buffer index at which to start reading data
      len - the total number of bytes to read.
      Throws:
      EOFException - if already at the end of file.
      IOException - if there was an IO error before the requested number of bytes could all be read.
    • readUTF

      public final String readUTF() throws IOException
      Returns:
      a string
      Throws:
      IOException - if there was an IO error while reading from the file.
    • writeUTF

      public final void writeUTF(String s) throws IOException
      Parameters:
      s - a string
      Throws:
      IOException - if there was an IO error while writing to the file.
    • skip

      public final long skip(long n) throws IOException
      Moves the file pointer by a number of bytes from its current position.
      Parameters:
      n - the number of byter to move. Negative values are allowed and result in moving the pointer backward.
      Returns:
      the actual number of bytes that the pointer moved, which may be fewer than requested if the file boundary was reached.
      Throws:
      IOException - if there was an IO error.
    • read

      public final int read(byte[] b) throws IOException
      Read as many bytes into a byte array as possible. The number of bytes read may be fewer than the size of the array, for example because the end-of-file is reached during the read.
      Parameters:
      b - the byte buffer to fill with data from the file.
      Returns:
      the number of bytes actually read.
      Throws:
      IOException - if there was an IO error while reading, other than the end-of-file.
    • write

      public final void write(byte[] b) throws IOException
      Writes the contents of a byte array into the file.
      Parameters:
      b - the byte buffer to write into the file.
      Throws:
      IOException - if there was an IO error while writing to the file...