
我想知道是否存在使用Jackson解析JSON文件的“正确”方法,其中JSON文件包含一个巨大的属性,而无需将整个流加载到内存中.我需要保持较低的内存,因为它是Android应用程序.我不是在这里问如何Android: Parsing large JSON file,而是一个属性确实很大而其他属性都没有关系.
例如,假设我有以下内容:
{ "filename": "afilename.jpg", "data": "**Huge data here, about 20Mb base64 string**", "mime": "mimeType", "otherPropertIEs": "..."}如果需要,可以将data属性提取到一个新文件中(通过outputstream或其他含义),但是我无法使用Jackson来实现.可以使用其他库,我只是以为杰克逊的流API可以使它成为理想的库.
谢谢
解决方法:
最终,我设法恢复了如此庞大的数据,其中,在Json文件上有一个输入流,我想从中解析数据,然后是要将数据写入其中的文件:
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()
以上是内存溢出为你收集整理的Android:解析具有较大属性且内存使用率较低的JSON文件全部内容,希望文章能够帮你解决Android:解析具有较大属性且内存使用率较低的JSON文件所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)