otis 2003/03/01 09:38:24 Modified: src/java/org/apache/lucene/store FSDirectory.java Log: - Added a manual renaming of files in case the java.io.File's renameTo(File) call fails. It has been reported that this happens on Windows JVMs. Contributed by: Matt Tucker Revision Changes Path 1.14 +52 -6 jakarta-lucene/src/java/org/apache/lucene/store/FSDirectory.java Index: FSDirectory.java =================================================================== RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/store/FSDirectory.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- FSDirectory.java 29 Jan 2003 17:18:55 -0000 1.13 +++ FSDirectory.java 1 Mar 2003 17:38:24 -0000 1.14 @@ -3,8 +3,8 @@ /* ==================================================================== * The Apache Software License, Version 1.1 * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. + * Copyright (c) 2001, 2002, 2003 The Apache Software Foundation. All + * rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,6 +57,8 @@ import java.io.IOException; import java.io.File; import java.io.RandomAccessFile; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.util.Hashtable; import org.apache.lucene.util.Constants; @@ -69,19 +71,22 @@ * @see Directory * @author Doug Cutting */ - public final class FSDirectory extends Directory { /** This cache of directories ensures that there is a unique Directory * instance per path, so that synchronization on the Directory can be used to * synchronize access between readers and writers. * * This should be a WeakHashMap, so that entries can be GC'd, but that would - * require Java 1.2. Instead we use refcounts... */ + * require Java 1.2. Instead we use refcounts... + */ private static final Hashtable DIRECTORIES = new Hashtable(); private static final boolean DISABLE_LOCKS = Boolean.getBoolean("disableLuceneLocks") || Constants.JAVA_1_1; + /** A buffer optionally used in renameTo method */ + private byte[] buffer = null; + /** Returns the directory instance for the named location. * * <p>Directories are cached, so that, for a given canonical path, the same @@ -207,8 +212,49 @@ if (!nu.delete()) throw new IOException("couldn't delete " + to); - if (!old.renameTo(nu)) - throw new IOException("couldn't rename " + from + " to " + to); + // Rename the old file to the new one. Unfortunately, the renameTo() + // method does not work reliably under some JVMs. Therefore, if the + // rename fails, we manually rename by copying the old file to the new one + if (!old.renameTo(nu)) { + java.io.InputStream in = null; + java.io.OutputStream out = null; + try { + in = new FileInputStream(old); + out = new FileOutputStream(nu); + // see if the buffer needs to be initialized. Initialization is + // only done on-demand since many VM's will never run into the renameTo + // bug and hence shouldn't waste 1K of mem for no reason. + if (buffer == null) { + buffer = new byte[1024]; + } + int len; + while ((len = in.read(buffer)) >= 0) { + out.write(buffer, 0, len); + } + + // delete the old file. + old.delete(); + } + catch (IOException ioe) { + throw new IOException("couldn't rename " + from + " to " + to); + } + finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // what can we do? + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + // what can we do? + } + } + } + } } /** Creates a new, empty file in the directory with the given name.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]