0

以下のコードを使用してファイルをダウンロードしていますが、小さなファイルでは問題なく動作しますが、サイズが 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例外が発生します。

4

6 に答える 6

3

ループで試しませんでしたか?このような

 byte data[] = new byte[1024];
 int count;
  while ((count = in.read(data, 0, 1024)) != -1)
            {
                    out.write(data, 0, count);
            }
于 2012-10-04T09:18:01.743 に答える
2

long でデータ サイズを読み取り、それを int にダウン キャストしていますが、これは安全ではなく、負の配列長を引き起こしています。実際、このコードを使用すると、ファイルの長さは 0 になるはずです。長さは負ではなく、単にゼロになる場合があります。

解決策として、事前に配列を作成するのではなく、ファイルに直接書き込んでみてください。また、配列に 11G のメモリを割り当てることは、とにかく良い考えではありません。

FileOutputStream出力ファイル パスからを作成し、ファイルを安全にコピーする必要があるストリームの最後に到達するまで、 から読み取りInputStreamおよび書き込みを行うことができます。OutputStream-1

于 2012-10-04T09:10:42.533 に答える
1

それを保存するには11 GBが非常に大きいバイト配列に保存していますが、問題が発生していると思います。

エラーが発生した正確な行を提供してください。

于 2012-10-04T09:14:52.017 に答える
0

Java は、配列のインデックス付けに int を使用します。Intger.MAX_VALUEです2^31-1。_ 通常の配列には2^31-1バイトのみを格納できます。2GiB

于 2012-10-04T09:12:19.180 に答える
0

File downzipそれはあなたに問題を引き起こす長さです。

downzip.length()long明示的にキャストした を返しますint。そうすれば、配列を初期化する負の値を簡単に取得できます。

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

もう 1 つのことは、ファイル全体を読み取らないようにする必要があることです。より良い方法は、チャンクで読み書きすることです。

@Ashok Rajの回答でこれを行う方法の例があります。

于 2012-10-04T09:16:55.307 に答える
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のファイルで問題なく使用できました

于 2012-10-04T11:03:46.940 に答える