3

私はこのhttp://www.codeproject.com/Articles/31944/Implementing-a-TextReader-to-extract-various-filesを使用しており、ほとんど機能しています。

このテストを作成して、フィルターがバイト配列から期待どおりに読み取られるかどうかを確認しました。

private const string ExpectedText = "This is a test!";
[Test]
public void FilterReader_RtfBytes_TextMatch()
{
    var bytes = File.ReadAllBytes(@"Test Documents\DocTest.rtf");
    var reader = new FilterReader(bytes, ".rtf");
    reader.Init();
    var actualText = reader.ReadToEnd();
    StringAssert.Contains(ExpectedText, actualText);
}

テストはErrorCode:FILTER_E_ACCESSで失敗します。ファイル名を指定すると、正常に機能します。

new FilterReader(@"Test Documents\DocTest.rtf", ".rtf"); <-- works

それがなぜなのか私は戸惑っています。コードを調べたところ、エラーを返すのはrtffilterdllのようです。これはさらに不可解です。

次のような他のファイルタイプでも正常に機能します。.doc、.docx、.pdf

4

1 に答える 1

2

内部的には、iFilterでの具体的な作業方法の使用は、コンストラクターによって定義されます。コンストラクターを使用する場合FilterReader(byte[] bytes, string extension)、メモリからのコンテンツのロードにはIPersistStreamが使用されFilterReader(string path, string extension)、ファイルからのロードにはIPersistFileが使用されます。

IPersistStreamで使用するとrtf-ifilterがエラーを返す理由ソースコードが開かれていないため、わかりません。

私の場合、フィルター固有のコンストラクターをカプセル化し、次の方法でコードをリファクタリングします。

  • すべてのコンストラクターを削除します
  • remove public void Init()-method
  • 1つのカスタムコンストラクターを実装しますpublic FilterReader(string fileName, string extension, uint blockSize = 0x2000)

    #region Contracts
    
    Contract.Requires(!string.IsNullOrEmpty(fileName));
    Contract.Requires(!string.IsNullOrEmpty(extension));
    Contract.Requires(blockSize > 1);
    
    #endregion
    
    const string rtfExtension = ".rtf";
    
    FileName = fileName;
    Extension = extension;
    BufferSize = blockSize;
    
    _buffer = new char[ActBufferSize];
    
    // ! Take into account that Rtf-file can be loaded only using IPersistFile.
    var doUseIPersistFile = string.Compare(rtfExtension, extension, StringComparison.InvariantCultureIgnoreCase) == 0;
    
    // Initialize _filter instance.
    try
    {
        if (doUseIPersistFile)
        {
            // Load content using IPersistFile.
            _filter = FilterLoader.LoadIFilterFromIPersistFile(FileName, Extension);
        }
        else
        {
            // Load content using IPersistStream.
            using (var stream = new FileStream(path: fileName, mode: FileMode.Open, access: FileAccess.Read, share: FileShare.Read))
            {
                var buffer = new byte[stream.Length];
                stream.Read(buffer, 0, buffer.Length);
    
                _filter = FilterLoader.LoadIFilterFromStream(buffer, Extension);
            }
        }
    }
    catch (FileNotFoundException)
    {
        throw;
    }
    catch (Exception e)
    {
        throw new AggregateException(message: string.Format("Filter Not Found or Loaded for extension '{0}'.", Extension), innerException: e);
    }
    
于 2014-12-15T08:17:08.097 に答える