001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.util; 018 019import java.io.File; 020import java.io.FileDescriptor; 021import java.io.FileNotFoundException; 022import java.io.IOException; 023import java.io.RandomAccessFile; 024import java.nio.channels.FileChannel; 025 026public class RecoverableRandomAccessFile implements java.io.DataOutput, java.io.DataInput, java.io.Closeable { 027 028 private static final boolean SKIP_METADATA_UPDATE = 029 Boolean.getBoolean("org.apache.activemq.kahaDB.files.skipMetadataUpdate"); 030 031 RandomAccessFile raf; 032 File file; 033 String mode; 034 035 public RecoverableRandomAccessFile(File file, String mode) throws FileNotFoundException { 036 this.file = file; 037 this.mode = mode; 038 raf = new RandomAccessFile(file, mode); 039 } 040 041 public RecoverableRandomAccessFile(String name, String mode) throws FileNotFoundException { 042 this.file = new File(name); 043 this.mode = mode; 044 raf = new RandomAccessFile(file, mode); 045 } 046 047 protected RandomAccessFile getRaf() throws IOException { 048 if (raf == null) { 049 raf = new RandomAccessFile(file, mode); 050 } 051 return raf; 052 } 053 054 protected void handleException() throws IOException { 055 try { 056 if (raf != null) { 057 raf.close(); 058 } 059 } catch (Throwable ignore) { 060 } finally { 061 raf = null; 062 } 063 } 064 065 @Override 066 public void close() throws IOException { 067 if (raf != null) { 068 raf.close(); 069 } 070 } 071 072 @Override 073 public void readFully(byte[] bytes) throws IOException { 074 try { 075 getRaf().readFully(bytes); 076 } catch (IOException ioe) { 077 handleException(); 078 throw ioe; 079 } 080 } 081 082 @Override 083 public void readFully(byte[] bytes, int i, int i2) throws IOException { 084 try { 085 getRaf().readFully(bytes, i, i2); 086 } catch (IOException ioe) { 087 handleException(); 088 throw ioe; 089 } 090 } 091 092 @Override 093 public int skipBytes(int i) throws IOException { 094 try { 095 return getRaf().skipBytes(i); 096 } catch (IOException ioe) { 097 handleException(); 098 throw ioe; 099 } 100 } 101 102 @Override 103 public boolean readBoolean() throws IOException { 104 try { 105 return getRaf().readBoolean(); 106 } catch (IOException ioe) { 107 handleException(); 108 throw ioe; 109 } 110 } 111 112 @Override 113 public byte readByte() throws IOException { 114 try { 115 return getRaf().readByte(); 116 } catch (IOException ioe) { 117 handleException(); 118 throw ioe; 119 } 120 } 121 122 @Override 123 public int readUnsignedByte() throws IOException { 124 try { 125 return getRaf().readUnsignedByte(); 126 } catch (IOException ioe) { 127 handleException(); 128 throw ioe; 129 } 130 } 131 132 @Override 133 public short readShort() throws IOException { 134 try { 135 return getRaf().readShort(); 136 } catch (IOException ioe) { 137 handleException(); 138 throw ioe; 139 } 140 } 141 142 @Override 143 public int readUnsignedShort() throws IOException { 144 try { 145 return getRaf().readUnsignedShort(); 146 } catch (IOException ioe) { 147 handleException(); 148 throw ioe; 149 } 150 } 151 152 @Override 153 public char readChar() throws IOException { 154 try { 155 return getRaf().readChar(); 156 } catch (IOException ioe) { 157 handleException(); 158 throw ioe; 159 } 160 } 161 162 @Override 163 public int readInt() throws IOException { 164 try { 165 return getRaf().readInt(); 166 } catch (IOException ioe) { 167 handleException(); 168 throw ioe; 169 } 170 } 171 172 @Override 173 public long readLong() throws IOException { 174 try { 175 return getRaf().readLong(); 176 } catch (IOException ioe) { 177 handleException(); 178 throw ioe; 179 } 180 } 181 182 @Override 183 public float readFloat() throws IOException { 184 try { 185 return getRaf().readFloat(); 186 } catch (IOException ioe) { 187 handleException(); 188 throw ioe; 189 } 190 } 191 192 @Override 193 public double readDouble() throws IOException { 194 try { 195 return getRaf().readDouble(); 196 } catch (IOException ioe) { 197 handleException(); 198 throw ioe; 199 } 200 } 201 202 @Override 203 public String readLine() throws IOException { 204 try { 205 return getRaf().readLine(); 206 } catch (IOException ioe) { 207 handleException(); 208 throw ioe; 209 } 210 } 211 212 @Override 213 public String readUTF() throws IOException { 214 try { 215 return getRaf().readUTF(); 216 } catch (IOException ioe) { 217 handleException(); 218 throw ioe; 219 } 220 } 221 222 @Override 223 public void write(int i) throws IOException { 224 try { 225 getRaf().write(i); 226 } catch (IOException ioe) { 227 handleException(); 228 throw ioe; 229 } 230 } 231 232 @Override 233 public void write(byte[] bytes) throws IOException { 234 try { 235 getRaf().write(bytes); 236 } catch (IOException ioe) { 237 handleException(); 238 throw ioe; 239 } 240 } 241 242 @Override 243 public void write(byte[] bytes, int i, int i2) throws IOException { 244 try { 245 getRaf().write(bytes, i, i2); 246 } catch (IOException ioe) { 247 handleException(); 248 throw ioe; 249 } 250 } 251 252 @Override 253 public void writeBoolean(boolean b) throws IOException { 254 try { 255 getRaf().writeBoolean(b); 256 } catch (IOException ioe) { 257 handleException(); 258 throw ioe; 259 } 260 } 261 262 @Override 263 public void writeByte(int i) throws IOException { 264 try { 265 getRaf().writeByte(i); 266 } catch (IOException ioe) { 267 handleException(); 268 throw ioe; 269 } 270 } 271 272 @Override 273 public void writeShort(int i) throws IOException { 274 try { 275 getRaf().writeShort(i); 276 } catch (IOException ioe) { 277 handleException(); 278 throw ioe; 279 } 280 } 281 282 @Override 283 public void writeChar(int i) throws IOException { 284 try { 285 getRaf().writeChar(i); 286 } catch (IOException ioe) { 287 handleException(); 288 throw ioe; 289 } 290 } 291 292 @Override 293 public void writeInt(int i) throws IOException { 294 try { 295 getRaf().writeInt(i); 296 } catch (IOException ioe) { 297 handleException(); 298 throw ioe; 299 } 300 } 301 302 @Override 303 public void writeLong(long l) throws IOException { 304 try { 305 getRaf().writeLong(l); 306 } catch (IOException ioe) { 307 handleException(); 308 throw ioe; 309 } 310 } 311 312 @Override 313 public void writeFloat(float v) throws IOException { 314 try { 315 getRaf().writeFloat(v); 316 } catch (IOException ioe) { 317 handleException(); 318 throw ioe; 319 } 320 } 321 322 @Override 323 public void writeDouble(double v) throws IOException { 324 try { 325 getRaf().writeDouble(v); 326 } catch (IOException ioe) { 327 handleException(); 328 throw ioe; 329 } 330 } 331 332 @Override 333 public void writeBytes(String s) throws IOException { 334 try { 335 getRaf().writeBytes(s); 336 } catch (IOException ioe) { 337 handleException(); 338 throw ioe; 339 } 340 } 341 342 @Override 343 public void writeChars(String s) throws IOException { 344 try { 345 getRaf().writeChars(s); 346 } catch (IOException ioe) { 347 handleException(); 348 throw ioe; 349 } 350 } 351 352 @Override 353 public void writeUTF(String s) throws IOException { 354 try { 355 getRaf().writeUTF(s); 356 } catch (IOException ioe) { 357 handleException(); 358 throw ioe; 359 } 360 } 361 362 363 //RAF methods 364 public long length() throws IOException { 365 try { 366 return getRaf().length(); 367 } catch (IOException ioe) { 368 handleException(); 369 throw ioe; 370 } 371 } 372 373 public void setLength(long length) throws IOException { 374 throw new IllegalStateException("File size is pre allocated"); 375 } 376 377 public void seek(long pos) throws IOException { 378 try { 379 getRaf().seek(pos); 380 } catch (IOException ioe) { 381 handleException(); 382 throw ioe; 383 } 384 } 385 386 public FileDescriptor getFD() throws IOException { 387 try { 388 return getRaf().getFD(); 389 } catch (IOException ioe) { 390 handleException(); 391 throw ioe; 392 } 393 } 394 395 public void sync() throws IOException { 396 try { 397 getRaf().getChannel().force(!SKIP_METADATA_UPDATE);; 398 } catch (IOException ioe) { 399 handleException(); 400 throw ioe; 401 } 402 } 403 404 public FileChannel getChannel() throws IOException { 405 try { 406 return getRaf().getChannel(); 407 } catch (IOException ioe) { 408 handleException(); 409 throw ioe; 410 } 411 } 412 413 public int read(byte[] b, int off, int len) throws IOException { 414 try { 415 return getRaf().read(b, off, len); 416 } catch (IOException ioe) { 417 handleException(); 418 throw ioe; 419 } 420 } 421 422 public int read(byte[] b) throws IOException { 423 try { 424 return getRaf().read(b); 425 } catch (IOException ioe) { 426 handleException(); 427 throw ioe; 428 } 429 } 430}