0

我正在尝试读取一个大文件 (>150MB) 并将文件内容作为ByteArrayOutputStream. 这是我的代码...

private ByteArrayOutputStream readfileContent(String url) throws IOException{

    log.info("Entering readfileContent ");
    ByteArrayOutputStream writer=null;
    FileInputStream reader=null;

    try{
        reader = new FileInputStream(url);
        writer = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];

        int bytesRead = reader.read(buffer);
        while (bytesRead =  > -1) { 
            writer.write(buffer, 0, bytesRead);
            buffer = new byte[1024];
        }

    }
    finally {
        writer.close();
    }

    log.info("Exiting readfileContent ");
    return writer;
}

我得到一个java.lang.OutOfMemoryError: Java heap space exception. 我尝试增加 java 堆大小,但它仍然会发生。有人可以帮助解决这个问题。

4

5 回答 5

1

您应该返回BufferedInputStream并让调用者从中读取。您正在做的是将整个文件作为ByteArrayOutputStream.

您的问题缺少您想要对文件内容执行的操作。没有它,我们只能猜测。有一个ServletOutputStream注释掉。你本来想写这个吗?写这个而不是ByteArrayOutputStream应该工作。

于 2012-05-10T12:01:04.053 回答
1

while 循环中有错误。将其更改为

 while (bytesRead >= -1) { 
     writer.write(buffer, 0, bytesRead);
     bytesRead = reader.read(buffer);
 }

也不要忘记关闭reader

(它仍然需要相当大的内存。)

于 2012-05-10T14:17:08.413 回答
0

由于您知道要读取多少字节,因此可以通过创建ByteArrayOutputStream大小来节省时间和空间。这将节省“增长”ByteArrayOutputStream后备存储的时间和空间开销。(我没有查看代码,但它可能使用与 相同的策略StringBuilder;即每次用完时将分配加倍。该策略最终可能会在峰值使用时使用多达 3 倍的文件大小。)

(坦率地说,当您知道大小时将输出放入 aByteArrayOutputStream似乎有些毫无意义。只需分配足够大的字节数组并直接读取即可。)

除此之外,答案是您需要使堆更大。

于 2012-05-10T12:02:40.610 回答
0

Your approach is going to use at least the same ammount of memory as the file, but because ByteArrayOutputStream is using a byte array as storage, it'll potentially have to resize itself 150,000 times (150 meg/1024k buffer) which is not efficient. Upping the heap size to 2* your file size and increasing the size of buf to something much larger may allow it to run, but as other posters have said, it's far better to read form the file as you go, rather than read it in as a String.

于 2012-05-10T12:05:11.327 回答
0

我在 Windows 中的 C# 中看到了类似的问题,原因是主机上没有足够的连续虚拟内存。如果您在 Windows 上,您可以尝试增加 VM 空间。

于 2012-05-10T14:25:06.643 回答