【问题标题】:Reading gzipped XML in scala在scala中读取gzip压缩的XML
【发布时间】:2016-08-16 19:32:30
【问题描述】:

当我尝试将 xml.gz 文件读入 Scala 时,收到以下错误:

com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(UTF8Reader.java:701)
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(UTF8Reader.java:567)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1896)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1761)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1799)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:156)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
at scala.xml.factory.XMLLoader$class.loadXML(XMLLoader.scala:41)
at scala.xml.XML$.loadXML(XML.scala:60)
at scala.xml.factory.XMLLoader$class.loadFile(XMLLoader.scala:50)
at scala.xml.X

我有以下代码:

import scala.xml.XML 
val xml = XML.loadFile("/home/vagrant/miniprojects/spark/allVotes/part-00380.xml.gz") 

我有 2,000 多个 xml.gz 文件要读入。什么是有效的解决方案?非常感谢!!

【问题讨论】:

  • 以尽可能完整且可测试的最小形式展示您的工作(您如何进行解析,尤其是您如何进行 gzip 解压缩)将是一个开始的地方。见stackoverflow.com/help/mcve
  • ...那么,你根本没有在做 gzip 解压缩。不能像读取 XML 文件一样读取 gzip 文件,这有什么奇怪的?
  • 感谢您的提醒。当我对文件进行压缩时,它占用了太多内存......
  • ...如果您需要对一组组合的 XML 文档运行查询,这些文档需要的 RAM 比您可以存储的更多,请考虑为此目的使用 XQuery 数据库。 (忽略当您说“内存”时实际上是指磁盘存储时)。如果您无法将解压缩的文本存储在 RAM 中,那么您也没有足够的内存来存储从该文本构建的 DOM。

标签: xml scala


【解决方案1】:

.xml.gz 在外层不是 XML —— 它是 gzip。在读取时使用 GZIPInputStream 对其进行解压缩:

import java.io.FileInputStream
import java.util.zip.GZIPInputStream
import scala.xml.XML

def loadXmlGz(filename : String) = {
  XML.load(new GZIPInputStream(new FileInputStream(new java.io.File(filename))))
}

var xml = loadXmlGz("/home/vagrant/miniprojects/spark/allVotes/part-00380.xml.gz")

【讨论】:

  • 非常感谢。这很有帮助。
  • 谢谢,但我对此很幼稚。当我使用此代码时,我仍然通过仅导入一个 .xml.gz 文件收到内存错误。 scala> var xml = loadXmlGz("/home/vagrant/miniprojects/spark/allVotes/part-00000.xml.gz") java.lang.OutOfMemoryError: GC overhead limit exceeded
  • 如果您没有足够的内存来存储 XML 文档的 DOM 结构,您将需要给您的 JVM 更多内存——或者重写您的代码以不使用基于 DOM 的模型。请参阅stackoverflow.com/questions/13184212/… 了解如何完成此操作的示例。
  • 开箱即用,顺便说一句,当我在命令行运行scala-2.11 时,我让它在具有 256MB 堆限制的 JVM 中运行。这不是很大的净空。如果你没有设置自定义JAVA_OPTS,你可能应该这样做。
  • ...不过,除此之外,内存限制问题可能应该是另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 2010-11-14
  • 1970-01-01
  • 2011-07-06
  • 2014-07-04
  • 2015-07-14
  • 1970-01-01
相关资源
最近更新 更多