Ich erstelle eine Android-App, die eine ~ 5 mb binäre Datei lesen muss, um den Teil der Rede-Tagger von Apache OpenNLP zu verwenden. Ich versuchte eine ziemlich umständliche Route, um die Datei schnell zu lesen, mit einem ByteBuffer und einer benutzerdefinierten ByteBufferInputStream-Klasse. Ich dachte, dass ich es richtig mache, aber als ich das POSModel überprüfte, das von der Methode zurückgegeben wird, stellt es sich als "Null" heraus. Was passieren soll, ist, dass ein ByteBuffer die Informationen aus der Binärdatei liest und diese dann als InputStream dem POSModel-Konstruktor gibt.Schnelle Methode zum Lesen von binären Datei Inhalt funktioniert nicht richtig
Hier ist der Code für den Teil des Sprachmodells aus der Binärdatei bekommen:
public POSModel setupPOSModel() {
ByteBufferInputStream modelIn = null;
POSModel model = null;
try {
InputStream stream = getResources().openRawResource(R.raw.en_pos_maxent);
byte[] b = IOUtils.toByteArray(stream);
ByteBuffer buf = ByteBuffer.wrap(b);
modelIn = new ByteBufferInputStream(buf);
model = new POSModel(modelIn);
} catch (IOException e) {
// Model loading failed, handle the error
e.printStackTrace();
} finally {
if (modelIn != null) {
try {
modelIn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//at this point 'model' is null
System.out.println("POS MODEL: " + model);
return model;
}
Und hier ist der Code für die ByteBufferInputStream, die ich von einem anderen Stack-Überlauf Frage kam:
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
public class ByteBufferInputStream extends InputStream {
private int bbisInitPos;
private int bbisLimit;
private ByteBuffer bbisBuffer;
public ByteBufferInputStream(ByteBuffer buffer) {
this(buffer, buffer.limit() - buffer.position());
}
public ByteBufferInputStream(ByteBuffer buffer, int limit) {
bbisBuffer = buffer;
bbisLimit = limit;
bbisInitPos = bbisBuffer.position();
}
@Override
public int read() throws IOException {
if (bbisBuffer.position() - bbisInitPos > bbisLimit)
return -1;
return bbisBuffer.get();
}
}
Nun, mein Endziel ist einfach, "en_pos_maxent" Binärdatei so schnell wie möglich zu lesen (derzeit, mit einem regulären InputStream, dauert es etwa 20 Sekunden), wenn es also einen besseren Weg als meine Umweg, um den Inhalt der Datei schnell zu bekommen mit einem ByteBuffer dann th bei alternativer Methode könnte auch funktionieren.
Update:
Hier ist der Stack-Trace für die nach der Methode geworfen Ausnahme:
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: java.util.zip.ZipException: CRC mismatch
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at java.util.zip.ZipInputStream.readAndVerifyDataDescriptor(ZipInputStream.java:215)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:164)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at opennlp.tools.util.model.BaseModel.loadModel(BaseModel.java:245)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at opennlp.tools.util.model.BaseModel.<init>(BaseModel.java:179)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at opennlp.tools.postag.POSModel.<init>(POSModel.java:105)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at com.newssummary.MainActivity$override.setupPOSModel(MainActivity.java:245)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at com.newssummary.MainActivity$override.access$dispatch(MainActivity.java)
08-08 14:59:38.220 2735-3351/com.newssummary W/System.err: at com.newssummary.MainActivity.setupPOSModel(MainActivity.java:0)
08-08 14:59:38.221 2735-3351/com.newssummary W/System.err: at com.newssummary.MainActivity$4.doAsync(MainActivity.java:190)
08-08 14:59:38.221 2735-3351/com.newssummary W/System.err: at com.newssummary.MainActivity$4.doAsync(MainActivity.java:182)
08-08 14:59:38.221 2735-3351/com.newssummary W/System.err: at com.arasthel.asyncjob.AsyncJob$4.run(AsyncJob.java:91)
08-08 14:59:38.221 2735-3351/com.newssummary W/System.err: at java.lang.Thread.run(Thread.java:818)
wirft die 'POSModel'-Initialisierung eine' IOException'? Können Sie die Stack-Trace teilen? – oldrinb
Wenn Sie toByteArray aufrufen, haben Sie bereits den gesamten Stream in ein Array kopiert. – lionscribe
Löschen Sie den 'ByteBufferInputStream' und den' ByteBuffer' sowie das Byte-Array und übergeben Sie den * originalen * Stream direkt an den Konstruktor von 'POSModel'. Wenn es nicht schnell genug ist, wickle es in einen "BufferedInputStream". All diese zusätzlichen Spielereien verschwenden nur Zeit und Raum und führen Bugs ein. – EJP