java.lang.OutOfMemoryError 在 java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)?

java.lang.OutOfMemoryError at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)?

我在将文件上传到 google 驱动器时遇到此问题,我正在将录制的音频上传到 google 驱动器,当时出现此异常

写入文件内容的代码

                      OutputStream outputStream = result.getDriveContents().getOutputStream();
                    FileInputStream fis;
                    try {
                        fis = new FileInputStream(file);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        byte[] buf = new byte[1024];
                        int n;
                        while (-1 != (n = fis.read(buf)))
                            baos.write(buf, 0, n);
                        byte[] photoBytes = baos.toByteArray();
                        outputStream.write(photoBytes);

                        outputStream.close();
                        outputStream = null;
                        fis.close();
                        fis = null;

                        Log.e("File Size", "Size " + file.length());

                    } catch (FileNotFoundException e) {
                        Log.v("EXCEPTION", "FileNotFoundException: " + e.getMessage());
                    } catch (IOException e1) {
                        Log.v("EXCEPTION", "Unable to write file contents." + e1.getMessage());
                    }

异常发生在行`baos.write(buf, 0, n);

请帮我解决这个错误。`

您遇到 OOM 是因为您在将文件写入 google 驱动器 outputStream 之前尝试将完整文件读入内存。文件可能太大而无法存储在内存中。这样你需要一部分一部分地写。使用此方法很容易完成:

  private static final int BUFFER_SIZE = 1024;

  public static long copy(InputStream from, OutputStream to)
      throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    long total = 0;
    while (true) {
      int r = from.read(buffer);
      if (r == -1) {
        break;
      }
      to.write(buffer, 0, r);
      total += r;
    }
    return total;
  }

该方法将 return 复制的字节数。

首先写入 ByteArrayOutputStream 意味着完整的文件将在 JVM 的堆中结束。根据文件大小和堆大小,这可能是不可能的,因此例外。如果您不需要 ByteArrayOutputStream 其他任何东西,只需直接写信给 outputStream:

OutputStream outputStream = result.getDriveContents().getOutputStream();
FileInputStream fis;
try {
    fis = new FileInputStream(file);
    byte[] buf = new byte[1024];
    int n;
    while (-1 != (n = fis.read(buf)))
        outputStream.write(buf, 0, n);


} catch (FileNotFoundException e) {
    Log.v("EXCEPTION", "FileNotFoundException: " + e.getMessage());
} catch (IOException e1) {
    Log.v("EXCEPTION", "Unable to write file contents." + e1.getMessage());
} finally {
    outputStream.close();
    fis.close();
    Log.e("File Size", "Size " + file.length());
}

P.S.: 如果引用很快超出范围,则没有必要清空引用...