一般读取任何文件格式并将其转换为 .txt 格式

Generically read any file format and convert it to .txt format

如果包含文本,我需要确保在进行任何进一步处理之前将用户提供的文件转换为 .txt 文件。

目前我有一个 switch 语句检查特定格式并将其转换为 .txt 格式。

switch (extension)
{
    case ".pdf":
        //Convert from .pdf to .txt file
        break;
    case ".doc":
        //Convert from .doc to .txt file
        break;
    default:
        Console.WriteLine("The file could not be converted!");
        break;
}

问题是,我需要更通用的东西来检查给定文件是否为 .txt,或者如果不是但可以转换,那么就这样做。

听从L.B的建议我要投胎this.

在带有 IKVM 的 .Net 应用程序中使用 Tika Java 库

这听起来可能令人恐惧和异端,但您是否知道可以利用 .Net 应用程序中的 Java 库,而无需 TCP 套接字或 web 服务陷入困境?让我向您介绍 IKVM,坦率地说它很神奇:

IKVM.NET 是针对 Mono 和 Microsoft .NET Framework 的 Java 的实现。它包括以下组件:

  • A Java 在 .NET 中实现的虚拟机
  • Java class 库
  • 的 .NET 实现
  • 支持 Java 和 .NET 互操作性的工具

使用 IKVM,我们已经能够成功地将我们的 Dovetail Seeker 搜索应用程序与 Java 中实现的 Tika 文本提取库集成。借助 Tika,我们可以轻松地从多种受支持格式的丰富文档中提取文本。为什么是蒂卡?因为在 .Net 世界中没有任何东西可以与 Tika 相提并论。

此 post 将回顾我们如何与 Tika 集成。如果您喜欢代码,可以在 Github.

上的回购中找到 this example

将 Jar 编译成程序集

首先,我们需要获得最新版本的 Tika。我下载并构建了 Tika source using Maven as instructed。这样做的结果是一些 jar 文件。我们感兴趣的是 tika-app-x.x.jar,它将我们需要的一切捆绑到一个有用的容器中。

接下来我们需要将我们构建的这个 jar 转换为 .Net 程序集。使用 ikvmc.exe.

执行此操作
tika\build>ikvmc.exe -target:library tika-app-0.7.jar

不幸的是,您会看到大量看起来很麻烦的警告,但最终结果是一个 .Net 程序集包装了 Java jar,您可以在项目中引用它。

使用 .Net 中的 Tika

IKVM 非常透明。您只需引用 Tika 应用程序集,您的 .Net 代码就会与 Java 类型对话。起初有点奇怪,因为您有 Java 版本的类型和 .Net 版本。接下来,您需要确保所有依赖的 IKVM 运行时程序集都包含在您的项目中。使用 Reflector,我发现 Tika 应用程序集引用了很多 IKVM 程序集,这些程序集似乎没有被使用。我必须通过反复试验找出哪些程序集没有被正在进行的丰富文档提取所触及。如果需要,您可以简单地将所有引用的 IKVM 程序集包含在您的应用程序中。下面我已经为您完成了工作,并删除了对似乎在运行的所有 IKVM 程序集的所有引用。

16 个程序集减少到 5 个。更小的部署。

使用提卡

为了进行一些文本提取,我们会要求 Tika 非常友好地解析我们扔给它的文件。出于我的目的,这涉及让 Tika 自动确定如何解析流并提取有关文档的文本和元数据。

public TextExtractionResult Extract(string filePath)
{
var parser = new AutoDetectParser();
var metadata = new Metadata();
var parseContext = new ParseContext();
java.lang.Class parserClass = parser.GetType();
parseContext.set(parserClass, parser);

try
{
var file = new File(filePath);
var url = file.toURI().toURL();
using (var inputStream = MetadataHelper.getInputStream(url, metadata))
{
parser.parse(inputStream, getTransformerHandler(), metadata, parseContext);
inputStream.close();
}

return assembleExtractionResult(_outputWriter.toString(), metadata);
}
catch (Exception ex)
{
throw new ApplicationException("Extraction of text from the file '{0}' failed.".ToFormat(filePath), ex);
}
}

一个重要的警告

Java 有一个叫做 ClassLoader 的概念,它与如何找到和加载 Java 类型有关。可能有更好的方法解决这个问题,但出于某种原因,如果您不实现自定义 ClassLoader,并且还设置了一个应用程序设置,提示 IKVM 运行时关于将哪种 .Net 类型用作 ClassLoader。

public class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{
}
}

这里有一个例子app.config 告诉 IKVM 在哪里找到类加载器。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ikvm:java.system.class.loader" value="TikaOnDotNet.MySystemClassLoader, TikaOnDotNet" />
</appSettings>
</configuration>

这一步非常重要。如果 IKVM 找不到 class 加载程序,由于某些可怕的原因,Tika 可以正常工作但只提取没有元数据的空文档.这令人不安的主要原因是没有引发异常。出于这个原因,我们实际上在我们的应用程序中有一个验证步骤,以确保应用程序设置存在并且它解析为有效类型。

演示

这是一个演示提取和结果的测试。

[Test]
public void should_extract_from_pdf()
{
var textExtractionResult = new TextExtractor().Extract("Tika.pdf");

textExtractionResult.Text.ShouldContain("pack of pickled almonds");

Console.WriteLine(textExtractionResult);
}

像这样把简单的丰富文档放进去。

然后一个 TextExtractionResult 出来了:

public class TextExtractionResult
{
public string Text { get; set; }
public string ContentType { get; set; }
public IDictionary<string, string> Metadata { get; set; }
//toString() override
}

这是 Tika 的原始输出:

结论

我希望这有助于增强您在 .Net 代码中使用 Java 库的信心,如果您需要使用 Tika 在.Net 平台。享受。


设置信息:

使用 Nuget 查找 TikaOnDotnet 并将 TikaOnDotnet 和 TikaOnDotnet.TextExtractor 安装到您的项目中。这是在 Winform 应用程序上测试它的代码:

public partial class Form1 : Form
{
    private System.Windows.Forms.TextBox textBox1;
    private TextExtractor _textExtractor;
    public Form1()
    {
        InitializeComponent();
        _textExtractor = new TextExtractor();

        textBox1 = new System.Windows.Forms.TextBox();
        textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
        textBox1.Multiline = true;
        textBox1.Name = "textBox1";
        textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
        textBox1.AllowDrop = true;
        textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop);
        textBox1.DragOver += new System.Windows.Forms.DragEventHandler(this.textBox1_DragOver);
        Controls.Add(this.textBox1);
        Name = "Drag/Drop any file on to the TextBox";
        ClientSize = new System.Drawing.Size(867, 523);
    }

    private void textBox1_DragOver(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
            e.Effect = DragDropEffects.Copy;
        else
            e.Effect = DragDropEffects.None;
    }

    private void textBox1_DragDrop(object sender, DragEventArgs e)
    {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        if (files != null && files.Length != 0)
        {
            TextExtractionResult textExtractionResult = _textExtractor.Extract(files[0]);
            textBox1.Text = textExtractionResult.Text;
        }
    }
}

编辑:原博客页面已移至但没有302 perm重定向http://clarify.dovetailsoftware.com/kmiller/2010/07/02/using-the-tika-java-library-in-your-net-application-with-ikvm/