V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
andybest
V2EX  ›  问与答

对于某些丧心病狂提供了上百兆 XML 文件的 API 要怎么破?

  •  
  •   andybest · 2014-07-21 15:18:34 +08:00 · 4147 次点击
    这是一个创建于 3780 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如: http://www.meituan.com/api/v2/beijing/deals (只是例子,有比这个大很多的)

    每次读取服务器妥妥 OutOfMemoryError,除了分配给服务器更多的可用内存(土豪就没这个问题了)
    在服务器可用内存低于这个 XML 文件大小时,如何正常处理这个 API ?
    26 条回复    2014-07-22 10:16:34 +08:00
    Livid
        1
    Livid  
    MOD
       2014-07-21 15:31:07 +08:00 via iPhone
    没有提供分页参数么?
    izoabr
        2
    izoabr  
       2014-07-21 15:42:01 +08:00
    @julyclyde 你觉得这个问题怎么办?
    yorkw
        3
    yorkw  
       2014-07-21 15:47:13 +08:00   ❤️ 1
    tabris17
        4
    tabris17  
       2014-07-21 15:50:21 +08:00
    自己写一个XMLParser
    keithellis
        5
    keithellis  
       2014-07-21 16:03:45 +08:00   ❤️ 2
    SAX parser
    feiyuanqiu
        6
    feiyuanqiu  
       2014-07-21 16:08:31 +08:00   ❤️ 1
    PHP的话,可以用XMLReader这个扩展,它是按照文件流的方式每次按照节点来读取,读完一个节点再读下一个,不会把文件整个载入内存,php5.1以上都是自带了的,直接可以用。
    andybest
        7
    andybest  
    OP
       2014-07-21 16:20:19 +08:00
    @keithellis SAX (Simple API for XML) parser 不是在初始化的时候一次将XML全部装入内存的吗?如何能解决这个问题呢?
    chmlai
        8
    chmlai  
       2014-07-21 16:22:29 +08:00   ❤️ 1
    @andybest SAX 不需要, DOM 才是
    andybest
        9
    andybest  
    OP
       2014-07-21 16:25:40 +08:00
    @chmlai 谢谢,SAX 是 streaming 的读取模式吗?
    keithellis
        10
    keithellis  
       2014-07-21 16:26:13 +08:00   ❤️ 2
    bigredapple
        11
    bigredapple  
       2014-07-21 16:28:39 +08:00   ❤️ 1
    SAX
    andybest
        12
    andybest  
    OP
       2014-07-21 16:28:52 +08:00
    @keithellis Very useful !收藏了,十分感谢!
    kaneg
        13
    kaneg  
       2014-07-21 16:32:08 +08:00   ❤️ 1
    如果你使用Java,基于事件的流式处理方式应该更适合你。示例代码:
    try {
    URL url = new URL("http://www.meituan.com/api/v2/beijing/deals");
    URLConnection connection = url.openConnection();
    connection.setConnectTimeout(5000);
    connection.setReadTimeout(60000);
    InputStream is = connection.getInputStream();
    try {
    XMLInputFactory factory = XMLInputFactory.newInstance();
    XMLEventReader xmlEventReader = factory.createXMLEventReader(new BufferedInputStream(is));
    while (xmlEventReader.hasNext()) {
    XMLEvent xmlEvent = xmlEventReader.nextEvent();

    if (xmlEvent.isStartElement()) {
    StartElement startElement = xmlEvent.asStartElement();
    System.out.println(startElement.getName().getLocalPart());
    }
    }
    } catch (Exception e) {
    System.err.println(e.getMessage());
    }
    } catch (IOException e) {
    System.err.println(e.getMessage());
    }
    xujialiang
        14
    xujialiang  
       2014-07-21 16:46:29 +08:00
    IOS中,document方式会一次把xml全部读进内存的。
    Zhang
        15
    Zhang  
       2014-07-21 16:52:25 +08:00
    加载完了,浏览器耗了4.42GB内存
    andybest
        16
    andybest  
    OP
       2014-07-21 16:53:56 +08:00
    @Zhang 用什么方式加载的?
    fanghui
        17
    fanghui  
       2014-07-21 17:17:07 +08:00
    笨方法:下载--保存文件--分文件--解析文件---
    Zhang
        18
    Zhang  
       2014-07-21 17:22:31 +08:00
    @andybest safari呀
    ChiChou
        19
    ChiChou  
       2014-07-21 17:47:54 +08:00
    @fanghui 分文件就破坏了 XML 的合法性。
    ChiChou
        20
    ChiChou  
       2014-07-21 17:48:04 +08:00
    pull 比较适合这个场景。
    binjoo
        21
    binjoo  
       2014-07-21 17:57:25 +08:00
    @meituan 我觉得你有必要来看看。。
    yangxiongwei
        22
    yangxiongwei  
       2014-07-21 19:29:02 +08:00   ❤️ 1
    SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
    julyclyde
        23
    julyclyde  
       2014-07-21 20:35:49 +08:00 via iPad
    @izoabr sax啊大家都说了。这些都是历史遗留问题了

    lz做啥的?
    yangxiongwei
        24
    yangxiongwei  
       2014-07-21 21:54:38 +08:00
    @julyclyde lz应该是做“后端开发”的,哈哈
    http://www.v2ex.com/t/123763
    julyclyde
        25
    julyclyde  
       2014-07-21 23:32:04 +08:00 via iPad
    @Livid 没分页不稀罕。我甚至见过每次访问时当成执行生成这文件内容的团购网站呢
    arslion
        26
    arslion  
       2014-07-22 10:16:34 +08:00
    只读的话用SAX呗~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:17 · PVG 21:17 · LAX 05:17 · JFK 08:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.