View Javadoc

    1   /***
    2    *
    3    * Copyright 2004 Protique Ltd
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18
    19  package org.codehaus.activemq.message.util;
    20  import java.io.File;
    21  import java.io.IOException;
    22  import java.io.RandomAccessFile;
    23
    24  /***
    25   * Simply writes/reads data from a RandomAccessFile
    26   *
    27   * @version $Revision: 1.1 $
    28   */
    29  class FileDataBlock {
    30      private RandomAccessFile dataBlock;
    31      private File file;
    32      private long maxSize;
    33      private long currentOffset;
    34
    35      /***
    36       * Constructor
    37       *
    38       * @param file File handle
    39       * @param maxSize maximum size (in bytes) for the block
    40       * @throws IOException
    41       */
    42      FileDataBlock(File file, long maxSize) throws IOException {
    43          this.file = file;
    44          this.maxSize = maxSize;
    45          this.dataBlock = new RandomAccessFile(file, "rw");
    46          if (dataBlock.length() > 0) {
    47              this.currentOffset = dataBlock.readLong();//read header
    48          }
    49          else {
    50              dataBlock.writeLong(0);
    51              currentOffset = dataBlock.length();
    52          }
    53      }
    54
    55      /***
    56       * close and deletes the block
    57       *
    58       * @throws IOException
    59       */
    60      synchronized void close() throws IOException {
    61          dataBlock.close();
    62          file.delete();
    63      }
    64
    65      /***
    66       * test to if there is enough room in the block to write the data
    67       *
    68       * @param data bytes to be written
    69       * @return true if there is enough space left in the block to write the data
    70       * @throws IOException
    71       */
    72      synchronized boolean isEnoughSpace(byte[] data) throws IOException {
    73          return ((dataBlock.length() + data.length) < maxSize);
    74      }
    75
    76      /***
    77       * Write data to the end of the block
    78       *
    79       * @param data the bytes to write
    80       * @throws IOException
    81       */
    82      synchronized void write(byte[] data) throws IOException {
    83          dataBlock.seek(dataBlock.length());
    84          dataBlock.writeInt(data.length);
    85          dataBlock.write(data);
    86      }
    87
    88      /***
    89       * read next chunk of data
    90       *
    91       * @return next chunk of data or null if no more to read
    92       * @throws IOException
    93       */
    94      synchronized byte[] read() throws IOException {
    95          byte[] result = null;
    96          if (currentOffset > 0 && currentOffset < dataBlock.length()) {
    97              dataBlock.seek(currentOffset);
    98              int length = dataBlock.readInt();
    99              result = new byte[length];
    100             dataBlock.readFully(result);
    101             currentOffset = dataBlock.getFilePointer();
    102             updateHeader(currentOffset);
    103         }
    104         return result;
    105     }
    106
    107     private void updateHeader(long pos) throws IOException {
    108         dataBlock.seek(0);
    109         dataBlock.writeLong(pos);
    110     }
    111 }