对于某些丧心病狂提供了上百兆 XML 文件的 API 要怎么破? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
andybest
V2EX    问与答

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

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

    每次读取服务器妥妥 OutOfMemoryError,除了分配给服务器更多的可用内存(土豪就没这个问题了)
    在服务器可用内存低于这个 XML 文件大小时,如何正常处理这个 API ?
    26 条回复    2014-07-22 10:16:34 +08:00
    Livid
        1
    Livid  
    MOD
    PRO
       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     Solana     5391 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:03 PVG 17:03 LAX 02:03 JFK 05:03
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86