1 25 26 package org.jrobin.core; 27 28 import java.io.IOException ; 29 import java.io.RandomAccessFile ; 30 import java.io.File ; 31 import java.nio.channels.FileChannel ; 32 import java.nio.channels.FileLock ; 33 import java.util.HashSet ; 34 35 41 public class RrdFileBackend extends RrdBackend { 42 static final long LOCK_DELAY = 100; 44 private static HashSet openFiles = new HashSet (); 45 46 protected RandomAccessFile file; 47 protected FileChannel channel; 48 protected FileLock fileLock; 49 50 protected RrdFileBackend(String path, boolean readOnly, int lockMode) throws IOException { 51 super(path); 52 file = new RandomAccessFile (path, readOnly? "r": "rw"); 53 channel = file.getChannel(); 54 if(!readOnly) { 55 lockFile(lockMode); 56 registerWriter(path); 58 } 59 } 60 61 private static synchronized void registerWriter(String path) throws IOException { 62 String canonicalPath = getCanonicalPath(path); 63 if(openFiles.contains(canonicalPath)) { 64 throw new IOException ("File \"" + path + "\" already open for R/W access. " + 65 "You cannot open the same file for R/W access twice"); 66 } 67 else { 68 openFiles.add(canonicalPath); 69 } 70 } 71 72 private void lockFile(int lockMode) throws IOException { 73 if(lockMode == RrdDb.WAIT_IF_LOCKED || lockMode == RrdDb.EXCEPTION_IF_LOCKED) { 74 do { 75 fileLock = channel.tryLock(); 76 if(fileLock == null) { 77 if(lockMode == RrdDb.WAIT_IF_LOCKED) { 79 try { 81 Thread.sleep(LOCK_DELAY); 82 } catch (InterruptedException e) { 83 } 85 } 86 else { 87 throw new IOException ("Access denied. " + 88 "File [" + getPath() + "] already locked"); 89 } 90 } 91 } while(fileLock == null); 92 } 93 } 94 95 99 public void close() throws IOException { 100 super.close(); unregisterWriter(getPath()); 102 unlockFile(); 103 channel.close(); 104 file.close(); 105 } 106 107 private static synchronized void unregisterWriter(String path) throws IOException { 108 String canonicalPath = getCanonicalPath(path); 109 openFiles.remove(canonicalPath); 110 } 111 112 private void unlockFile() throws IOException { 113 if(fileLock != null) { 114 fileLock.release(); 115 fileLock = null; 116 } 117 } 118 119 123 protected void finalize() throws IOException { 124 close(); 125 } 126 127 133 public static String getCanonicalPath(String path) throws IOException { 134 return new File (path).getCanonicalPath(); 135 } 136 137 142 public String getCanonicalPath() throws IOException { 143 return RrdFileBackend.getCanonicalPath(getPath()); 144 } 145 146 152 protected void write(long offset, byte[] b) throws IOException { 153 file.seek(offset); 154 file.write(b); 155 } 156 157 163 protected void read(long offset, byte[] b) throws IOException { 164 file.seek(offset); 165 if(file.read(b) != b.length) { 166 throw new IOException ("Not enough bytes available in file " + getPath()); 167 } 168 } 169 170 175 public long getLength() throws IOException { 176 return file.length(); 177 } 178 179 185 protected void setLength(long length) throws IOException { 186 file.setLength(length); 187 } 188 } 189 | Popular Tags |