处理超大的 json 文件。返回总是内存不足

Posted

技术标签:

【中文标题】处理超大的 json 文件。返回总是内存不足【英文标题】:Working with extra large json files. Return always out of memory 【发布时间】:2013-02-12 10:11:37 【问题描述】:

如何将流 API json 与 jackson 一起使用?请参阅下面的代码:

    ObjectMapper mapper = new ObjectMapper();

    Map<String, Object> map = new HashMap<String, Object>();

    List<Object> list = new ArrayList<Object>();

    // Get images in database
    try 
            Class.forName(DRIVER);
            connection = DriverManager.getConnection(URL, USER, PASSWORD);

            Statement s = connection.createStatement();
            ResultSet r = s.executeQuery("select * from images");

            while (r.next()) 

                byte[] imageBytes = r.getBytes("image");
                String imageBase64 = DatatypeConverter.printBase64Binary(imageBytes);
                list.add(imageBase64);
            

     catch (SQLException e) 

    

    map.put("images", list);

    // Stream Json API
    try 
            mapper.writeValue(new File("c:\\images.json"), map);
     catch (JsonGenerationException e) 
            e.printStackTrace();
     catch (JsonMappingException e) 
            e.printStackTrace();
     catch (IOException e) 
            e.printStackTrace();
    

总是返回内存不足。我不知道将流与杰克逊一起使用。我使用超大 json,平均 2000 张图像,每个图像都有一个 imageBase64。我做错了什么?

【问题讨论】:

Here's an example @SotiriosDelimanolis 非常好,非常感谢。解决内存不足的问题。现在,如何显示生成的 json? 你可以通过一些 InputStream 读取文件,把它塞进一个字符串,然后打印出来。 @SotiriosDelimanolis 好!谢谢。 @SotiriosDelimanolis 当我阅读 json 文件时同样的问题。天哪,我疯了.. 【参考方案1】:

不是将所有图像都保存在内存中,而是以增量方式读取和写入它们。 可以在 here(“读写事件流”)中找到 Jackson Streaming API 的示例。

编辑:这应该很难弄清楚人们......但这是一个简单的例子:

// typed from memory, some methods may be off a bit
JsonFactory f = objectMapper.getFactory();
JsonGenerator gen = f.createGenerator(new File("c:\\images.json"));
gen.writeStartArray(); // to get array of objects
// get the DB connection etc
while (r.next()) 
  gen.writeFieldName("image");
  InputStream in = r.getBinaryStream("image");
  gen.writeBinary(in, -1); // length optional for JSON
  in.close();

   gen.writeEndArray(); // 获取对象数组 gen.close();

这应该可以解决问题。

【讨论】:

同样的问题。无法使用 base64 生成 json,因为文件很大。没门。如何为数据库中的每个图像生成一个 url?有什么想法吗? 一样什么?当您以增量方式读取和写入内容时,它们不会存储在内存中 - 您显然会写入文件或其他可流式存储。而不是在内存中编码 Base64,也可以增量写入,只要二进制数据可以使用InputStream 访问。至于 URL,那是另一个问题,超出了 JSON 数据绑定的范围。但实际上,与其问问题,不如试着理解我指出的例子,看看为什么会有所作为。 谢谢,我可以生成images.json,没问题,但是读取images.json是不可能的,文件很大。资源有限的移动应用程序没有办法。现在,为每个图像生成一个 URL,解决我的问题。 为什么阅读会有问题?也可以使用流式 API,使用JsonParser 反向读取数据。我会让你弄清楚那个。

以上是关于处理超大的 json 文件。返回总是内存不足的主要内容,如果未能解决你的问题,请参考以下文章

如何增加内存来处理超大 Lua 表

手机内存总是提示不足的解决方法

Linux乐观malloc:内存不足时new总是会抛出吗?

电脑总是显示内存不足,怎么解决

java总是提示内存不足

Karma 单元测试 webpack:进程内存不足后返回的 API 致命错误处理程序