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

在进行任何进一步处理之前,我需要确保用户提供的文件在包含文本时转换为.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,或者它是否可以转换,这样做。

根据LB的建议,我将转发这一点 。

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

这可能听起来很恐怖和异端,但您是否知道可以利用来自.Net应用程序的Java库而没有TCP套接字或Web服务陷入交火? 让我向您介绍IKVM,这是坦率的魔术:

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

  • 用.NET实现的Java虚拟机
  • Java类库的.NET实现
  • 支持Java和.NET互操作性的工具

使用IKVM,我们能够成功地将我们的Dovetail Seeker搜索应用程序与用Java实现的Tika文本提取库集成。 使用Tika,我们可以轻松地从许多支持的格式中提取丰富文档中的文本。 为什么Tika? 因为在.Net世界中没有任何可比的Tika。

这篇文章将回顾我们如何与Tika整合。 如果您喜欢代码,可以在Github上的repo中找到这个例子 。

将Jar编译成程序集

首先,我们需要掌握最新版本的Tika。 我按照指示使用Maven下载并构建了Tika 源 。 结果是一些jar文件。 我们感兴趣的是tika-app-xxjar,它将我们需要的所有内容捆绑到一个有用的容器中。

接下来我们需要将我们构建的jar转换为.Net程序集。 使用ikvmc.exe执行此操作。

 tika\build>ikvmc.exe -target:library tika-app-0.7.jar 

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

使用Tika From .Net

IKVM非常透明。 您只需引用Tika app程序集,并且您的.Net代码与Java类型对话。 一开始有点奇怪,因为你有Java版本的类型和.Net版本。 接下来,您需要确保项目中包含所有从属IKVM运行时程序集。 使用Reflector我发现Tika app程序集引用了许多似乎没有使用的IKVM程序集。 我必须通过反复试验来弄清楚哪些组件没有被富文档提取所触及。 如果需要,您可以简单地将所有引用的IKVM程序集包含在您的应用程序中。 下面我已经为您完成了工作,并删除了对所有看似正在运行的IKVM程序集的所有引用。

在此处输入图像描述

16个组件低至5.部署小得多。

使用Tika

为了做一些文本提取,我们会非常好地问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找到ClassLoader的位置。

       

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

演示

这是一个测试,展示了提取和结果。

 [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 Metadata { get; set; } //toString() override } 

以下是Tika的原始输出:

在此处输入图像描述

结论

我希望这有助于增强您对.Net代码中使用Java库的信心,如果您需要在.Net平台上与Tika合作,我希望我的示例repo会有所帮助。 请享用。


设置此信息的信息:

使用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烫发重定向http://clarify.dovetailsoftware.com/kmiller/2010/07/02/using-the-tika-java-library-in-your-net-应用与- IKVM /