2011-01-13 6 views
5

Moim celem jest umieszczenie wielu obiektów java.io.File w pliku zip i wydrukowanie do HttpServletResponse, aby użytkownik mógł je pobrać.Tworzenie pliku ZIP dla listy "plików wirtualnych" i wyjście do httpservletresponse

Pliki zostały utworzone przez marszałka JAXB. Jest to obiekt java.io.File, ale w rzeczywistości nie znajduje się w systemie plików (jest to tylko w pamięci), więc nie mogę utworzyć obiektu FileInputStream.

Wszystkie zasoby, które widziałem, używają OutputStream do drukowania zawartości zip. Ale wszystkie te zasoby używają FileInputStream (którego nie mogę użyć).

Ktoś wie, jak mogę to zrobić?

+3

Co masz na myśli, że to 'java.io.File'? Obiekt 'File' jest po prostu fantazyjnym obiektem adresowym; nie zawiera żadnej zawartości pliku. Gdzie są twoje dane? – erickson

Odpowiedz

3

Okazuje się, że jestem idiotą :) pliku, który był „stworzył” było zapisanie na niewłaściwą ścieżkę i przełknięcie wyjątku, więc pomyślałem, że było "stworzone" w porządku. Kiedy jednak próbowałem utworzyć instancję nowego FileInputStream, skarżyłem się, że plik nie istnieje (słusznie). Miałem brainfart i założyłem, że obiekt java.io.File faktycznie zawierał w nim informacje o plikach. Ale jak zauważył erickson, było to fałszywe.

Dzięki Ralph za kod, użyłem go po rozwiązaniu problemu nieprawidłowej ścieżki.

Mój kod:

ZipOutputStream out = new ZipOutputStream(response.getOutputStream()); 
byte[] buf = new byte[1024]; 

File file; 
InputStream in; 
// Loop through entities 
for (TitleProductAccountApproval tpAccountApproval : tpAccountApprovals) { 
    // Generate the file  
    file = xmlManager.getXML(
     tpAccountApproval.getTitleProduct().getTitleProductId(), 
     tpAccountApproval.getAccount().getAccountId(), 
     username); 

    // Write to zip file 
    in = new FileInputStream(file); 
    out.putNextEntry(new ZipEntry(file.getName())); 

    int len; 
    while ((len = in.read(buf)) > 0) { 
     out.write(buf, 0, len); 
    } 

    out.closeEntry(); 
    in.close(); 
} 

out.close(); 
+0

Problem ze ścieżką Invalide? - co masz na myśli - czy w kodzie mojej odpowiedzi jest błąd serios? – Ralph

+0

Twój kod nie był doskonały. To była moja wina. – Corey

6

Zapoznaj się z biblioteką Apache Commons Compress, która udowodniła funkcjonalność, której potrzebujesz.

Oczywiście "erickson" ma rację z jego commment na twoje pytanie. Będziesz potrzebował conent pliku, a nie obiektu java.io.File. W moim przykładzie zakładam, że masz metodę byte[] getTheContentFormSomewhere(int fileNummer), która zwraca zawartość pliku (w pamięci) pliku fileNummer-th. - Oczywiście ta funkcja jest kiepskim projektem, ale jest tylko dla ilustracji.

Powinno to działać trochę jak ten:

void compress(final OutputStream out) { 
    ZipOutputStream zipOutputStream = new ZipOutputStream(out); 
    zipOutputStream.setLevel(ZipOutputStream.STORED); 

    for(int i = 0; i < 10; i++) { 
    //of course you need the file content of the i-th file 
    byte[] oneFileContent = getTheContentFormSomewhere(i); 
    addOneFileToZipArchive(zipOutputStream, "file"+i+"."txt", oneFileContent); 
    } 

    zipOutputStream.close(); 
} 

void addOneFileToZipArchive(final ZipOutputStream zipStream, 
      String fileName, 
      byte[] content) { 
    ZipArchiveEntry zipEntry = new ZipArchiveEntry(fileName); 
    zipStream.putNextEntry(zipEntry); 
    zipStream.write(pdfBytes); 
    zipStream.closeEntry(); 
} 

Snipets swojego kontrolera http:

HttpServletResponse response 
... 
    response.setContentType("application/zip"); 
    response.addHeader("Content-Disposition", "attachment; filename=\"compress.zip\""); 
    response.addHeader("Content-Transfer-Encoding", "binary"); 
    ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream(); 
    compress(outputBuffer); 
    response.getOutputStream().write(outputBuffer.toByteArray()); 
    response.getOutputStream().flush(); 
    outputBuffer.close();