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 final boolean isSkipMetadataUpdate; 035 036 public RecoverableRandomAccessFile(File file, String mode, boolean skipMetadataUpdate) throws FileNotFoundException { 037 this.file = file; 038 this.mode = mode; 039 raf = new RandomAccessFile(file, mode); 040 isSkipMetadataUpdate = skipMetadataUpdate; 041 } 042 043 public RecoverableRandomAccessFile(File file, String mode) throws FileNotFoundException { 044 this(file, mode, SKIP_METADATA_UPDATE); 045 } 046 047 public RecoverableRandomAccessFile(String name, String mode) throws FileNotFoundException { 048 this(new File(name), mode); 049 } 050 051 public RandomAccessFile getRaf() throws IOException { 052 if (raf == null) { 053 raf = new RandomAccessFile(file, mode); 054 } 055 return raf; 056 } 057 058 protected void handleException() throws IOException { 059 try { 060 if (raf != null) { 061 raf.close(); 062 } 063 } catch (Throwable ignore) { 064 } finally { 065 raf = null; 066 } 067 } 068 069 @Override 070 public void close() throws IOException { 071 if (raf != null) { 072 raf.close(); 073 } 074 } 075 076 @Override 077 public void readFully(byte[] bytes) throws IOException { 078 try { 079 getRaf().readFully(bytes); 080 } catch (IOException ioe) { 081 handleException(); 082 throw ioe; 083 } 084 } 085 086 @Override 087 public void readFully(byte[] bytes, int i, int i2) throws IOException { 088 try { 089 getRaf().readFully(bytes, i, i2); 090 } catch (IOException ioe) { 091 handleException(); 092 throw ioe; 093 } 094 } 095 096 @Override 097 public int skipBytes(int i) throws IOException { 098 try { 099 return getRaf().skipBytes(i); 100 } catch (IOException ioe) { 101 handleException(); 102 throw ioe; 103 } 104 } 105 106 @Override 107 public boolean readBoolean() throws IOException { 108 try { 109 return getRaf().readBoolean(); 110 } catch (IOException ioe) { 111 handleException(); 112 throw ioe; 113 } 114 } 115 116 @Override 117 public byte readByte() throws IOException { 118 try { 119 return getRaf().readByte(); 120 } catch (IOException ioe) { 121 handleException(); 122 throw ioe; 123 } 124 } 125 126 @Override 127 public int readUnsignedByte() throws IOException { 128 try { 129 return getRaf().readUnsignedByte(); 130 } catch (IOException ioe) { 131 handleException(); 132 throw ioe; 133 } 134 } 135 136 @Override 137 public short readShort() throws IOException { 138 try { 139 return getRaf().readShort(); 140 } catch (IOException ioe) { 141 handleException(); 142 throw ioe; 143 } 144 } 145 146 @Override 147 public int readUnsignedShort() throws IOException { 148 try { 149 return getRaf().readUnsignedShort(); 150 } catch (IOException ioe) { 151 handleException(); 152 throw ioe; 153 } 154 } 155 156 @Override 157 public char readChar() throws IOException { 158 try { 159 return getRaf().readChar(); 160 } catch (IOException ioe) { 161 handleException(); 162 throw ioe; 163 } 164 } 165 166 @Override 167 public int readInt() throws IOException { 168 try { 169 return getRaf().readInt(); 170 } catch (IOException ioe) { 171 handleException(); 172 throw ioe; 173 } 174 } 175 176 @Override 177 public long readLong() throws IOException { 178 try { 179 return getRaf().readLong(); 180 } catch (IOException ioe) { 181 handleException(); 182 throw ioe; 183 } 184 } 185 186 @Override 187 public float readFloat() throws IOException { 188 try { 189 return getRaf().readFloat(); 190 } catch (IOException ioe) { 191 handleException(); 192 throw ioe; 193 } 194 } 195 196 @Override 197 public double readDouble() throws IOException { 198 try { 199 return getRaf().readDouble(); 200 } catch (IOException ioe) { 201 handleException(); 202 throw ioe; 203 } 204 } 205 206 @Override 207 public String readLine() throws IOException { 208 try { 209 return getRaf().readLine(); 210 } catch (IOException ioe) { 211 handleException(); 212 throw ioe; 213 } 214 } 215 216 @Override 217 public String readUTF() throws IOException { 218 try { 219 return getRaf().readUTF(); 220 } catch (IOException ioe) { 221 handleException(); 222 throw ioe; 223 } 224 } 225 226 @Override 227 public void write(int i) throws IOException { 228 try { 229 getRaf().write(i); 230 } catch (IOException ioe) { 231 handleException(); 232 throw ioe; 233 } 234 } 235 236 @Override 237 public void write(byte[] bytes) throws IOException { 238 try { 239 getRaf().write(bytes); 240 } catch (IOException ioe) { 241 handleException(); 242 throw ioe; 243 } 244 } 245 246 @Override 247 public void write(byte[] bytes, int i, int i2) throws IOException { 248 try { 249 getRaf().write(bytes, i, i2); 250 } catch (IOException ioe) { 251 handleException(); 252 throw ioe; 253 } 254 } 255 256 @Override 257 public void writeBoolean(boolean b) throws IOException { 258 try { 259 getRaf().writeBoolean(b); 260 } catch (IOException ioe) { 261 handleException(); 262 throw ioe; 263 } 264 } 265 266 @Override 267 public void writeByte(int i) throws IOException { 268 try { 269 getRaf().writeByte(i); 270 } catch (IOException ioe) { 271 handleException(); 272 throw ioe; 273 } 274 } 275 276 @Override 277 public void writeShort(int i) throws IOException { 278 try { 279 getRaf().writeShort(i); 280 } catch (IOException ioe) { 281 handleException(); 282 throw ioe; 283 } 284 } 285 286 @Override 287 public void writeChar(int i) throws IOException { 288 try { 289 getRaf().writeChar(i); 290 } catch (IOException ioe) { 291 handleException(); 292 throw ioe; 293 } 294 } 295 296 @Override 297 public void writeInt(int i) throws IOException { 298 try { 299 getRaf().writeInt(i); 300 } catch (IOException ioe) { 301 handleException(); 302 throw ioe; 303 } 304 } 305 306 @Override 307 public void writeLong(long l) throws IOException { 308 try { 309 getRaf().writeLong(l); 310 } catch (IOException ioe) { 311 handleException(); 312 throw ioe; 313 } 314 } 315 316 @Override 317 public void writeFloat(float v) throws IOException { 318 try { 319 getRaf().writeFloat(v); 320 } catch (IOException ioe) { 321 handleException(); 322 throw ioe; 323 } 324 } 325 326 @Override 327 public void writeDouble(double v) throws IOException { 328 try { 329 getRaf().writeDouble(v); 330 } catch (IOException ioe) { 331 handleException(); 332 throw ioe; 333 } 334 } 335 336 @Override 337 public void writeBytes(String s) throws IOException { 338 try { 339 getRaf().writeBytes(s); 340 } catch (IOException ioe) { 341 handleException(); 342 throw ioe; 343 } 344 } 345 346 @Override 347 public void writeChars(String s) throws IOException { 348 try { 349 getRaf().writeChars(s); 350 } catch (IOException ioe) { 351 handleException(); 352 throw ioe; 353 } 354 } 355 356 @Override 357 public void writeUTF(String s) throws IOException { 358 try { 359 getRaf().writeUTF(s); 360 } catch (IOException ioe) { 361 handleException(); 362 throw ioe; 363 } 364 } 365 366 367 //RAF methods 368 public long length() throws IOException { 369 try { 370 return getRaf().length(); 371 } catch (IOException ioe) { 372 handleException(); 373 throw ioe; 374 } 375 } 376 377 public void setLength(long length) throws IOException { 378 throw new IllegalStateException("File size is pre allocated"); 379 } 380 381 public void seek(long pos) throws IOException { 382 try { 383 getRaf().seek(pos); 384 } catch (IOException ioe) { 385 handleException(); 386 throw ioe; 387 } 388 } 389 390 public FileDescriptor getFD() throws IOException { 391 try { 392 return getRaf().getFD(); 393 } catch (IOException ioe) { 394 handleException(); 395 throw ioe; 396 } 397 } 398 399 public void sync() throws IOException { 400 try { 401 getRaf().getChannel().force(!isSkipMetadataUpdate);; 402 } catch (IOException ioe) { 403 handleException(); 404 throw ioe; 405 } 406 } 407 408 public FileChannel getChannel() throws IOException { 409 try { 410 return getRaf().getChannel(); 411 } catch (IOException ioe) { 412 handleException(); 413 throw ioe; 414 } 415 } 416 417 public int read(byte[] b, int off, int len) throws IOException { 418 try { 419 return getRaf().read(b, off, len); 420 } catch (IOException ioe) { 421 handleException(); 422 throw ioe; 423 } 424 } 425 426 public int read(byte[] b) throws IOException { 427 try { 428 return getRaf().read(b); 429 } catch (IOException ioe) { 430 handleException(); 431 throw ioe; 432 } 433 } 434}