最後に、私はこのような巨大なデータを回復することができました。ここでin
、データを解析したいjsonファイルの入力ストリームでありout
、データを書き込むファイルです:
public boolean extrationContenuDocument(FileInputStream in, FileOutputStream out, FileInfo info)
throws JsonParseException, IOException {
SerializedString keyDocContent = new SerializedString("data");
boolean isDone = false;
JsonParser jp = this.jsonFactory.createJsonParser(in);
// Let's move our inputstream cursor until the 'data' property is found
while (!jp.nextFieldName(keyDocContent)) {
Log.v("Traitement JSON", "Searching for 'data' property ...");
}
// Found it? Ok, move the inputstream cursor until the begining of it's
// content
JsonToken current = jp.nextToken();
// if the current token is not String value it means u didn't found the
// 'data' property or it's content is not a correct => stop
if (current == JsonToken.VALUE_STRING) {
Log.v("Traitement JSON", "Property 'data' found");
// Here it gets a little tricky cause if the file is not big enough
// all the content of the 'data' property could be read directly
// insted of using this
if (info.getSize() > TAILLE_MIN_PETIT_FICHER) {
Log.v("Traitement JSON", "the content of 'data' is too big to be read directly -> using buffered reading");
// JsonParser uses a buffer to read, there is some data that
// could have been read by it, i need to fetch it
ByteArrayOutputStream debutDocStream = new ByteArrayOutputStream();
int premierePartieRead = jp.releaseBuffered(debutDocStream);
byte[] debutDoc = debutDocStream.toByteArray();
// Write the head of the content of the 'data' property, this is
// actually what as read from the inputstream by the JsonParser
// when did jp.nextToken()
Log.v("Traitement JSON", "Write the head");
out.write(debutDoc);
// Now we need to write the rest until we find the tail of the
// content of the 'data' property
Log.v("Traitement JSON", "Write the middle");
// So i prepare a buffer to continue reading the inputstream
byte[] buffer = new byte[TAILLE_BUFFER_GROS_FICHER];
// The escape char that determines where to stop reading will be "
byte endChar = (byte) '"';
// Fetch me some bytes from the inputstream
int bytesRead = in.read(buffer);
int bytesBeforeEndChar = 0;
int deuxiemePartieRead = 0;
boolean isDocContentFin = false;
// Are we at the end of the 'data' property? Keep writing the
// content of the 'data' property if it's not the case
while ((bytesRead > 0) && !isDocContentFin) {
bytesBeforeEndChar = 0;
// Since am using a buffer the escape char could be in the
// middle of it, gotta look if it is
for (byte b : buffer) {
if (b != endChar) {
bytesBeforeEndChar++;
} else {
isDocContentFin = true;
break;
}
}
if (bytesRead > bytesBeforeEndChar) {
Log.v("Traitement JSON", "Write the tail");
out.write(buffer, 0, bytesBeforeEndChar);
deuxiemePartieRead += bytesBeforeEndChar;
} else {
out.write(buffer, 0, bytesRead);
deuxiemePartieRead += bytesRead;
}
bytesRead = in.read(buffer);
}
Log.v("Traitement JSON", "Bytes read: " + (premierePartieRead + deuxiemePartieRead) + " (" + premierePartieRead + " head,"
+ deuxiemePartieRead + " tail)");
isDone = true;
} else {
Log.v("Traitement JSON", "File is small enough to be read directly");
String contenuFichier = jp.getText();
out.write(contenuFichier.getBytes());
isDone = true;
}
} else {
throw new JsonParseException("The property " + keyDocContent.getValue() + " couldn't be found in the Json Stream.", null);
}
jp.close();
return isDone;
}
それはきれいではありませんが、魅力のように機能します! @staxman ご意見をお聞かせください。
編集 :
これは現在実装されている機能です。https ://github.com/FasterXML/jackson-core/issues/14
およびJsonParser.readBinaryValue()を参照してください。