使用RAMDirectory在Lucene.net中导致FileNotFoundException

时间:2013-09-27 22:54:50

标签: c# unit-testing lucene.net

我有一个索引管理器类,可以将文档写入索引。当我传递一个RAMDirectory来创建一个IndexWriter,我在文件segments.gen

上得到一个FileNotFoundException

这是我的班级:

public class IndexManager
{
    private readonly IIndexPersistable _indexPersister;

    public IndexManager(IIndexPersistable indexPersister)
    {
        _indexPersister = indexPersister;
    }

    public Directory Directory
    {
        get { return _indexPersister.Directory; }
    }

    internal void WriteDocumentsToIndex(
        IEnumerable<Document> documents, 
        bool recreateIndex)
    {
        using(var writer = 
            new IndexWriter(
                Directory, 
                new StandardAnalyzer(LuceneVersion.LUCENE_30), 
                recreateIndex,
                IndexWriter.MaxFieldLength.UNLIMITED))
        {
            foreach (Document document in documents)
            {
                writer.AddDocument(document);
            }

            writer.Optimize();
        }
    }
}


public class InMemoryPersister : IIndexPersistable
{
    private readonly Directory _directory;

    public InMemoryPersister()
    {
        _directory = new RAMDirectory();
    }

    public Directory Directory
    {
        get { return _directory; }
    }
}

这是单元测试方法:

[TestMethod]
    public void TestMethod1()
    {
        using (var manager = new IndexManager(new InMemoryPersister()))
        {
            IList<Recipe> recipes = Repositories.RecipeRepo.GetAllRecipes().ToList();
            IEnumerable<Document> documents = recipes.Select(RecipeIndexer.IndexRecipe);
            manager.WriteDocumentsToIndex(documents, true);
        }
    }

我尝试了一些不同的排列,但在这个解决方案中,我总是得到一个FileNotFoundException。我在测试解决方案中有另一个非常类似的实现,它运行良好。我还修改了这个解决方案几次,以便在创建新的IndexWriter时简单地声明一个新的RAMDirectory,但也失败了。

非常感谢帮助/建议。如果我需要澄清任何内容,请告诉我。

2 个答案:

答案 0 :(得分:2)

我已启用CLR例外中断。 Lucene抛出异常并处理它们但我正在打断这个过程。一旦我禁用了CLR Exception break,我的测试就成功地使用了RAMDirectory。

答案 1 :(得分:1)

如果create参数为false且Directory尚未包含索引,则Index Writer将抛出FileNotFound异常。使用RAMDirectory,第一次打开IndexWriter时,它将没有索引。如果您希望它创建索引,则可以将IndexReader.IndexExists(Directory) || recreate传递给构造函数,而不仅仅是recreate

另一个选择是使用一个没有create参数的IndexWriter构造函数,如果它不存在则会创建索引,如果不存在则打开现有的索引。