我使用下面的代码下载文件,它适用于小文件,但当我尝试下载文件大小> 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
异常。
答案 0 :(得分:3)
你没试过循环吗?像这样
byte data[] = new byte[1024];
int count;
while ((count = in.read(data, 0, 1024)) != -1)
{
out.write(data, 0, count);
}
答案 1 :(得分:2)
您正在读取数据大小的长整数并将其转换为int,这是不安全的,并且导致负数组长度。实际上,如果我使用此代码,你的文件长度应为0,长度可能不是负数,而只是零。
作为解决方案,请尝试直接写入文件,而不是预先创建数组。此外,为阵列分配11G内存无论如何都不是一个好主意。
您可以从输出文件路径创建FileOutputStream
,然后从InputStream
读取并写入OutputStream
,直到您到达应该安全的流-1
的末尾复制文件给你。
答案 2 :(得分:1)
您将它存储到字节数组中,其中存储11 GB非常大,我认为存在问题。
请提供错误的确切行。
答案 3 :(得分:0)
Java使用int进行数组索引。 Intger.MAX_VALUE
为2^31-1
。您只能在常规数组中存储2^31-1
字节2GiB
。
答案 4 :(得分:0)
导致问题的是File downzip
的长度。
downzip.length()
会返回long
,您明确地将其转换为int
。这样你很容易得到用于初始化数组的负值:
byte[] dataRead = new byte[(int)downzip.length()];
另一件事是你应该避免阅读整个文件。更好的方法是以块状读取和写入。
你有一个如何在@Ashok Raj的回答中做到这一点的例子。
答案 5 :(得分:0)
使用此方法:
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文件