6

IKVMを使用していくつかのJavaライブラリをC#プロジェクトに移植しています。ライブラリAPI(StanfordNLP)では、nlp関数で使用される統計モデルをトレーニングするためにファイルをロードする必要があります。ファイルシステムからのファイルのロードは何週間もうまく機能しましたが、ファイルシステムからファイルを取得するのではなく、ファイルをdllの埋め込みリソースとして追加したいと思います。

問題は、JavaAPIが.net埋め込みリソースを見つけられないことです。

ファイルシステムからファイルを取得するときに機能するコードのスニペットを次に示します。

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");
   }
}

しかし、「englishPCFG.ser.gz」ファイルをVisual Studioの埋め込みリソース(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を返します。最初の2つのドット( "。")をスラッシュ( "/")、バックスラッシュ( "\")、およびダブルバックスラッシュ( "\\")に置き換えて、さまざまな形式のリソース文字列を試しました。java.ioが.netリソースにアクセスできないのではないかと疑い始めています。Java APIが.netリソースを認識しないのは当然のことですが、IKVMがブリッジを提供する可能性があると思いました。IKVM.Internals.VirtualFileSystemと呼ばれるものへの参照を見たことがありますが、1つの参照(http://old.nabble.com/Manual-by-name-embedded-resource-lookup--td31162421.html)のみであり、実際にクラスを含むIKVMdllが見つかりました。

どんな助けでも大歓迎です。使ってます:

c#.NET 4.5

Visual Studio 2012

最新のStanfordNLPJavaライブラリ

IKVM 7.0.4335.0

4

2 に答える 2

4

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);
于 2012-11-06T07:35:50.387 に答える
1

正しい解決策のヒントは、埋め込んだファイルの拡張子にあります。

プレーンなシリアル化された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)

ただし、モデルに拡張子が付いている場合、これはファイルがgzipで圧縮されていることを意味し、逆シリアル化の前に.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)
于 2017-05-19T03:41:00.583 に答える