📄 fsdirectory.java
字号:
package org.apache.lucene.store;/** * Copyright 2004 The Apache Software Foundation * * Licensed 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;/** * Straightforward implementation of {@link Directory} as a directory of files. * * @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. * * This should be a WeakHashMap, so that entries can be GC'd, but that would * require Java 1.2. Instead we use refcounts... */ private static final Hashtable DIRECTORIES = new Hashtable(); private static boolean disableLocks = false; /** * 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 */ 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. * * <p>Directories are cached, so that, for a given canonical path, the same * FSDirectory instance will always be returned. This permits * synchronization on directories. * * @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. * * <p>Directories are cached, so that, for a given canonical path, the same * FSDirectory instance will always be returned. This permits * synchronization on directories. * * @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 { file = new File(file.getCanonicalPath()); 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, create); DIRECTORIES.put(file, dir); } else if (create) { dir.create(); } } synchronized (dir) { dir.refCount++; } return dir; } private File directory = null; private int refCount; private File lockDir; protected FSDirectory() {}; // permit subclassing private void init(File path, boolean create) throws IOException { directory = path; if (LOCK_DIR == null) { lockDir = directory; } else { lockDir = new File(LOCK_DIR); } // Ensure that lockDir exists and is a directory. if (!lockDir.exists()) { if (!lockDir.mkdirs()) throw new IOException("Cannot create directory: " + lockDir.getAbsolutePath()); } else if (!lockDir.isDirectory()) { throw new IOException("Found regular file where directory expected: " + lockDir.getAbsolutePath()); } if (create) { create(); } if (!directory.isDirectory()) throw new IOException(path + " not a directory"); } private synchronized void create() throws IOException { if (!directory.exists()) if (!directory.mkdirs()) throw new IOException("Cannot create directory: " + directory); if (!directory.isDirectory()) throw new IOException(directory + " not a directory"); String[] files = directory.list(new IndexFileNameFilter()); // clear old files if (files == null) throw new IOException("Cannot read directory " + directory.getAbsolutePath()); for (int i = 0; i < files.length; i++) { File file = new File(directory, files[i]); if (!file.delete()) throw new IOException("Cannot delete " + file); } String lockPrefix = getLockPrefix().toString(); // clear old locks files = lockDir.list(); if (files == null) throw new IOException("Cannot read lock directory " + lockDir.getAbsolutePath()); for (int i = 0; i < files.length; i++) { if (!files[i].startsWith(lockPrefix)) continue; File lockFile = new File(lockDir, files[i]); if (!lockFile.delete()) throw new IOException("Cannot delete " + lockFile); } } /** Returns an array of strings, one for each file in the directory. */ public String[] list() { return directory.list(); } /** Returns true iff a file with the given name exists. */ public boolean fileExists(String name) { File file = new File(directory, name); return file.exists(); } /** Returns the time the named file was last modified. */ public long fileModified(String name) { File file = new File(directory, name); return file.lastModified(); } /** Returns the time the named file was last modified. */ public static long fileModified(File directory, String name) { File file = new File(directory, name); return file.lastModified(); } /** Set the modified time of an existing file to now. */ public void touchFile(String name) { File file = new File(directory, name); file.setLastModified(System.currentTimeMillis()); } /** Returns the length in bytes of a file in the directory. */ public long fileLength(String name) { File file = new File(directory, name); return file.length(); } /** Removes an existing file in the directory. */ public void deleteFile(String name) throws IOException { File file = new File(directory, name); if (!file.delete()) throw new IOException("Cannot delete " + file); } /** Renames an existing file in the directory. */ public synchronized void renameFile(String from, String to) throws IOException { File old = new File(directory, from); File nu = new File(directory, to); /* This is not atomic. If the program crashes between the call to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -