2012-11-05 12 views
5

IKVMを使用して、いくつかのJavaライブラリをC#プロジェクトに移植しています。ライブラリapi(StanfordNLP)では、nlp関数で使用される統計モデルを学習するためにファイルをロードする必要があります。ファイルシステムからのファイルのロードは数週間はうまくいっていますが、ファイルシステムから取得するのではなく、dllの埋め込みリソースとしてファイルを追加したいと考えています。IKVMポートのJavaライブラリの.netリソースにアクセスするには

問題は、Java APIが.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」はVS2012を使用して(Visual Studioで埋め込みリソースファイル作ります)と一致するようにコードを変更します。

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)実際にクラスを含むIKVM dllが見つかりませんでした。

ご協力いただければ幸いです。私が使用しています:

C#.NETの4.5

のVisual Studio 2012

最新スタンフォードNLPのJavaライブラリ

IKVM 7.0.4335.0

答えて

3

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); 
+0

助けてくれてありがとうJeroen!私はちょうどそれを試しました。最初の3つのステップは正常に実行されたように見えますが、4番目の例外は「無効なストリームヘッダー:1F8B0800」です。 – user1800804

+0

例外が解決されました。ロードされるファイルは、ObjectOutputStreamによって生成されたものと一致する形式ではありません。再度ありがとう、ジェーレン。 – user1800804

0

こんにちは正しいソリューションへのntは、あなたが埋め込んだファイルの拡張子の中にあります。

それはプレーンな直列化された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を持っている場合、このファイルはgzip圧縮されていることを意味し、あなたに入力ストリームをラップする必要があり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) 
関連する問題