Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一般读取任何文件格式并将其转换为.txt格式_C#_File_Text_Ikvm - Fatal编程技术网

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

C# 一般读取任何文件格式并将其转换为.txt格式,c#,file,text,ikvm,C#,File,Text,Ikvm,在进一步处理之前,我需要确保用户提供的文件已转换为.txt文件(如果包含文本) 目前,我有一个switch语句检查特定的格式,并将其转换为.txt格式 switch (extension) { case ".pdf": //Convert from .pdf to .txt file break; case ".doc": //Convert from .doc to .txt file break; def

在进一步处理之前,我需要确保用户提供的文件已转换为.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.的建议,我将转世

在带有IKVM的.Net应用程序中使用Tika Java库 这听起来可能很吓人,也很离经叛道,但您知道吗,在没有TCP套接字或web服务的情况下,从.Net应用程序中利用Java库是可能的?让我向您介绍IKVM,它确实很神奇:

IKVM.NET是Java for Mono和Microsoft.NET框架的一个实现。它包括以下组件:

  • 在.NET中实现的Java虚拟机
  • Java类库的.NET实现
  • 支持Java和.NET互操作性的工具
使用IKVM,我们已经能够成功地将我们的燕尾式搜索引擎应用程序与用Java实现的Tika文本提取库集成。使用Tika,我们可以轻松地从多种支持的格式的富文档中提取文本。为什么是提卡?因为在.Net世界里,没有什么比得上Tika

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

将Jar编译成程序集

首先,我们需要得到最新版本的Tika。我下载并制作了Tika。结果是生成了几个jar文件。我们感兴趣的是tika-app-x.x.jar,它将我们需要的所有东西捆绑到一个有用的容器中

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

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

使用.Net中的Tika

IKVM非常透明。您只需引用Tika应用程序集,您的.Net代码就可以与Java类型对话。一开始有点奇怪,因为有Java版本的类型和.Net版本。接下来,您需要确保项目中包含所有依赖的IKVM运行时程序集。使用Reflector,我发现Tika应用程序集引用了许多似乎未使用的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有一个称为类加载器的概念,它与Java类型的查找和加载方式有关。可能有更好的方法解决这个问题,但出于某种原因,如果您不实现自定义类加载器,并且还设置了一个应用程序设置,提示IKVM运行时使用哪个.Net类型作为类加载器

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>
简单地说,像这样的富文档就可以进入了

一个TextExtractionResult出来了:

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

编辑:原始博客页面已移动到,但没有302 perm重定向

遵循L.B的建议,我将转世

在带有IKVM的.Net应用程序中使用Tika Java库 这听起来可能很吓人,也很离经叛道,但您知道吗,在没有TCP套接字或web服务的情况下,从.Net应用程序中利用Java库是可能的?让我向您介绍IKVM,它确实很神奇:

IKVM.NET是Java for Mono和Microsoft.NET框架的一个实现。它包括以下组件:

  • 在.NET中实现的Java虚拟机
  • Java类库的.NET实现
  • 支持Java和.NET互操作性的工具
使用IKVM,我们已经能够成功地将我们的燕尾式搜索引擎应用程序与用Java实现的Tika文本提取库集成。使用Tika,我们可以轻松地从多种支持的格式的富文档中提取文本。为什么是提卡?因为在.Net世界里,没有什么比得上Tika

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

将Jar编译成程序集

首先,我们需要得到最新版本的Tika。我下载并制作了Tika。结果是生成了几个jar文件。我们感兴趣的是tika-app-x.x.jar,它将我们需要的所有东西捆绑到一个有用的容器中

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

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

使用.Net中的Tika

IKVM非常透明。您只需引用Tika应用程序集,您的.Net代码就可以与Java类型对话。一开始有点奇怪,因为有Java版本的类型和.Net版本。下一步你要做的是
[Test]
public void should_extract_from_pdf()
{
var textExtractionResult = new TextExtractor().Extract("Tika.pdf");

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

Console.WriteLine(textExtractionResult);
}
public class TextExtractionResult
{
public string Text { get; set; }
public string ContentType { get; set; }
public IDictionary<string, string> Metadata { get; set; }
//toString() override
}
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;
        }
    }
}