2012-10-04 5 views
0

아래 코드를 사용하여 파일을 다운로드하고 있지만 작은 파일에는 문제가 없지만 크기가 11GB 이상인 파일을 다운로드하려고 시도 할 때 java.lang.NegativeArraySizeException 예외가 발생했습니다.파일 또는 zip 파일을 다운로드하는 자바 코드

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

을 파일에 최대에 그것을 사용했다? –

+8

11GB는 너무 커서 int에 들어 가지 않습니다. 그리고 네 질문은 뭐니? –

+0

다운로드를 다시 시작 하시길 바랍니다. 11GB를 통해 90 %의 길을 얻고 다시 시작해야하는 것은 다소 고통 스러울 것입니다. –

답변

2

데이터 크기가 길어서 int로 내 보내지는 것이 안전하지 않으며 음수 배열 길이가 원인입니다. 실제로이 코드로 이동하면 파일 길이는 0이어야하며 길이는 음수가 아니라 단순히 0이 될 수 있습니다.

해결책으로 배열을 미리 작성하는 대신 파일에 직접 작성하십시오. 또한 어레이에 11G 메모리를 할당하는 것은 어쨌든 좋은 생각이 아닙니다.

당신은 출력 파일 경로에서 FileOutputStream를 만들 수 있습니다 후 InputStream 읽고 안전하게 당신을 위해 파일을 복사해야 스트림 -1의 끝에 도달 할 때까지 OutputStream에 기록.

+0

대용량 파일을 다운로드 할 수 있도록 내 코드에서 어떤 수정을해야합니까? – ankit

+0

@ankit 당신은 한 번에 전체 파일을 다운로드하고 있습니다. 작은 파일이라 할지라도 그렇게해서는 안됩니다. 내부 버퍼를 사용하고 루프를 반복하여 파일을 작은 덩어리로 다운로드하십시오. –

+0

@Alonso Dominguez가 코드를 제공 할 수 있습니다. – ankit

0

Java는 배열 색인을 위해 int를 사용합니다. Intger.MAX_VALUE2^31-1입니다. 2^31-1 바이트 2GiB 만 일반 배열로 저장할 수 있습니다.

+0

대용량 파일을 다운로드하려면 코드에서 어떤 수정을해야합니까? – ankit

+1

전체 바이트를 작업하고 배열을 더 작은 조각으로 분할하려면 64 비트 Java 구현을 사용해야합니다. 저장하는 경우 버퍼로 읽고 쓰기 만하면됩니다. – azendh

1

11 기가 바이트를 저장하기에 꽤 큰 바이트 배열로 저장하려고합니다. 문제가 발생한다고 생각합니다.

오류가 발생한 정확한 행을 입력하십시오.

+0

오류는 다음 행에 있습니다. byte [] dataRead = new byte [(int) downzip.length()]; value (int) downzip.length()는 큰 파일에 대해 음수가되고 java.lang.NegativeArraySizeException 예외를 제공합니다. – ankit

+1

downzip.length()를 int로 변환하려고하면 for 루프를 사용하여 저장할 수 있습니다. 하나의 반복에서 byte가 아닌 int 크기 만 저장하고 파일에 쓰고 모든 데이터가 들어올 때까지 루프를 계속 수행합니다 사본입니다. –

0

문제가되는 길이는 File downzip입니다.

downzip.length()longint으로 명시 적으로 전송됩니다. 그렇게하면 배열을 초기화 할 때 음수 값을 쉽게 얻을 수 있습니다.

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

또 다른 점은 전체 파일을 읽지 않도록해야한다는 것입니다. 더 좋은 방법은 독해와 청크로 작성하는 것입니다.

당신은 @Ashok Raj의 답변에서 이것을 수행하는 방법에 대한 예제를 가지고 있습니다.

+0

예 u r 오른쪽 대용량 파일을 다운로드 할 수 있도록 코드에서 수정해야 할 사항은 무엇입니까? – ankit

3

루프를 시도하지 않으셨습니까? 이

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

이 희망을 시도하면 효과가 있음 – ankit

+0

확실한 경우 문제가있을 경우 다시 방문하십시오. –

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

내가 성공적으로 오류가있는 라인을 오는가 20기가바이트이 ​​

관련 문제