【问题标题】:How do I access a .net resource for an IKVM-ported java library如何访问 IKVM 移植的 Java 库的 .net 资源
【发布时间】:2012-11-05 17:46:31
【问题描述】:

我正在使用 IKVM 将一些 java 库移植到我的 c# 项目中。库 api (StanfordNLP) 要求加载一个文件来训练 nlp 函数使用的统计模型。从文件系统加载文件已经运行了好几个星期,但我现在想将文件作为嵌入资源添加到 dll 中,而不是从文件系统中检索它。

问题是java api没有找到.net嵌入资源。

这是从文件系统检索文件时起作用的代码的 sn-p:

public class SNLPModel
{
   public LexicalizedParser LP;

   public SNLPModel()
   {
      // Using a relative file path in the target build directory
      LP = LexicalizedParser.loadModel("models-stanford\\englishPCFG.ser.gz");
   }
}

但是当我在 Visual Studio 中将“englishPCFG.ser.gz”文件作为嵌入式资源(使用 VS2012)并更改代码以匹配时:

public class SNLPModel
{
   public LexicalizedParser LP;

   public SNLPModel()
   {
        // Using this line of code to verify that the file is being loaded as
        // an embedded resource. Running in debug, I have verified that it is, and
        // noted its complete name.
        string[] s = System.Reflection.Assembly.GetExecutingAssembly()
                        .GetManifestResourceNames();

        java.io.InputStream modelFile = java.lang.ClassLoader
              .getSystemResourceAsStream
              ("FeatureExtraction.StanfordNLP_Models.englishPCFG.ser.gz");

        java.io.ObjectInputStream x = new java.io.ObjectInputStream(modelFile);

        LP = LexicalizedParser.loadModel(x);
   }
}

InputStream 对象 modelFile 始终返回 null。我尝试了各种形式的资源字符串,将前两个点(“.”)替换为正斜杠(“/”)、反斜杠(“\”)和双反斜杠(“\\”)。我开始怀疑 java.io 无法访问 .net 资源。 java api 不能识别 .net 资源也就不足为奇了,但我认为 IKVM 可能会提供一个桥梁。我看到了对名为 IKVM.Internals.VirtualFileSystem 的引用,但只有一个引用 (http://old.nabble.com/Manual-by-name-embedded-resource-lookup--td31162421.html) 并且没有没有找到任何实际包含该类的 IKVM dll。

任何帮助将不胜感激。我正在使用:

c#.NET 4.5

Visual Studio 2012

最新的斯坦福 NLP java 库

IKVM 7.0.4335.0

【问题讨论】:

    标签: c# visual-studio-2012 ikvm


    【解决方案1】:

    IKVM 没有自动支持这个,但是自己做真的很容易:

    var asm = Assembly.GetExecutingAssembly();
    var stream = asm.GetManifestResourceStream("FeatureExtraction.StanfordNLP_Models.englishPCFG.ser.gz");
    var inp = new ikvm.io.InputStreamWrapper(stream);
    var x = new java.io.ObjectInputStream(inp);
    

    【讨论】:

    • 感谢杰罗恩的帮助!我刚试了一下;前三步看似执行成功,但第四步抛出异常:“invalid stream header: 1F8B0800”
    • 解决了异常。正在加载的文件的格式与 ObjectOutputStream 生成的格式不一致。再次感谢 Jeroen。
    【解决方案2】:

    正确解决方案的提示在您嵌入的文件的扩展名中。

    如果是普通的序列化 java 对象(如english-left3words-distsim.tagger),你可以像这样加载它

    let model = "../english-left3words-distsim.tagger"
    use fs = new FileStream(model, FileMode.Open)
    use isw = new ikvm.io.InputStreamWrapper(fs)
    let tagger = edu.stanford.nlp.tagger.maxent.MaxentTagger(isw)
    

    但如果你的模型有扩展名.gz,这意味着文件被压缩了,你必须在反序列化之前将输入流包装到java.util.zip.GZIPInputStream

    let model = "../englishRNN.ser.gz"
    use fs = new FileStream(model, FileMode.Open)
    use isw = new ikvm.io.InputStreamWrapper(fs)
    
    use ois =
        if model.EndsWith(".gz")
        then
            let gzs = new java.util.zip.GZIPInputStream(isw)
            new java.io.ObjectInputStream(gzs)
        else new java.io.ObjectInputStream(isw)
    let lp = edu.stanford.nlp.parser.lexparser.LexicalizedParser.loadModel(ois)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-11
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 2014-06-02
      • 2016-04-09
      相关资源
      最近更新 更多