简体   繁体   中英

Java code to download a file or a zip file

I am using below code to download a file and it works fine for small files, but when I tried to download a file whose size > 11GB code is not working and giving java.lang.NegativeArraySizeException exception

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();;
        }
           }
}


}

The error is at this line:

byte[] dataRead = new byte[(int)downzip.length()];

The value (int)downzip.length() becomes negative for big files and gives java.lang.NegativeArraySizeException exception.

didn't you try in a loop? like this

 byte data[] = new byte[1024];
 int count;
  while ((count = in.read(data, 0, 1024)) != -1)
            {
                    out.write(data, 0, count);
            }

You are reading data size in long and down casting it into int, which is not safe, and is causing the negative array length. Actually your file length should be 0 if I go by this code, and the length may not be negative but simply zero.

As a solution, try writing directly to a file instead of creating an array upfront. Also, allocating 11G memory for array is anyway not a good idea.

You can create a FileOutputStream from the output file path and then read from the InputStream and write to OutputStream until you reach the end of stream -1 that should safely copy file for you.

You are storing it into byte array for which 11 GB is quite big to store that, i think there is the problem occur.

Please provide the exact line where you got the error.

Java use int for array indexing. The Intger.MAX_VALUE is 2^31-1 . You can store only 2^31-1 bytes 2GiB in a regular array.

It is the length of File downzip that causing you a problem.

downzip.length() returns long , which you explicitly cast to int . That way you easily get negative value with which you initialize array:

byte[] dataRead = new byte[(int)downzip.length()];

Another thing is you should avoid reading a whole file. Better way would be reading and writing it in chunks.

You have example of how to do this in @Ashok Raj's answer.

Use this method:

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();
    }
}

I have successfully used it, on up to 20GB files

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM