我在使用公司应用程序下载文件时遇到问题,当我下载超过50mb的文件时崩溃。
我从WS处将文件作为本机字节数组获取,然后将其转换为对象字节数组以进行序列化,然后再将这些字节转换为要下载的文件。
这与小文件完美配合,但是当您下载50mb以上的文件时,从bytes[]
到Byte[]
的转换将失败。
这是我的代码:
private RespuestaDescargarDocumento rellenarRespuestaDescarga(byte[] contenido, String nombreDocumento){
Byte[] bytes = ArrayUtils.toObject(contenido);
RespuestaDescargarDocumento respuesta = new RespuestaDescargarDocumento();
respuesta.setContenido(bytes);
respuesta.setNombreDocumento(nombreDocumento);
return respuesta;
}
我看了一下toObject()
的工作,我意识到它在此循环的每个迭代中都在做new Byte()
,因此,如果我要下载例如52mb的文件,它将进行53167398迭代,对于每次迭代都会创建一个新的字节。
public static Byte[] toObject(byte[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
return EMPTY_BYTE_OBJECT_ARRAY;
}
final Byte[] result = new Byte[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = new Byte(array[i]);
}
return result;
}
我认为这很荒谬,所以我寻找了没有这种方法的转换方法,并找到了这个线程:
how to convert byte[] to Byte[], and the other way around?
我尝试了如下最佳答案:
private RespuestaDescargarDocumento rellenarRespuestaDescarga(byte[] contenido, String nombreDocumento) {
//Byte[] bytes = ArrayUtils.toObject(contenido);
Byte[] bytes = byteToByte(contenido);
RespuestaDescargarDocumento respuesta = new RespuestaDescargarDocumento();
respuesta.setContenido(bytes);
respuesta.setNombreDocumento(nombreDocumento);
return respuesta;
}
private Byte[] byteToByte(byte[] array) {
if (array == null || array.length == 0) {
return ArrayUtils.EMPTY_BYTE_OBJECT_ARRAY;
}
Byte[] bytes;
bytes = new Byte[array.length];
for (int i = 0; i < array.length; i++) {
bytes[i] = array[i];
}
return bytes;
}
现在,我可以完美下载52mb的文件,从而可以正常工作,或者是我想下载150mb的较大文件时再次崩溃。这次循环执行159551619次迭代。
我遇到以下错误:
java.lang.OutOfMemoryError: Java heap space
在这一行:
bytes = new Byte[array.length];
所以它甚至没有得到我函数的for循环,就像Java无法创建此大小的数组(159551619)。但是我发现Java中数组的最大大小为2147483647,因此它仍可与此一起使用。
我做错什么了吗?