2012-11-05 14 views
5

Ich verwende IKVM, um einige Java-Bibliotheken in mein C# -Projekt zu portieren. Die Bibliothek api (StanfordNLP) erfordert, dass eine Datei geladen wird, um die von den nlp-Funktionen verwendeten statistischen Modelle zu trainieren. Das Laden der Datei aus dem Dateisystem hat wochenlang gut funktioniert, aber ich möchte jetzt die Datei als eingebettete Ressource in einer DLL hinzufügen, anstatt sie aus dem Dateisystem abzurufen.Wie greife ich auf eine .net-Ressource für eine IKVM-portierte Java-Bibliothek zu

Das Problem ist, dass die Java API die eingebettete .net-Ressource nicht findet.

Hier ist ein Ausschnitt aus Code, der eine Datei aus dem Dateisystem funktioniert, wenn das Abrufen:

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

Aber wenn ich die „englishPCFG.ser.gz“ mache eine eingebettete Ressource in Visual Studio-Datei (VS2012 mit

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

das Input Objekt, Modelldatei wird immer null zurückgegeben:), und den Code entsprechen ändern. Ich habe verschiedene Formen der Ressource-Zeichenfolge versucht, die ersten beiden Punkte (".") Durch Schrägstrich ("/"), umgekehrten Schrägstrich ("\") und doppelten umgekehrten Schrägstrich ("\\") ersetzt. Ich beginne zu vermuten, dass java.io nicht auf die .net-Ressource zugreifen kann. Es wäre nicht überraschend, dass die Java-API die .net-Ressourcen nicht erkennt, aber ich dachte, IKVM könnte eine Brücke bieten. Ich habe einen Verweis auf etwas namens IKVM.Internals.VirtualFileSystem gesehen, aber nur die eine Referenz (http://old.nabble.com/Manual-by-name-embedded-resource-lookup--td31162421.html) und den Port ' t habe alle IKVM-DLLs gefunden, die tatsächlich die Klasse enthalten.

Jede Hilfe würde sehr geschätzt werden. Ich verwende:

C# .NET 4.5

Visual Studio 2012

Neueste Stanford NLP Java-Bibliotheken

IKVM 7.0.4335.0

Antwort

3

Es gibt keine automatische Unterstützung für diese in IKVM, aber es ist wirklich einfach, es selbst zu tun:

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

Danke für die Hilfe Jeroen! Ich habe es gerade ausprobiert; Die ersten drei Schritte scheinen erfolgreich ausgeführt zu werden, aber der vierte löst eine Ausnahme aus: "Ungültiger Stream-Header: 1F8B0800" – user1800804

+0

Die Ausnahme wurde behoben. Die geladene Datei hatte kein Format, das mit dem von ObjectOutputStream erzeugten Format übereinstimmt. Danke nochmal, Jeroen. – user1800804

0

Die hallo Die richtige Lösung befindet sich in der Erweiterung der Datei, die Sie einbetten.

Wenn es schlicht serialisierten Java-Objekt (wie english-left3words-distsim.tagger) Sie es wie diese laden kann

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) 

aber wenn Ihr Modell Erweiterung hat .gz dies, dass die Datei bedeuten, gzip, und Sie haben Eingangsstrom wickeln in java.util.zip.GZIPInputStream vor Deserialisierung

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)