1

我需要将文件转换为字节数组,但不能使用 .mov 文件(1.32 Gb)来完成。该方法适用于小型 .txt 文件和 JPEG 图像,但是当我尝试使用 MOV 文件时,我不能。我只是得到一个 NullPointerException。

代码:

public byte[] fileToByteArray(File file){
    ByteArrayOutputStream baos = null;
    InputStream fis = null;
    try{
        byte[] buffer = new byte[(int)file.length()];
        baos = new ByteArrayOutputStream();
        fis = new FileInputStream(file);
        int read;
        while((read = fis.read(buffer)) != -1){
            baos.write(buffer, 0, read);
        }
    }catch(Exception ex){
        System.out.println("Error: 1");
    }finally{
        try{
            if(baos != null){
                baos.close();
            }
        }catch(Exception ex){
            System.out.println("Error: 2");
        }
        try{
            if(fis != null){
                fis.close();
            }
        }catch(Exception ex){
            System.out.println("Error: 3");
        }
        return baos.toByteArray();
    }
}
4

3 回答 3

1

在这一行:

return baos.toByteArray();

您正在无条件地取消引用baos......即使如果此行引发异常,它仍然为 null:

byte[] buffer = new byte[(int)file.length()];

我怀疑该行引发异常(内存不足,猜测)...但是由于您的异常处理策略“捕获所有异常,将它们打印出来并忽略它们”,您在不应该的情况下继续进行.

对此的直接解决方法是仅捕获您真正想要捕获的异常——如果有的话IOException,几乎可以肯定只有在这种情况下。事实上,我可能根本不会在您编写的代码中使用任何子句,除了可能在代码上。(你不希望一个异常来掩盖其他地方的异常。如果你使用的是 Java 7,请使用 try-with-resources 语句使所有这些更容易开始。)catchcloseclose

以你正在做的方式“处理”异常是一个非常糟糕的主意——你基本上是在说你想继续不管出了什么问题,如果你幸运的话,这只会导致一个错误导致另一个错误,或者如果你很不幸,你最终做出了糟糕的状态改变,例如用坏的数据覆盖好数据,甚至没有意识到这一点。

现在至于更大的问题——你试图分配一个巨大的数组,我怀疑你没有告诉 JVM 使用那么多内存。您需要从以下内容开始:

java -Xmx3G ...

...假设您使用的是 64 位 JVM,它乐于使用这么多内存。

于 2012-09-09T08:12:49.650 回答
0

1.32 GB 大约是2^30.4字节。OutOfMemoryError很可能会在这条线上抛出一个:

byte[] buffer = new byte[(int)file.length()];

结果,代码流跳转到异常处理程序(它将尝试打印"Error: 1",在这种情况下可能会可能不会工作)。结果,当代码流到达finally块时,仍然baos是.nullNullPointerException

我建议的解决方案是不要尝试将 1.32 GB 的文件读入内存……至少是这样。

于 2012-09-09T08:12:37.873 回答
0

你为什么不以 4K/8K/16K 字节数组的形式阅读它?这样,您将永远不会耗尽内存。我通过网络以这种方式复制了多达 20GB 的文件。

于 2012-09-09T08:31:51.777 回答