📄 fsdirectory.java
字号:
package org.apache.lucene.store;/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Hashtable;import org.apache.lucene.index.IndexFileNameFilter;// Used only for WRITE_LOCK_NAME in deprecated create=true case:import org.apache.lucene.index.IndexWriter;/** * Straightforward implementation of {@link Directory} as a directory of files. * Locking implementation is by default the {@link SimpleFSLockFactory}, but * can be changed either by passing in a {@link LockFactory} instance to * <code>getDirectory</code>, or specifying the LockFactory class by setting * <code>org.apache.lucene.store.FSDirectoryLockFactoryClass</code> Java system * property, or by calling {@link #setLockFactory} after creating * the Directory. * <p>Directories are cached, so that, for a given canonical * path, the same FSDirectory instance will always be * returned by <code>getDirectory</code>. This permits * synchronization on directories.</p> * * @see Directory * @author Doug Cutting */public 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. We use * refcounts to ensure when the last use of an FSDirectory * instance for a given canonical path is closed, we remove the * instance from the cache. See LUCENE-776 * for some relevant discussion. */ private static final Hashtable DIRECTORIES = new Hashtable(); private static boolean disableLocks = false; // TODO: should this move up to the Directory base class? Also: should we // make a per-instance (in addition to the static "default") version? /** * Set whether Lucene's use of lock files is disabled. By default, * lock files are enabled. They should only be disabled if the index * is on a read-only medium like a CD-ROM. */ public static void setDisableLocks(boolean doDisableLocks) { FSDirectory.disableLocks = doDisableLocks; } /** * Returns whether Lucene's use of lock files is disabled. * @return true if locks are disabled, false if locks are enabled. */ public static boolean getDisableLocks() { return FSDirectory.disableLocks; } /** * Directory specified by <code>org.apache.lucene.lockDir</code> * or <code>java.io.tmpdir</code> system property. * @deprecated As of 2.1, <code>LOCK_DIR</code> is unused * because the write.lock is now stored by default in the * index directory. If you really want to store locks * elsewhere you can create your own {@link * SimpleFSLockFactory} (or {@link NativeFSLockFactory}, * etc.) passing in your preferred lock directory. Then, * pass this <code>LockFactory</code> instance to one of * the <code>getDirectory</code> methods that take a * <code>lockFactory</code> (for example, {@link #getDirectory(String, LockFactory)}). */ public static final String LOCK_DIR = System.getProperty("org.apache.lucene.lockDir", System.getProperty("java.io.tmpdir")); /** The default class which implements filesystem-based directories. */ private static Class IMPL; static { try { String name = System.getProperty("org.apache.lucene.FSDirectory.class", FSDirectory.class.getName()); IMPL = Class.forName(name); } catch (ClassNotFoundException e) { throw new RuntimeException("cannot load FSDirectory class: " + e.toString(), e); } catch (SecurityException se) { try { IMPL = Class.forName(FSDirectory.class.getName()); } catch (ClassNotFoundException e) { throw new RuntimeException("cannot load default FSDirectory class: " + e.toString(), e); } } } private static MessageDigest DIGESTER; static { try { DIGESTER = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e.toString(), e); } } /** A buffer optionally used in renameTo method */ private byte[] buffer = null; /** Returns the directory instance for the named location. * @param path the path to the directory. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(String path) throws IOException { return getDirectory(new File(path), null); } /** Returns the directory instance for the named location. * @param path the path to the directory. * @param lockFactory instance of {@link LockFactory} providing the * locking implementation. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(String path, LockFactory lockFactory) throws IOException { return getDirectory(new File(path), lockFactory); } /** Returns the directory instance for the named location. * @param file the path to the directory. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(File file) throws IOException { return getDirectory(file, null); } /** Returns the directory instance for the named location. * @param file the path to the directory. * @param lockFactory instance of {@link LockFactory} providing the * locking implementation. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(File file, LockFactory lockFactory) throws IOException { file = new File(file.getCanonicalPath()); if (file.exists() && !file.isDirectory()) throw new IOException(file + " not a directory"); if (!file.exists()) if (!file.mkdirs()) throw new IOException("Cannot create directory: " + file); FSDirectory dir; synchronized (DIRECTORIES) { dir = (FSDirectory)DIRECTORIES.get(file); if (dir == null) { try { dir = (FSDirectory)IMPL.newInstance(); } catch (Exception e) { throw new RuntimeException("cannot load FSDirectory class: " + e.toString(), e); } dir.init(file, lockFactory); DIRECTORIES.put(file, dir); } else { // Catch the case where a Directory is pulled from the cache, but has a // different LockFactory instance. if (lockFactory != null && lockFactory != dir.getLockFactory()) { throw new IOException("Directory was previously created with a different LockFactory instance; please pass null as the lockFactory instance and use setLockFactory to change it"); } } } synchronized (dir) { dir.refCount++; } return dir; } /** Returns the directory instance for the named location. * * @deprecated Use IndexWriter's create flag, instead, to * create a new index. * * @param path the path to the directory. * @param create if true, create, or erase any existing contents. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(String path, boolean create) throws IOException { return getDirectory(new File(path), create); } /** Returns the directory instance for the named location. * * @deprecated Use IndexWriter's create flag, instead, to * create a new index. * * @param file the path to the directory. * @param create if true, create, or erase any existing contents. * @return the FSDirectory for the named file. */ public static FSDirectory getDirectory(File file, boolean create) throws IOException { FSDirectory dir = getDirectory(file, null); // This is now deprecated (creation should only be done // by IndexWriter): if (create) { dir.create(); } return dir; } private void create() throws IOException { if (directory.exists()) { String[] files = directory.list(IndexFileNameFilter.getFilter()); // clear old files if (files == null) throw new IOException("cannot read directory " + directory.getAbsolutePath() + ": list() returned null"); for (int i = 0; i < files.length; i++) { File file = new File(directory, files[i]); if (!file.delete()) throw new IOException("Cannot delete " + file); } } lockFactory.clearLock(IndexWriter.WRITE_LOCK_NAME); } private File directory = null; private int refCount; protected FSDirectory() {}; // permit subclassing private void init(File path, LockFactory lockFactory) throws IOException { // Set up lockFactory with cascaded defaults: if an instance was passed in, // use that; else if locks are disabled, use NoLockFactory; else if the // system property org.apache.lucene.store.FSDirectoryLockFactoryClass is set, // instantiate that; else, use SimpleFSLockFactory: directory = path; boolean doClearLockID = false; if (lockFactory == null) { if (disableLocks) { // Locks are disabled: lockFactory = NoLockFactory.getNoLockFactory(); } else { String lockClassName = System.getProperty("org.apache.lucene.store.FSDirectoryLockFactoryClass"); if (lockClassName != null && !lockClassName.equals("")) { Class c; try { c = Class.forName(lockClassName); } catch (ClassNotFoundException e) { throw new IOException("unable to find LockClass " + lockClassName); } try { lockFactory = (LockFactory) c.newInstance(); } catch (IllegalAccessException e) { throw new IOException("IllegalAccessException when instantiating LockClass " + lockClassName); } catch (InstantiationException e) { throw new IOException("InstantiationException when instantiating LockClass " + lockClassName); } catch (ClassCastException e) { throw new IOException("unable to cast LockClass " + lockClassName + " instance to a LockFactory"); } if (lockFactory instanceof NativeFSLockFactory) { ((NativeFSLockFactory) lockFactory).setLockDir(path); } else if (lockFactory instanceof SimpleFSLockFactory) { ((SimpleFSLockFactory) lockFactory).setLockDir(path); } } else { // Our default lock is SimpleFSLockFactory; // default lockDir is our index directory: lockFactory = new SimpleFSLockFactory(path); doClearLockID = true; } } } setLockFactory(lockFactory); if (doClearLockID) { // Clear the prefix because write.lock will be // stored in our directory: lockFactory.setLockPrefix(null); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -