Apache OpenNLP에서 음성 인식 태그를 사용하려면 ~ 5MB 바이너리 파일을 읽어야하는 Android 앱을 만듭니다. 필자는 ByteBuffer와 사용자 정의 ByteBufferInputStream 클래스를 사용하여 파일을 빠르게 읽을 수있는 경로를 시도했습니다. 나는 그것을 정확하게하고 있다고 생각했지만, 메소드에 의해 리턴 된 POSModel을 체크했을 때 'null'이되었다. 일어날 일은 ByteBuffer가 바이너리 파일에서 정보를 읽고 그 정보를 POSModel 생성자에 대한 InputStream으로 제공한다는 것입니다. 여기 바이너리 파일 내용을 빠르게 읽는 빠른 방법이 제대로 작동하지 않습니다.
바이너리 파일에서 음성 모델의 부분을 얻기에 대한 코드입니다 :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;
}
을 그리고 여기 또 다른 스택 오버플로 질문에서 얻은 ByteBufferInputStream에 대한 코드입니다 :
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();
}
}
이제 최종 목표는 가능한 한 빨리 "en_pos_maxent"바이너리 파일을 읽는 것입니다 (현재 일반 InputStream을 사용하면 약 20 초 걸립니다). 따라서 내 원형 파일보다 파일 내용을 빨리 얻는 방법이 더 좋습니다. ByteBuffer를 사용하여 th 다른 방법으로도 작동 할 수 있습니다.
업데이트 :
다음 방법에 의해 던져진 예외 스택 추적 : 당신이 POSModel
초기화에 의해 던져진 예외에 대해 더 자세히 들어가없이
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)
'POSModel' 초기화가 IOException을 던집니까? 스택 트레이스를 공유 할 수 있습니까? – oldrinb
ByteArray를 호출 할 때 이미 전체 스트림을 배열에 복사했습니다. – lionscribe
'ByteBufferInputStream'과'ByteBuffer'와 바이트 배열을 없애고 원래의 스트림을'POSModel'의 생성자에 직접 넘겨줍니다. 빠르지 않으면'BufferedInputStream'으로 랩핑하십시오. 이 모든 여분의 헛소리는 시간과 공간을 낭비하고 버그를 가져 오는 것입니다. – EJP