CompoundFileReader.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:7k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. using BufferedIndexInput = Lucene.Net.Store.BufferedIndexInput;
  18. using Directory = Lucene.Net.Store.Directory;
  19. using IndexInput = Lucene.Net.Store.IndexInput;
  20. using IndexOutput = Lucene.Net.Store.IndexOutput;
  21. using Lock = Lucene.Net.Store.Lock;
  22. namespace Lucene.Net.Index
  23. {
  24. /// <summary> Class for accessing a compound stream.
  25. /// This class implements a directory, but is limited to only read operations.
  26. /// Directory methods that would normally modify data throw an exception.
  27. /// 
  28. /// </summary>
  29. /// <author>  Dmitry Serebrennikov
  30. /// </author>
  31. /// <version>  $Id: CompoundFileReader.java 208905 2005-07-03 10:40:01Z dnaber $
  32. /// </version>
  33. public class CompoundFileReader : Directory
  34. {
  35. private sealed class FileEntry
  36. {
  37. internal long offset;
  38. internal long length;
  39. }
  40. // Base info
  41. private Directory directory;
  42. private System.String fileName;
  43. private IndexInput stream;
  44. private System.Collections.Hashtable entries = new System.Collections.Hashtable();
  45. public CompoundFileReader(Directory dir, System.String name)
  46. {
  47. directory = dir;
  48. fileName = name;
  49. bool success = false;
  50. try
  51. {
  52. stream = dir.OpenInput(name);
  53. // read the directory and init files
  54. int count = stream.ReadVInt();
  55. FileEntry entry = null;
  56. for (int i = 0; i < count; i++)
  57. {
  58. long offset = stream.ReadLong();
  59. System.String id = stream.ReadString();
  60. if (entry != null)
  61. {
  62. // set length of the previous entry
  63. entry.length = offset - entry.offset;
  64. }
  65. entry = new FileEntry();
  66. entry.offset = offset;
  67. entries[id] = entry;
  68. }
  69. // set the length of the final entry
  70. if (entry != null)
  71. {
  72. entry.length = stream.Length() - entry.offset;
  73. }
  74. success = true;
  75. }
  76. finally
  77. {
  78. if (!success && (stream != null))
  79. {
  80. try
  81. {
  82. stream.Close();
  83. }
  84. catch (System.IO.IOException)
  85. {
  86. }
  87. }
  88. }
  89. }
  90. public virtual Directory GetDirectory()
  91. {
  92. return directory;
  93. }
  94. public virtual System.String GetName()
  95. {
  96. return fileName;
  97. }
  98. public override void  Close()
  99. {
  100. lock (this)
  101. {
  102. if (stream == null)
  103. throw new System.IO.IOException("Already closed");
  104. entries.Clear();
  105. stream.Close();
  106. stream = null;
  107. }
  108. }
  109. public override IndexInput OpenInput(System.String id)
  110. {
  111. lock (this)
  112. {
  113. if (stream == null)
  114. throw new System.IO.IOException("Stream closed");
  115. FileEntry entry = (FileEntry) entries[id];
  116. if (entry == null)
  117. throw new System.IO.IOException("No sub-file with id " + id + " found");
  118. return new CSIndexInput(stream, entry.offset, entry.length);
  119. }
  120. }
  121. /// <summary>Returns an array of strings, one for each file in the directory. </summary>
  122. public override System.String[] List()
  123. {
  124. System.String[] res = new System.String[entries.Count];
  125.             entries.Keys.CopyTo(res, 0);
  126. return res;
  127. }
  128. /// <summary>Returns true iff a file with the given name exists. </summary>
  129. public override bool FileExists(System.String name)
  130. {
  131. return entries.ContainsKey(name);
  132. }
  133. /// <summary>Returns the time the compound file was last modified. </summary>
  134. public override long FileModified(System.String name)
  135. {
  136. return directory.FileModified(fileName);
  137. }
  138. /// <summary>Set the modified time of the compound file to now. </summary>
  139. public override void  TouchFile(System.String name)
  140. {
  141. directory.TouchFile(fileName);
  142. }
  143. /// <summary>Not implemented</summary>
  144. /// <throws>  UnsupportedOperationException  </throws>
  145. public override void  DeleteFile(System.String name)
  146. {
  147. throw new System.NotSupportedException();
  148. }
  149. /// <summary>Not implemented</summary>
  150. /// <throws>  UnsupportedOperationException  </throws>
  151. public override void  RenameFile(System.String from, System.String to)
  152. {
  153. throw new System.NotSupportedException();
  154. }
  155. /// <summary>Returns the length of a file in the directory.</summary>
  156. /// <throws>  IOException if the file does not exist  </throws>
  157. public override long FileLength(System.String name)
  158. {
  159. FileEntry e = (FileEntry) entries[name];
  160. if (e == null)
  161. throw new System.IO.IOException("File " + name + " does not exist");
  162. return e.length;
  163. }
  164. /// <summary>Not implemented</summary>
  165. /// <throws>  UnsupportedOperationException  </throws>
  166. public override IndexOutput CreateOutput(System.String name)
  167. {
  168. throw new System.NotSupportedException();
  169. }
  170. /// <summary>Not implemented</summary>
  171. /// <throws>  UnsupportedOperationException  </throws>
  172. public override Lock MakeLock(System.String name)
  173. {
  174. throw new System.NotSupportedException();
  175. }
  176. /// <summary>Implementation of an IndexInput that reads from a portion of the
  177. /// compound file. The visibility is left as "package" *only* because
  178. /// this helps with testing since JUnit test cases in a different class
  179. /// can then access package fields of this class.
  180. /// </summary>
  181. public /*internal*/ sealed class CSIndexInput : BufferedIndexInput
  182. {
  183. public /*internal*/ IndexInput base_Renamed;
  184. internal long fileOffset;
  185. internal long length;
  186. internal CSIndexInput(IndexInput base_Renamed, long fileOffset, long length)
  187. {
  188. this.base_Renamed = base_Renamed;
  189. this.fileOffset = fileOffset;
  190. this.length = length;
  191. }
  192. /// <summary>Expert: implements buffer refill.  Reads bytes from the current
  193. /// position in the input.
  194. /// </summary>
  195. /// <param name="b">the array to read bytes into
  196. /// </param>
  197. /// <param name="offset">the offset in the array to start storing bytes
  198. /// </param>
  199. /// <param name="len">the number of bytes to read
  200. /// </param>
  201. public override void  ReadInternal(byte[] b, int offset, int len)
  202. {
  203. lock (base_Renamed)
  204. {
  205. long start = GetFilePointer();
  206. if (start + len > length)
  207. throw new System.IO.IOException("read past EOF");
  208. base_Renamed.Seek(fileOffset + start);
  209. base_Renamed.ReadBytes(b, offset, len);
  210. }
  211. }
  212. /// <summary>Expert: implements seek.  Sets current position in this file, where
  213. /// the next {@link #ReadInternal(byte[],int,int)} will occur.
  214. /// </summary>
  215. /// <seealso cref="ReadInternal(byte[],int,int)">
  216. /// </seealso>
  217. public override void  SeekInternal(long pos)
  218. {
  219. }
  220. /// <summary>Closes the stream to further operations. </summary>
  221. public override void  Close()
  222. {
  223. }
  224. public override long Length()
  225. {
  226. return length;
  227. }
  228. }
  229. }
  230. }