[英]Java code to download a file or a zip file
我正在使用下面的代码下载文件,并且对于小文件也可以正常工作,但是当我尝试下载大小> 11GB的文件不起作用并给出java.lang.NegativeArraySizeException
异常时
public String downloadDirectory()
{
OutputStream myOut = null;
FileInputStream fileInputStream = null;
File downzip = new File(dirName+"/"+dir+".zip");
getServletResponse().setContentType("TEXT/HTML");
getServletResponse().setHeader("Content-Disposition","attachment; filename=\"" + dir +".zip" + "\"");
getServletResponse().setContentLength((int)downzip.length());
System.out.println("length "+(int)downzip.length());
//READ DATA FROM FILE
byte[] dataRead = new byte[(int)downzip.length()];
fileInputStream = new FileInputStream(downzip);
fileInputStream.read(dataRead,0,(int)downzip.length());
//WRITE DATA TO OUTFILE
myOut = getServletResponse().getOutputStream();
myOut.write(dataRead);
if (fileInputStream != null) {
fileInputStream.close();
}
}
catch(Exception e)
{
e.printStackTrace();
Execute.rmdirscript(dirName);
return "exception";
}
finally{
System.out.println("finally downloaddir");
if(myOut!=null){
try{
myOut.close();}
catch(Exception e){
e.printStackTrace();;
}
}
if (fileInputStream != null) {
try{
fileInputStream.close();}
catch(Exception e){
e.printStackTrace();;
}
}
}
}
错误在此行:
byte[] dataRead = new byte[(int)downzip.length()];
对于大文件,值(int)downzip.length()
变为负数,并给出java.lang.NegativeArraySizeException
异常。
您没有尝试循环吗? 像这样
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1)
{
out.write(data, 0, count);
}
您正在长时间读取数据大小并将其强制转换为int,这是不安全的,并且会导致负数组长度。 实际上,如果我按此代码操作,则文件长度应为0,并且长度可能不是负数,而仅仅是0。
作为解决方案,请尝试直接写入文件而不是先创建数组。 同样,为阵列分配11G内存也不是一个好主意。
您可以从输出文件路径创建FileOutputStream
,然后从InputStream
读取并写入OutputStream
直到到达应安全地为您复制文件的流-1
的末尾。
您将其存储到11 GB的字节数组中,对于存储该字节数组来说,它是很大的,我认为这是有问题的。
请提供错误所在的确切行。
Java使用int进行数组索引。 Intger.MAX_VALUE
是2^31-1
。 您只能在常规阵列中存储2^31-1
字节2GiB
。
是File downzip
的长度导致您出现问题。
downzip.length()
返回long
,您将其显式转换为int
。 这样,您很容易获得用于初始化数组的负值:
byte[] dataRead = new byte[(int)downzip.length()];
另一件事是您应该避免读取整个文件。 更好的方法是分块读取和写入。
您可以在@Ashok Raj的答案中找到有关如何执行此操作的示例。
使用此方法:
private static void readFileAndDumpIt(String pathToFile, OutputStream out){
try {
InputStream fIs = new BufferedInputStream(new FileInputStream(pathToFile));
byte[] array=new byte[4096];
for(int numberRead=fIs.read(array);numberRead!=-1;numberRead=fIs.read(array)){
out.write(array,0,numberRead);
out.flush();
}
fIs.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
我已成功使用它,最多可使用20GB的文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.