blob: 0e7fd49e73197285d3cb7614b3232cd4faede519 [file] [log] [blame]
/*
* 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.
*/
using System;
namespace Lucene.Net.Store
{
/// <summary>A Directory is a flat list of files. Files may be written once, when they
/// are created. Once a file is created it may only be opened for read, or
/// deleted. Random access is permitted both when reading and writing.
///
/// <p> Java's i/o APIs not used directly, but rather all i/o is
/// through this API. This permits things such as: <ul>
/// <li> implementation of RAM-based indices;
/// <li> implementation indices stored in a database, via JDBC;
/// <li> implementation of an index as a single file;
/// </ul>
///
/// Directory locking is implemented by an instance of {@link
/// LockFactory}, and can be changed for each Directory
/// instance using {@link #setLockFactory}.
///
/// </summary>
/// <author> Doug Cutting
/// </author>
[Serializable]
public abstract class Directory
{
/// <summary>Holds the LockFactory instance (implements locking for
/// this Directory instance).
/// </summary>
[NonSerialized]
protected internal LockFactory lockFactory;
/// <summary>Returns an array of strings, one for each file in the
/// directory. This method may return null (for example for
/// {@link FSDirectory} if the underlying directory doesn't
/// exist in the filesystem or there are permissions
/// problems).
/// </summary>
public abstract System.String[] List();
/// <summary>Returns true iff a file with the given name exists. </summary>
public abstract bool FileExists(System.String name);
/// <summary>Returns the time the named file was last modified. </summary>
public abstract long FileModified(System.String name);
/// <summary>Set the modified time of an existing file to now. </summary>
public abstract void TouchFile(System.String name);
/// <summary>Removes an existing file in the directory. </summary>
public abstract void DeleteFile(System.String name);
/// <summary>Renames an existing file in the directory.
/// If a file already exists with the new name, then it is replaced.
/// This replacement is not guaranteed to be atomic.
/// </summary>
/// <deprecated>
/// </deprecated>
public abstract void RenameFile(System.String from, System.String to);
/// <summary>Returns the length of a file in the directory. </summary>
public abstract long FileLength(System.String name);
/// <summary>Creates a new, empty file in the directory with the given name.
/// Returns a stream writing this file.
/// </summary>
public abstract IndexOutput CreateOutput(System.String name);
/// <summary>Returns a stream reading an existing file. </summary>
public abstract IndexInput OpenInput(System.String name);
/// <summary>Returns a stream reading an existing file, with the
/// specified read buffer size. The particular Directory
/// implementation may ignore the buffer size. Currently
/// the only Directory implementations that respect this
/// parameter are {@link FSDirectory} and {@link
/// Lucene.Net.Index.CompoundFileReader}.
/// </summary>
public virtual IndexInput OpenInput(System.String name, int bufferSize)
{
return OpenInput(name);
}
/// <summary>Construct a {@link Lock}.</summary>
/// <param name="name">the name of the lock file
/// </param>
public virtual Lock MakeLock(System.String name)
{
return lockFactory.MakeLock(name);
}
/// <summary> Attempt to clear (forcefully unlock and remove) the
/// specified lock. Only call this at a time when you are
/// certain this lock is no longer in use.
/// </summary>
/// <param name="name">name of the lock to be cleared.
/// </param>
public virtual void ClearLock(System.String name)
{
if (lockFactory != null)
{
lockFactory.ClearLock(name);
}
}
/// <summary>Closes the store. </summary>
public abstract void Close();
/// <summary> Set the LockFactory that this Directory instance should
/// use for its locking implementation. Each * instance of
/// LockFactory should only be used for one directory (ie,
/// do not share a single instance across multiple
/// Directories).
///
/// </summary>
/// <param name="lockFactory">instance of {@link LockFactory}.
/// </param>
public virtual void SetLockFactory(LockFactory lockFactory)
{
this.lockFactory = lockFactory;
lockFactory.SetLockPrefix(this.GetLockID());
}
/// <summary> Get the LockFactory that this Directory instance is
/// using for its locking implementation. Note that this
/// may be null for Directory implementations that provide
/// their own locking implementation.
/// </summary>
public virtual LockFactory GetLockFactory()
{
return this.lockFactory;
}
/// <summary> Return a string identifier that uniquely differentiates
/// this Directory instance from other Directory instances.
/// This ID should be the same if two Directory instances
/// (even in different JVMs and/or on different machines)
/// are considered "the same index". This is how locking
/// "scopes" to the right index.
/// </summary>
public virtual System.String GetLockID()
{
return this.ToString();
}
/// <summary> Copy contents of a directory src to a directory dest.
/// If a file in src already exists in dest then the
/// one in dest will be blindly overwritten.
///
/// </summary>
/// <param name="src">source directory
/// </param>
/// <param name="dest">destination directory
/// </param>
/// <param name="closeDirSrc">if <code>true</code>, call {@link #close()} method on source directory
/// </param>
/// <throws> IOException </throws>
public static void Copy(Directory src, Directory dest, bool closeDirSrc)
{
System.String[] files = src.List();
if (files == null)
{
throw new System.IO.IOException("cannot read directory " + src + ": list() returned null");
}
byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE];
for (int i = 0; i < files.Length; i++)
{
IndexOutput os = null;
IndexInput is_Renamed = null;
try
{
// create file in dest directory
os = dest.CreateOutput(files[i]);
// read current file
is_Renamed = src.OpenInput(files[i]);
// and copy to dest directory
long len = is_Renamed.Length();
long readCount = 0;
while (readCount < len)
{
int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len ? (int) (len - readCount) : BufferedIndexOutput.BUFFER_SIZE;
is_Renamed.ReadBytes(buf, 0, toRead);
os.WriteBytes(buf, toRead);
readCount += toRead;
}
}
finally
{
// graceful cleanup
try
{
if (os != null)
os.Close();
}
finally
{
if (is_Renamed != null)
is_Renamed.Close();
}
}
}
if (closeDirSrc)
src.Close();
}
}
}