Java: Verzeichnis-Probleme mit ZIP

    • Java: Verzeichnis-Probleme mit ZIP

      Ich schreibe gerade an einer Methode zum erstellen eines ZIP-Archivs aus mehreren Dateien. Die funktioniert auch schon, das Problem dabei ist nur, dass in dem ZIP-Archiv der originale Dateipfad der Dateien nachgebildet wird!
      So ergibt sich in meinem Testfall im ZIP-Archiv folgende Struktur: D:\firefox_portable\Firefox. Eigentlich möchte ich aber nur, dass die Dateien auf der obersten Ebene im ZIP-Archiv liegen. Manche Packprogramme können außerdem meine ZIP-Datei nichtmal einlesen, weil "D:" unter windows ein ungültiger Ordner/Dateiname ist!
      Wie lässt sich das bewerkstelligen?

      Hier meine Methode:

      Quellcode

      1. /**
      2. * Packt Dateien in eine ZIP-Datei.
      3. *
      4. * @param files Zu archivierende Dateien
      5. * @param zip Zu erstellendes ZIP-Archiv
      6. */
      7. public static void compressFilesToZip( String[] files, String zip ) {
      8. FileInputStream fis;
      9. int read;
      10. byte[] data = new byte[1024];
      11. try {
      12. // Zip-Archiv mit Stream verbinden
      13. ZipOutputStream zos = new ZipOutputStream( new FileOutputStream(zip) );
      14. // Archivierungs-Modus setzen
      15. zos.setMethod( ZipOutputStream.DEFLATED );
      16. // Kompressionsgrad setzen (9=hoechste Kompression)
      17. zos.setLevel( 9 );
      18. // Hinzufügen der einzelnen Einträge
      19. for ( int i=0; i < files.length; i++ ) {
      20. // Eintrag für neue Datei anlegen
      21. ZipEntry entry = new ZipEntry( files[i] );
      22. System.out.println( entry.toString() );
      23. fis = new FileInputStream( files[i] );
      24. // Neuer Eintrag dem Archiv hinzufügen
      25. zos.putNextEntry( entry );
      26. // Hinzufügen der Daten zum neuen Eintrag
      27. while( (read = fis.read(data, 0, data.length)) != -1 ) {
      28. zos.write( data, 0, read );
      29. }
      30. // Neuen Eintrag abschließen
      31. zos.closeEntry();
      32. fis.close();
      33. }
      34. zos.close();
      35. } catch( Exception e ) {
      36. e.printStackTrace();
      37. }
      38. }
      Alles anzeigen
    • Hi,

      ich hab's mir kurz angeschaut und bin draufgekommen, dass du beim ZipEntry beim Konstruktor den relativen Pfad in der ZIP-Datei übergeben musst:

      Java-Quellcode

      1. import java.io.*;
      2. import java.util.zip.*;
      3. class Zipper {
      4. private String prefix;
      5. private String []files;
      6. private String zip;
      7. private ZipOutputStream zos;
      8. public Zipper(String prefix, String []files, String zip)
      9. {
      10. this.prefix = prefix;
      11. this.files = files;
      12. this.zip = zip;
      13. this.zos = null;
      14. }
      15. public static void main(String []args) throws Exception
      16. {
      17. new Zipper(
      18. "/home/nax/Desktop/",
      19. new String[] {
      20. "/home/nax/Desktop/test/file1",
      21. "/home/nax/Desktop/test/file2"
      22. },
      23. "output.zip"
      24. ).compress();
      25. }
      26. /**
      27. * Comprimiert die Dateien in ein ZIP-Archiv
      28. */
      29. public void compress() throws Exception
      30. {
      31. try {
      32. createZipOutputStream();
      33. // Hinzufügen der einzelnen Einträge
      34. for (int i = 0; i < files.length; i++) {
      35. addFile(files[i]);
      36. }
      37. } finally {
      38. if (zos != null) zos.close();
      39. }
      40. }
      41. /**
      42. * Erstellt den ZipOutputStream und weist ihm dem zos-Attribut zu
      43. */
      44. private void createZipOutputStream() throws Exception
      45. {
      46. // Zip-Archiv mit Stream verbinden
      47. zos = new ZipOutputStream(
      48. new FileOutputStream(zip)
      49. );
      50. // Archivierungs-Modus setzen
      51. zos.setMethod(ZipOutputStream.DEFLATED);
      52. // Kompressionsgrad setzen (9=hoechste Kompression)
      53. zos.setLevel(9);
      54. }
      55. /**
      56. * Fügt die gegebene Datei zum Archiv hinzu und macht dabei den Pfad
      57. * relativ
      58. *
      59. * @file is die Datei, die hinzugefügt werden soll.
      60. */
      61. private void addFile(String file) throws Exception
      62. {
      63. // Eintrag für neue Datei anlegen
      64. ZipEntry entry = new ZipEntry(makeRel(file));
      65. System.out.println(entry.toString());
      66. FileInputStream fis = new FileInputStream(file);
      67. // Neuer Eintrag dem Archiv hinzufügen
      68. zos.putNextEntry(entry);
      69. // Hinzufügen der Daten zum neuen Eintrag
      70. int read;
      71. byte[] data = new byte[1024];
      72. while((read = fis.read(data, 0, data.length)) != -1)
      73. zos.write(data, 0, read);
      74. // Neuen Eintrag abschließen
      75. zos.closeEntry();
      76. fis.close();
      77. }
      78. /**
      79. * Macht den gegebenen Pfad relativ.
      80. */
      81. private String makeRel(String path)
      82. {
      83. if (path.startsWith(prefix))
      84. return path.substring(prefix.length());
      85. return path;
      86. }
      87. }
      Alles anzeigen
    • Mann bin ich blöd -__-
      Ich hab nur nicht geschnallt, dass ich dem Konstruktor von ZipEntry ja gar nicht den ganzen Pfad übergeben muss ...
      Das betrifft nämlich nur die Position der Datei in dem ZIP-Archiv.

      So gehts jetzt:

      Quellcode

      1. // Eintrag für neue Datei anlegen
      2. ZipEntry entry = new ZipEntry(
      3. files[i].substring( files[i].lastIndexOf(File.separatorChar)+1 )
      4. );


      Trotzdem vielen Dank für deine Bemühungen Nax! :)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Christoph ()