Package org.apache.lucene.store

# Class FSDirectory

java.lang.Object
org.apache.lucene.store.Directory
org.apache.lucene.store.BaseDirectory
org.apache.lucene.store.FSDirectory

All Implemented Interfaces:
  `Closeable`, `AutoCloseable`

Direct Known Subclasses:
  `MMapDirectory`, `NIOFSDirectory`

public abstract class FSDirectory extends BaseDirectory
Base class for Directory implementations that store index files in the file system. There are currently two core subclasses:

- `MMapDirectory` uses memory-mapped IO when reading. This is a good choice if you have plenty of virtual memory relative to your index size, eg if you are running on a 64 bit JRE, or you are running on a 32 bit JRE but your index sizes are small enough to fit into the virtual memory space. This class will use the modern `MemorySegment`PREVIEW API available since Java 21 which allows to safely unmap previously mmapped files after closing the `IndexInput`s. There is no need to enable the "preview feature" of your Java version; it works out of box with some compilation tricks. For more information about the foreign memory API read documentation of the `java.lang.foreign` package and Uwe's blog post.
- `NIOFSDirectory` uses java.nio's FileChannel's positional io when reading to avoid synchronization when reading from the same file. Unfortunately, due to a Windows-only Sun JRE bug this is a poor choice for Windows, but on all other platforms this is the preferred choice. Applications using `Thread.interrupt()` or `Future.cancel(boolean)` should use `RAFDirectory` instead, which is provided in the `misc` module. See `NIOFSDirectory` javadoc for details.

Unfortunately, because of system peculiarities, there is no single overall best implementation. Therefore, we've added the `open(java.nio.file.Path)` method, to allow Lucene to choose the best FSDirectory implementation given your environment, and the known limitations of each implementation. For users who have no reason to prefer a specific implementation, it's best to simply use `open(java.nio.file.Path)`. For all others, you should instantiate the desired implementation directly.

NOTE: Accessing one of the above subclasses either directly or indirectly from a thread while it's interrupted can close the underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and subsequent access to the index will throw a `ClosedChannelException`. Applications using `Thread.interrupt()` or `Future.cancel(boolean)` should use the slower legacy `RAFDirectory` from the `misc` Lucene module instead.

The locking implementation is by default `NativeFSLockFactory`, but can be changed by passing in a custom `LockFactory` instance.

See Also:
  - `Directory`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final Path`
  `directory`

  ### Fields inherited from class org.apache.lucene.store.BaseDirectory

  `isOpen, lockFactory`

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `FSDirectory(Path path, LockFactory lockFactory)`
  Create a new FSDirectory for the named location (ctor for subclasses).

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `close()`
  Closes the directory.
  `IndexOutput`
  `createOutput(String name, IOContext context)`
  Creates a new, empty file in the directory and returns an `IndexOutput` instance for appending data to this file.
  `IndexOutput`
  `createTempOutput(String prefix, String suffix, IOContext context)`
  Creates a new, empty, temporary file in the directory and returns an `IndexOutput` instance for appending data to this file.
  `void`
  `deleteFile(String name)`
  Removes an existing file in the directory.
  `void`
  `deletePendingFiles()`
  Try to delete any pending files that we had previously tried to delete but failed because we are on Windows and the files were still held open.
  `protected void`
  `ensureCanRead(String name)`
  `long`
  `fileLength(String name)`
  Returns the byte length of a file in the directory.
  `protected void`
  `fsync(String name)`
  `Path`
  `getDirectory()`
  `Set<String>`
  `getPendingDeletions()`
  Returns a set of files currently pending deletion in this directory.
  `String[]`
  `listAll()`
  Returns names of all files stored in this directory.
  `static String[]`
  `listAll(Path dir)`
  Lists all files (including subdirectories) in the directory.
  `static FSDirectory`
  `open(Path path)`
  Creates an FSDirectory instance, trying to pick the best implementation given the current environment.
  `static FSDirectory`
  `open(Path path, LockFactory lockFactory)`
  Just like `open(Path)`, but allows you to also specify a custom `LockFactory`.
  `void`
  `rename(String source, String dest)`
  Renames `source` file to `dest` file where `dest` must not already exist in the directory.
  `void`
  `sync(Collection<String> names)`
  Ensures that any writes to these files are moved to stable storage (made durable).
  `void`
  `syncMetaData()`
  Ensures that directory metadata, such as recent file renames, are moved to stable storage.
  `String`
  `toString()`

  ### Methods inherited from class org.apache.lucene.store.BaseDirectory

  `ensureOpen, obtainLock`

  ### Methods inherited from class org.apache.lucene.store.Directory

  `copyFrom, getTempFileName, openChecksumInput, openInput`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### directory

    protected final Path directory

- ## Constructor Details

  - ### FSDirectory

    protected FSDirectory(Path path, LockFactory lockFactory) throws IOException
    Create a new FSDirectory for the named location (ctor for subclasses). The directory is created at the named location if it does not yet exist.

    `FSDirectory` resolves the given Path to a canonical / real path to ensure it can correctly lock the index directory and no other process can interfere with changing possible symlinks to the index directory inbetween. If you want to use symlinks and change them dynamically, close all `IndexWriters` and create a new `FSDirectory` instance.

    Parameters:
      `path` - the path of the directory
      `lockFactory` - the lock factory to use, or null for the default (`NativeFSLockFactory`);
    Throws:
      `IOException` - if there is a low-level I/O error

- ## Method Details

  - ### open

    public static FSDirectory open(Path path) throws IOException
    Creates an FSDirectory instance, trying to pick the best implementation given the current environment. The directory returned uses the `NativeFSLockFactory`. The directory is created at the named location if it does not yet exist.

    `FSDirectory` resolves the given Path when calling this method to a canonical / real path to ensure it can correctly lock the index directory and no other process can interfere with changing possible symlinks to the index directory inbetween. If you want to use symlinks and change them dynamically, close all `IndexWriters` and create a new `FSDirectory` instance.

    Currently this returns `MMapDirectory` for Linux, MacOSX, Solaris, and Windows 64-bit JREs, and `NIOFSDirectory` for other JREs. It is highly recommended that you consult the implementation's documentation for your platform before using this method.

    NOTE: this method may suddenly change which implementation is returned from release to release, in the event that higher performance defaults become possible; if the precise implementation is important to your application, please instantiate it directly, instead. For optimal performance you should consider using `MMapDirectory` on 64 bit JVMs.

    See above

    Throws:
      `IOException`

  - ### open

    public static FSDirectory open(Path path, LockFactory lockFactory) throws IOException
    Just like `open(Path)`, but allows you to also specify a custom `LockFactory`.
    Throws:
      `IOException`

  - ### listAll

    public static String[] listAll(Path dir) throws IOException
    Lists all files (including subdirectories) in the directory.
    Throws:
      `IOException` - if there was an I/O error during listing

  - ### listAll

    public String[] listAll() throws IOException
    Description copied from class: `Directory`
    Returns names of all files stored in this directory. The output must be in sorted (UTF-16, java's `String.compareTo(java.lang.String)`) order.
    Specified by:
      `listAll` in class `Directory`
    Throws:
      `IOException` - in case of I/O error

  - ### fileLength

    public long fileLength(String name) throws IOException
    Description copied from class: `Directory`
    Returns the byte length of a file in the directory.

    This method must throw either `NoSuchFileException` or `FileNotFoundException` if `name` points to a non-existing file.

    Specified by:
      `fileLength` in class `Directory`
    Parameters:
      `name` - the name of an existing file.
    Throws:
      `IOException` - in case of I/O error

  - ### createOutput

    public IndexOutput createOutput(String name, IOContext context) throws IOException
    Description copied from class: `Directory`
    Creates a new, empty file in the directory and returns an `IndexOutput` instance for appending data to this file.

    This method must throw `FileAlreadyExistsException` if the file already exists.

    Specified by:
      `createOutput` in class `Directory`
    Parameters:
      `name` - the name of the file to create.
    Throws:
      `IOException` - in case of I/O error

  - ### createTempOutput

    public IndexOutput createTempOutput(String prefix, String suffix, IOContext context) throws IOException
    Description copied from class: `Directory`
    Creates a new, empty, temporary file in the directory and returns an `IndexOutput` instance for appending data to this file.

    The temporary file name (accessible via `IndexOutput.getName()`) will start with `prefix`, end with `suffix` and have a reserved file extension `.tmp`.

    Specified by:
      `createTempOutput` in class `Directory`
    Throws:
      `IOException`

  - ### ensureCanRead

    protected void ensureCanRead(String name) throws IOException
    Throws:
      `IOException`

  - ### sync

    public void sync(Collection<String> names) throws IOException
    Description copied from class: `Directory`
    Ensures that any writes to these files are moved to stable storage (made durable).

    Lucene uses this to properly commit changes to the index, to prevent a machine/OS crash from corrupting the index.

    Specified by:
      `sync` in class `Directory`
    Throws:
      `IOException`
    See Also:
      - `Directory.syncMetaData()`

  - ### rename

    public void rename(String source, String dest) throws IOException
    Description copied from class: `Directory`
    Renames `source` file to `dest` file where `dest` must not already exist in the directory.

    It is permitted for this operation to not be truly atomic, for example both `source` and `dest` can be visible temporarily in `Directory.listAll()`. However, the implementation of this method must ensure the content of `dest` appears as the entire `source` atomically. So once `dest` is visible for readers, the entire content of previous `source` is visible.

    This method is used by IndexWriter to publish commits.

    Specified by:
      `rename` in class `Directory`
    Throws:
      `IOException`

  - ### syncMetaData

    public void syncMetaData() throws IOException
    Description copied from class: `Directory`
    Ensures that directory metadata, such as recent file renames, are moved to stable storage.
    Specified by:
      `syncMetaData` in class `Directory`
    Throws:
      `IOException`
    See Also:
      - `Directory.sync(Collection)`

  - ### close

    public void close() throws IOException
    Description copied from class: `Directory`
    Closes the directory.
    Specified by:
      `close` in interface `AutoCloseable`
    Specified by:
      `close` in interface `Closeable`
    Specified by:
      `close` in class `Directory`
    Throws:
      `IOException`

  - ### getDirectory

    public Path getDirectory()
    Returns:
      the underlying filesystem directory

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `BaseDirectory`

  - ### fsync

    protected void fsync(String name) throws IOException
    Throws:
      `IOException`

  - ### deleteFile

    public void deleteFile(String name) throws IOException
    Description copied from class: `Directory`
    Removes an existing file in the directory.

    This method must throw either `NoSuchFileException` or `FileNotFoundException` if `name` points to a non-existing file.

    Specified by:
      `deleteFile` in class `Directory`
    Parameters:
      `name` - the name of an existing file.
    Throws:
      `IOException` - in case of I/O error

  - ### deletePendingFiles

    public void deletePendingFiles() throws IOException
    Try to delete any pending files that we had previously tried to delete but failed because we are on Windows and the files were still held open.
    Throws:
      `IOException`

  - ### getPendingDeletions

    public Set<String> getPendingDeletions() throws IOException
    Description copied from class: `Directory`
    Returns a set of files currently pending deletion in this directory.
    Specified by:
      `getPendingDeletions` in class `Directory`
    Throws:
      `IOException`