使用Java将大于2GB的文件读入内存

由于ByteArrayInputStream限制为2GB,是否有任何替代解决方案允许我将2.3GB(可能更大)文件的全部内容存储到一个由Stax2读取的InputStream中?

当前代码:

  XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(in); //ByteArrayInputStream???? try { SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = factory.newSchema(new StreamSource(schemaInputStream)); Validator validator = schema.newValidator(); validator.validate(new StAXSource(xmlStreamReader)); } finally { xmlStreamReader.close(); } 

对于性能调优,变量in不得来自磁盘。 我有很多 RAM。

使用NIO将文件读入一个巨大的ByteBuffer,然后创建一个读取ByteBuffer的流类。 在开源中有几个这样的浮动。

StAX2的重点在于您无需将文件读入内存。 您可以只提供源,并让StAX StreamReader根据需要提取数据。

您没有在问题中显示哪些额外限制?

如果你有很多内存,并且想要获得良好的性能,只需用大字节缓冲区包装你的InputStream,让缓冲区为你做缓冲:

 // 4 meg buffer on the stream InputStream buffered = new BufferedInputStream(schemaInputStream, 1024 * 1024 * 4); 

在Java中解决这个问题的另一种方法是创建一个RAMDisk,并在其上存储文件,这将从Java中解决问题,其中你的基本限制是你只能在一个数组中只有少于Integer.MAX_VALUE值。

如果你有大量的内存,你真的不会得到任何性能提升。 它只能以任何一种方式读入,并且磁盘缓存将确保它以最佳方式完成。 只需使用基于磁盘的输入流。

你可以使用内存写入压缩的数据

 ByteArrayOutputStream baos = new ByteArrayOutputStream ... new GZIPOutputStream(baos)); byte[] bytes = baos.toByteArray(); // < 100 MB? ByteArrayInputStream .... 

然后将输入流包装在GZIPInputStream中。

仍然是一个轻微的减速,但应该是XML的理想选择。