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 }