2013-08-23 12 views
6

Wygenerowałem wiele buforów obrazów w pamięci i chcę skompresować je do jednego pliku zip przed wysłaniem go jako załącznika wiadomości e-mail. Jak zapisać pliki do zip bez czytania plików z dysku.Jak mogę wygenerować plik zip bez zapisywania go na dysku przy pomocy Javy?

Czy istnieje sposób, w jaki mogę skompresować te pliki bez tworzenia pliku tymczasowego?

Zapisywanie na dysk jest czasochłonne ze względu na tysiące tworzonych plików.

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package cccprog; 

import java.awt.Component; 
import java.awt.Panel; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JRadioButton; 

/** 
* 
* @author Z 
*/ 
public class N { 

    public static void main(String[] args) throws Exception { 
     for (int i = 0; i < 10; i++) { 
      JFrame jf = new JFrame(); 
      Panel a = new Panel(); 

      JRadioButton birdButton = new JRadioButton(); 
      birdButton.setSize(100, 100); 

      birdButton.setSelected(true); 
      jf.add(birdButton); 

      getSaveSnapShot(birdButton, i + ".bmp"); 

     } 
    } 

    public static BufferedImage getScreenShot(Component component) { 

     BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_BYTE_GRAY); 
     // paints into image's Graphics 
     component.paint(image.getGraphics()); 
     return image; 
    } 

    public static void getSaveSnapShot(Component component, String fileName) throws Exception { 
     BufferedImage img = getScreenShot(component); 
//  BufferedImage img = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_BYTE_BINARY); 

     // write the captured image as a bmp 
     ImageIO.write(img, "bmp", new File(fileName)); 
    } 
} 
+3

Spójrz na java.utli.zip. –

+1

Tylko dla mojej ciekawości, dlaczego chcesz uniknąć tworzenia pliku tymczasowego? –

+0

To wydaje się powiązane http://stackoverflow.com/questions/7108035/how-to-flush-the-zipoutputstream-periodically-in-java – Ted

Odpowiedz

9

nie jestem pewien co do przypadków użycia ty masz tutaj, jeśli masz tysiące plików w pamięci może zabraknąć pamięci raczej szybko.

Pliki zip są jednak generowane ze strumieniami, więc nie ma potrzeby tymczasowego zapisywania ich w pliku - może równie dobrze być w pamięci lub przesyłane strumieniowo bezpośrednio do zdalnego odbiorcy (tylko z niewielkim buforem pamięci, aby uniknąć duży ślad pamięci).

Znalazłem stare narzędzie zip napisane kilka lat temu i zmodyfikowałem je nieznacznie dla twojego przypadku użycia. Tworzy plik zip zapisany w tablicy bajtów z listy plików, również przechowywanych w tablicach bajtowych. Ponieważ w pamięci znajduje się wiele plików, dodałem małą klasę pomocniczą MemoryFile z samą nazwą pliku i tablicą bajtów zawierającą zawartość. Aha, i upubliczniłem pola, żeby uniknąć zbroi i setterów - tylko po to, by zaoszczędzić trochę miejsca.

public class MyZip { 

    public static class MemoryFile { 
     public String fileName; 
     public byte[] contents; 
    } 

    public byte[] createZipByteArray(List<MemoryFile> memoryFiles) throws IOException { 
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
     ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream); 
     try { 
      for (MemoryFile memoryFile : memoryFiles) { 
       ZipEntry zipEntry = new ZipEntry(memoryFile.fileName); 
       zipOutputStream.putNextEntry(zipEntry); 
       zipOutputStream.write(memoryFile.contents); 
       zipOutputStream.closeEntry(); 
      } 
     } finally { 
      zipOutputStream.close(); 
     } 
     return byteArrayOutputStream.toByteArray(); 
    } 

} 
+0

Zaktualizowałem mój pierwotny wpis. Byłem zdezorientowany, jak można użyć BufferImage do tego samego. – user1198289

+0

Nie tylko "zaktualizowałeś" swój oryginalny wpis, ale całkowicie go zmieniłeś. Nie przepadam za tym zbytnio; to znaczy, że pytanie zostało całkowicie zmienione po tym, jak poświęciłem czas na odpowiedź. Należy pamiętać, że posiadanie "tysięcy" plików PDF w pamięci i tysiące obiektów BufferedImages to dwie różne rzeczy. Dla każdego obrazu musisz uzyskać strumień wyjściowy w formacie (gif, png, jpg, itp.), Który chcesz zapisać/przenieść do niego. Zwróć też uwagę, że obrazy skompresowane mają niewielki wpływ na kompresję, ponieważ zwykle są już skompresowane. – Steinar

1
   FileInputStream[] ins = //I assume you have all file handles in the form of FileInputStream 
      String[] fileNames = //I assume you have all file names 
      FileOutputStream out = new FileOutputStream(""); //specify the zip file name here 
      ZipOutputStream zipOut = new ZipOutputStream(out); 
      for (int i=0; i<ins.length; i++) { 
       ZipEntry entry = new ZipEntry(fileNames[i]); 
       zipOut.putNextEntry(entry); 
       int number = 0; 
       byte[] buffer = new byte[512]; 
       while ((number = ins[i].read(buffer)) != -1) { 
        zipOut.write(buffer, 0, number); 
       }       
       ins[i].close(); 
      } 
      out.close(); 
      zipOut.close(); 

Na podstawie dostarczonych informacji, wymyślić powyższym kodzie. Mam nadzieję że to pomoże.

+0

Zaktualizowałem swój pierwotny wpis. Byłem zdezorientowany, jak można użyć BufferImage do tego samego. – user1198289

Powiązane problemy