Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中将大于2GB的文件读入内存_Java_Io - Fatal编程技术网

在Java中将大于2GB的文件读入内存

在Java中将大于2GB的文件读入内存,java,io,Java,Io,由于ByteArrayInputStream限制为2GB,是否有其他解决方案允许我将2.3GB(可能更大)文件的全部内容存储到InputStream中,以供Stax2读取 当前代码: XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamRead

由于
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();
            }

对于性能调整,中的变量
不得来自磁盘。我有足够的内存。

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

StAX2的全部要点是,您不需要将文件读入内存。您可以只提供源代码,让StAX StreamReader根据需要提取数据

您还有哪些问题中未显示的其他约束条件

如果您有大量内存,并且希望获得良好的性能,只需使用大字节缓冲区包装您的InputStream,然后让缓冲区为您进行缓冲:

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

在Java中解决这个问题的另一种方法是创建一个RAMDisk,并将文件存储在该磁盘上,这将从Java中消除问题,Java的基本限制是在单个数组中只能有小于
Integer.MAX\u值的值。

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

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

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

ByteArrayInputStream ....
ByteArrayOutputStream=new ByteArrayOutputStream
... 新GZIPOutputStream(baos));
byte[]bytes=baos.toByteArray();//<100MB?
ByteArrayInputStream。。。。
然后将输入流包装到GZIPInputStream中


虽然速度稍慢,但应该是XML的理想选择。

使用NIO将文件读入一个巨大的ByteBuffer,然后创建一个读取ByteBuffer的流类。在开源软件中有很多这样的测试。

我需要在性能测试中找到瓶颈。我被明确要求做这个测试:将整个文件加载到内存中,验证它,并向我的老板提供时间。至于你老板的要求,没有办法创建一个超过2Gig值(字节)的简单内存段,所以你需要做一些黑客操作(比如多个字节数组,或按位移位,或内存窗口,或其他什么)来达到这个目的,这会引入其他性能约束。你最好的办法是创建RAMDisk,并将文件加载到其中,然后解决Java中的问题。这算吗?当然,它们都在内存中,但不是全部在JVM的内存中。生产代码当前使用管道流在生成文件时执行验证,并且使用TeInputStream,输出也被发送到压缩层。这在未启用验证时具有很好的性能。我将考虑ramdisk,+1@chiaticsecurityin.net,同样的问题也存在,并且有几种解决方案。看看,也许可以拆分多个包含(多个文件)吗?这是克服内存占用的好方法。特别是对于XML,2.3GB的文件压缩到70MB。我应该接受这个答案,因为考虑到问题的范围,这是一个完美的回答。然而,问题并不是形式良好的(X-Y问题):我需要执行XML验证基准测试,压缩开销并不是最好的主意。因此,您的解决方案不可能是一个通用的解决方案,因为您的数据可能非常丰富,压缩时超过2GB,但这可能会导致一个不同的Q&AsFine世界,感谢您仍在尝试(2.3 GB->70 MB)。我会给其他人留下类似问题的答案,因为gzip经常被忽略。实际上,我的商业案例(ECB ABS reporting)要求对磁盘上生成的XML进行GZIP压缩,因此我不必尝试您的代码,我已经得到了答案;-)