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

时间:2014-10-01 11:11:11

标签: java io

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

当前代码:

            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。

4 个答案:

答案 0 :(得分:5)

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

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

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

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

如果您拥有大量内存,那么无论如何您都无法获得任何性能提升。它只能以任何一种方式读入,并且磁盘缓存将确保它以最佳方式完成。只需使用基于磁盘的输入流。

答案 3 :(得分:-1)

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

ByteArrayOutputStream baos = new ByteArrayOutputStream
... new GZIPOutputStream(baos));

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

ByteArrayInputStream ....

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

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