1 5 package org.h2.util; 6 7 import java.io.File ; 8 import java.io.FileInputStream ; 9 import java.io.FileOutputStream ; 10 import java.io.FileWriter ; 11 import java.io.IOException ; 12 import java.io.RandomAccessFile ; 13 import java.sql.SQLException ; 14 import java.util.HashMap ; 15 import java.util.Properties ; 16 17 import org.h2.engine.Constants; 18 import org.h2.message.Message; 19 import org.h2.message.TraceSystem; 20 21 22 25 26 public class FileUtils { 27 28 public static final HashMap memoryFiles = new HashMap (); 29 private static final String MEMORY_PREFIX = "inmemory:"; 30 private static final String MEMORY_PREFIX_2 = "mem:"; 31 private static final boolean isCaseInsensitiveFileSystem = (File.separatorChar == '\\'); 33 34 36 public static RandomAccessFile openRandomAccessFile(String fileName, String mode) throws IOException { 37 try { 38 return new RandomAccessFile (fileName, mode); 39 } catch(IOException e) { 40 freeMemoryAndFinalize(); 41 return new RandomAccessFile (fileName, mode); 42 } 43 } 44 45 public static void setLength(RandomAccessFile file, long newLength) throws IOException { 46 try { 47 file.setLength(newLength); 48 } catch(IOException e) { 49 long length = file.length(); 50 if(newLength < length) { 51 throw e; 52 } else { 53 long pos = file.getFilePointer(); 54 file.seek(length); 55 long remaining = newLength - length; 56 int maxSize = 1024 * 1024; 57 int block = (int)Math.min(remaining, maxSize); 58 byte[] buffer = new byte[block]; 59 while(remaining > 0) { 60 int write = (int) Math.min(remaining, maxSize); 61 file.write(buffer, 0, write); 62 remaining -= write; 63 } 64 file.seek(pos); 65 } 66 } 67 } 68 69 public static FileWriter openFileWriter(String fileName, boolean append) throws IOException { 70 try { 71 return new FileWriter (fileName, append); 72 } catch(IOException e) { 73 freeMemoryAndFinalize(); 74 return new FileWriter (fileName, append); 75 } 76 } 77 78 public static boolean fileStartsWith(String fileName, String prefix) { 79 if(isCaseInsensitiveFileSystem) { 80 fileName = StringUtils.toUpperEnglish(fileName); 81 prefix = StringUtils.toUpperEnglish(prefix); 82 } 83 return fileName.startsWith(prefix); 84 } 85 86 public static FileOutputStream openFileOutputStream(File file) throws IOException , SQLException { 87 try { 88 FileUtils.createDirs(file.getAbsolutePath()); 89 return new FileOutputStream (file); 90 } catch(IOException e) { 91 freeMemoryAndFinalize(); 92 return new FileOutputStream (file); 93 } 94 } 95 96 private static void freeMemoryAndFinalize() { 97 long mem = Runtime.getRuntime().freeMemory(); 98 for(int i=0; i<16; i++) { 99 System.gc(); 100 long now = Runtime.getRuntime().freeMemory(); 101 Runtime.getRuntime().runFinalization(); 102 if(now == mem) { 103 break; 104 } 105 mem = now; 106 } 107 } 108 109 public static void rename(String oldName, String newName) throws SQLException { 110 if(isInMemory(oldName)) { 111 MemoryFile f = getMemoryFile(oldName); 112 f.setName(newName); 113 memoryFiles.put(newName, f); 114 return; 115 } 116 File oldFile = new File (oldName); 117 File newFile = new File (newName); 118 if(oldFile.getName().equals(newFile.getName())) { 119 throw Message.getInternalError("rename file old=new"); 120 } 121 if(!oldFile.exists()) { 122 throw Message.getSQLException(Message.FILE_RENAME_FAILED_2, new String []{oldName, newName}, null); 123 } 124 if(newFile.exists()) { 125 throw Message.getSQLException(Message.FILE_RENAME_FAILED_2, new String []{oldName, newName}, null); 126 } 127 for(int i=0; i<16; i++) { 128 boolean ok = oldFile.renameTo(newFile); 129 if(ok) { 130 return; 131 } 132 wait(i); 133 } 134 throw Message.getSQLException(Message.FILE_RENAME_FAILED_2, new String []{oldName, newName}, null); 135 } 136 137 public static synchronized Properties loadProperties(File file) throws IOException { 138 Properties prop = new Properties (); 139 if(file.exists()) { 140 FileInputStream in = new FileInputStream (file); 141 try { 142 prop.load(in); 143 } finally { 144 in.close(); 145 } 146 } 147 return prop; 148 } 149 150 public static boolean getBooleanProperty(Properties prop, String key, boolean def) { 151 String value = prop.getProperty(key, ""+def); 152 try { 153 return Boolean.valueOf(value).booleanValue(); 154 } catch(Exception e) { 155 TraceSystem.traceThrowable(e); 156 return def; 157 } 158 } 159 160 public static int getIntProperty(Properties prop, String key, int def) { 161 String value = prop.getProperty(key, ""+def); 162 try { 163 return MathUtils.decodeInt(value); 164 } catch(Exception e) { 165 TraceSystem.traceThrowable(e); 166 return def; 167 } 168 } 169 170 public static void createDirs(String fileName) throws SQLException { 171 File f = new File (fileName); 172 if(!f.exists()) { 173 String parent = f.getParent(); 174 if(parent == null) { 175 return; 176 } 177 File dir = new File (parent); 178 for(int i=0; i<16; i++) { 179 if(dir.exists() || dir.mkdirs()) { 180 return; 181 } 182 wait(i); 183 } 184 throw Message.getSQLException(Message.FILE_CREATION_FAILED_1, parent); 185 } 186 } 187 188 public static boolean createNewFile(String fileName) throws SQLException { 189 if(isInMemory(fileName)) { 190 if(exists(fileName)) { 191 return false; 192 } 193 getMemoryFile(fileName); 195 return true; 196 } 197 File file = new File (fileName); 198 for(int i=0; i<8; i++) { 199 try { 200 return file.createNewFile(); 201 } catch (IOException e) { 202 wait(i); 204 } 205 } 206 return false; 208 } 211 212 public static void delete(String fileName) throws SQLException { 213 if(isInMemory(fileName)) { 214 memoryFiles.remove(fileName); 215 return; 216 } 217 File file = new File (fileName); 218 if(file.exists()) { 219 for(int i=0; i<16; i++) { 220 boolean ok = file.delete(); 221 if(ok) { 222 return; 223 } 224 wait(i); 225 } 226 throw Message.getSQLException(Message.FILE_DELETE_FAILED_1, fileName); 227 } 228 } 229 230 private static void wait(int i) { 231 if(i > 8) { 232 System.gc(); 233 } 234 try { 235 long sleep = (long)i * (long)i; 237 Thread.sleep(sleep); 238 } catch (InterruptedException e) { 239 } 241 } 242 243 public static String getFileName(String name) throws SQLException { 244 String separator = System.getProperty("file.separator"); 245 String path = getParent(name) + separator; 246 String fullFileName = normalize(name); 247 if(!fullFileName.startsWith(path)) { 248 throw Message.getInternalError("file utils error: " + fullFileName+" does not start with "+path); 249 } 250 String fileName = fullFileName.substring(path.length()); 251 return fileName; 252 } 253 254 public static File getFileInUserHome(String filename) { 255 String userDir = System.getProperty("user.home"); 256 if(userDir == null) { 257 return new File (filename); 258 } 259 return new File (userDir, filename); 260 } 261 262 public static String normalize(String fileName) throws SQLException { 263 if(isInMemory(fileName)) { 264 return fileName; 265 } 266 File f = new File (fileName); 267 try { 268 return f.getCanonicalPath(); 269 } catch (IOException e) { 270 throw Message.convert(e); 271 } 272 } 273 274 public static void tryDelete(String fileName) { 275 if(isInMemory(fileName)) { 276 memoryFiles.remove(fileName); 277 return; 278 } 279 new File (fileName).delete(); 280 } 281 282 public static boolean isReadOnly(String fileName) { 283 if(isInMemory(fileName)) { 284 return false; 285 } 286 File f = new File (fileName); 287 return f.exists() && !f.canWrite(); 288 } 289 290 public static boolean exists(String fileName) { 291 if(isInMemory(fileName)) { 292 return memoryFiles.get(fileName) != null; 293 } 294 return new File (fileName).exists(); 295 } 296 297 public static MemoryFile getMemoryFile(String fileName) { 298 MemoryFile m = (MemoryFile)memoryFiles.get(fileName); 299 if(m == null) { 300 m = new MemoryFile(fileName); 301 memoryFiles.put(fileName, m); 302 } 303 return m; 304 } 305 306 public static long length(String fileName) { 307 if(isInMemory(fileName)) { 308 return getMemoryFile(fileName).length(); 309 } 310 return new File (fileName).length(); 311 } 312 313 public static boolean isInMemory(String fileName) { 314 return fileName.startsWith(MEMORY_PREFIX) || fileName.startsWith(MEMORY_PREFIX_2); 315 } 316 317 public static String createTempFile(String name, String suffix, boolean deleteOnExit) throws IOException , SQLException { 318 name += "."; 319 if(isInMemory(name)) { 320 for(int i=0;; i++) { 321 String n = name + i + suffix; 322 if(!exists(n)) { 323 getMemoryFile(n); 325 return n; 326 } 327 } 328 } 329 String prefix = new File (name).getName(); 330 File dir = new File (name).getAbsoluteFile().getParentFile(); 331 dir.mkdirs(); 332 File f = File.createTempFile(prefix, suffix, dir); 333 if(deleteOnExit) { 334 f.deleteOnExit(); 335 } 336 return f.getCanonicalPath(); 337 } 338 339 public static String getParent(String fileName) { 340 if(isInMemory(fileName)) { 341 return MEMORY_PREFIX; 342 } 343 return new File (fileName).getParent(); 344 } 345 346 public static String [] listFiles(String path) throws SQLException { 347 if(isInMemory(path)) { 348 String [] list = new String [memoryFiles.size()]; 349 MemoryFile[] l = new MemoryFile[memoryFiles.size()]; 350 memoryFiles.values().toArray(l); 351 for(int i=0; i<list.length; i++) { 352 list[i] = l[i].getName(); 353 } 354 return list; 355 } 356 try { 357 File [] files = new File (path).listFiles(); 358 if(files == null) { 359 return new String [0]; 360 } 361 String [] list = new String [files.length]; 362 for(int i=0; i<files.length; i++) { 363 list[i] = files[i].getCanonicalPath(); 364 } 365 return list; 366 } catch (IOException e) { 367 throw Message.convert(e); 368 } 369 } 370 371 public static boolean isDirectory(String fileName) { 372 if(isInMemory(fileName)) { 373 return false; 375 } 376 return new File (fileName).isDirectory(); 377 } 378 379 public static void copy(String original, String copy) throws SQLException { 380 FileOutputStream out = null; 381 FileInputStream in = null; 382 try { 383 out = openFileOutputStream(new File (copy)); 384 in = new FileInputStream (new File (original)); 385 byte[] buffer = new byte[Constants.IO_BUFFER_SIZE]; 386 while(true) { 387 int len = in.read(buffer); 388 if(len < 0) { 389 break; 390 } 391 out.write(buffer, 0, len); 392 } 393 } catch(IOException e) { 394 IOUtils.closeSilently(in); 395 IOUtils.closeSilently(out); 396 throw Message.convert(e); 397 } 398 } 399 400 public static void deleteRecursive(String fileName) throws SQLException { 401 if(FileUtils.isDirectory(fileName)) { 402 String [] list = FileUtils.listFiles(fileName); 403 for(int i=0; list != null && i<list.length; i++) { 404 deleteRecursive(list[i]); 405 } 406 } 407 FileUtils.delete(fileName); 408 } 409 410 } 411 | Popular Tags |