Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
Directory.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 using IndexFileNameFilter = Lucene.Net.Index.IndexFileNameFilter;
21 
22 namespace Lucene.Net.Store
23 {
24 
25  /// <summary>A Directory is a flat list of files. Files may be written once, when they
26  /// are created. Once a file is created it may only be opened for read, or
27  /// deleted. Random access is permitted both when reading and writing.
28  ///
29  /// <p/> Java's i/o APIs not used directly, but rather all i/o is
30  /// through this API. This permits things such as: <list>
31  /// <item> implementation of RAM-based indices;</item>
32  /// <item> implementation indices stored in a database, via JDBC;</item>
33  /// <item> implementation of an index as a single file;</item>
34  /// </list>
35  ///
36  /// Directory locking is implemented by an instance of <see cref="LockFactory" />
37  ///, and can be changed for each Directory
38  /// instance using <see cref="SetLockFactory" />.
39  ///
40  /// </summary>
41  [Serializable]
42  public abstract class Directory : System.IDisposable
43  {
44  protected internal volatile bool isOpen = true;
45 
46  /// <summary>Holds the LockFactory instance (implements locking for
47  /// this Directory instance).
48  /// </summary>
49  [NonSerialized]
50  protected internal LockFactory interalLockFactory;
51 
52  /// <summary>Returns an array of strings, one for each file in the directory.</summary>
53  /// <exception cref="System.IO.IOException"></exception>
54  public abstract System.String[] ListAll();
55 
56  /// <summary>Returns true iff a file with the given name exists. </summary>
57  public abstract bool FileExists(System.String name);
58 
59  /// <summary>Returns the time the named file was last modified. </summary>
60  public abstract long FileModified(System.String name);
61 
62  /// <summary>Set the modified time of an existing file to now. </summary>
63  public abstract void TouchFile(System.String name);
64 
65  /// <summary>Removes an existing file in the directory. </summary>
66  public abstract void DeleteFile(System.String name);
67 
68  /// <summary>Returns the length of a file in the directory. </summary>
69  public abstract long FileLength(System.String name);
70 
71 
72  /// <summary>Creates a new, empty file in the directory with the given name.
73  /// Returns a stream writing this file.
74  /// </summary>
75  public abstract IndexOutput CreateOutput(System.String name);
76 
77  /// <summary>Ensure that any writes to this file are moved to
78  /// stable storage. Lucene uses this to properly commit
79  /// changes to the index, to prevent a machine/OS crash
80  /// from corrupting the index.
81  /// </summary>
82  public virtual void Sync(System.String name)
83  {
84  }
85 
86  /// <summary>Returns a stream reading an existing file. </summary>
87  public abstract IndexInput OpenInput(System.String name);
88 
89  /// <summary>Returns a stream reading an existing file, with the
90  /// specified read buffer size. The particular Directory
91  /// implementation may ignore the buffer size. Currently
92  /// the only Directory implementations that respect this
93  /// parameter are <see cref="FSDirectory" /> and <see cref="Lucene.Net.Index.CompoundFileReader" />
94  ///.
95  /// </summary>
96  public virtual IndexInput OpenInput(System.String name, int bufferSize)
97  {
98  return OpenInput(name);
99  }
100 
101  /// <summary>Construct a <see cref="Lock" />.</summary>
102  /// <param name="name">the name of the lock file
103  /// </param>
104  public virtual Lock MakeLock(System.String name)
105  {
106  return interalLockFactory.MakeLock(name);
107  }
108  /// <summary> Attempt to clear (forcefully unlock and remove) the
109  /// specified lock. Only call this at a time when you are
110  /// certain this lock is no longer in use.
111  /// </summary>
112  /// <param name="name">name of the lock to be cleared.
113  /// </param>
114  public virtual void ClearLock(System.String name)
115  {
116  if (interalLockFactory != null)
117  {
118  interalLockFactory.ClearLock(name);
119  }
120  }
121 
122  [Obsolete("Use Dispose() instead")]
123  public void Close()
124  {
125  Dispose();
126  }
127 
128  /// <summary>Closes the store. </summary>
129  public void Dispose()
130  {
131  Dispose(true);
132  }
133 
134  protected abstract void Dispose(bool disposing);
135 
136  /// <summary> Set the LockFactory that this Directory instance should
137  /// use for its locking implementation. Each * instance of
138  /// LockFactory should only be used for one directory (ie,
139  /// do not share a single instance across multiple
140  /// Directories).
141  ///
142  /// </summary>
143  /// <param name="lockFactory">instance of <see cref="LockFactory" />.
144  /// </param>
145  public virtual void SetLockFactory(LockFactory lockFactory)
146  {
147  System.Diagnostics.Debug.Assert(lockFactory != null);
148  this.interalLockFactory = lockFactory;
149  lockFactory.LockPrefix = this.GetLockId();
150  }
151 
152  /// <summary> Get the LockFactory that this Directory instance is
153  /// using for its locking implementation. Note that this
154  /// may be null for Directory implementations that provide
155  /// their own locking implementation.
156  /// </summary>
157  public virtual LockFactory LockFactory
158  {
159  get { return this.interalLockFactory; }
160  }
161 
162  /// <summary> Return a string identifier that uniquely differentiates
163  /// this Directory instance from other Directory instances.
164  /// This ID should be the same if two Directory instances
165  /// (even in different JVMs and/or on different machines)
166  /// are considered "the same index". This is how locking
167  /// "scopes" to the right index.
168  /// </summary>
169  [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
170  public virtual string GetLockId()
171  {
172  return ToString();
173  }
174 
175  public override string ToString()
176  {
177  return base.ToString() + " lockFactory=" + LockFactory;
178  }
179 
180  /// <summary> Copy contents of a directory src to a directory dest.
181  /// If a file in src already exists in dest then the
182  /// one in dest will be blindly overwritten.
183  ///
184  /// <p/><b>NOTE:</b> the source directory cannot change
185  /// while this method is running. Otherwise the results
186  /// are undefined and you could easily hit a
187  /// FileNotFoundException.
188  ///
189  /// <p/><b>NOTE:</b> this method only copies files that look
190  /// like index files (ie, have extensions matching the
191  /// known extensions of index files).
192  ///
193  /// </summary>
194  /// <param name="src">source directory
195  /// </param>
196  /// <param name="dest">destination directory
197  /// </param>
198  /// <param name="closeDirSrc">if <c>true</c>, call <see cref="Close()" /> method on source directory
199  /// </param>
200  /// <throws> IOException </throws>
201  public static void Copy(Directory src, Directory dest, bool closeDirSrc)
202  {
203  System.String[] files = src.ListAll();
204 
206 
207  byte[] buf = new byte[BufferedIndexOutput.BUFFER_SIZE];
208  for (int i = 0; i < files.Length; i++)
209  {
210 
211  if (!filter.Accept(null, files[i]))
212  continue;
213 
214  IndexOutput os = null;
215  IndexInput is_Renamed = null;
216  try
217  {
218  // create file in dest directory
219  os = dest.CreateOutput(files[i]);
220  // read current file
221  is_Renamed = src.OpenInput(files[i]);
222  // and copy to dest directory
223  long len = is_Renamed.Length();
224  long readCount = 0;
225  while (readCount < len)
226  {
227  int toRead = readCount + BufferedIndexOutput.BUFFER_SIZE > len?(int) (len - readCount):BufferedIndexOutput.BUFFER_SIZE;
228  is_Renamed.ReadBytes(buf, 0, toRead);
229  os.WriteBytes(buf, toRead);
230  readCount += toRead;
231  }
232  }
233  finally
234  {
235  // graceful cleanup
236  try
237  {
238  if (os != null)
239  os.Close();
240  }
241  finally
242  {
243  if (is_Renamed != null)
244  is_Renamed.Close();
245  }
246  }
247  }
248  if (closeDirSrc)
249  src.Close();
250  }
251 
252  /// <throws> AlreadyClosedException if this Directory is closed </throws>
253  public /*protected internal*/ void EnsureOpen()
254  {
255  if (!isOpen)
256  throw new AlreadyClosedException("this Directory is closed");
257  }
258 
259  public bool isOpen_ForNUnit
260  {
261  get { return isOpen; }
262  }
263  }
264 }