Ich habe eine dynamische Textdatei, die Inhalte aus einer Datenbank gemäß der Benutzerabfrage auswählt. Ich muss diesen Inhalt in eine Textdatei schreiben und in einen Ordner in einem Servlet komprimieren. Wie soll ich das machen?
StringBuilder sb =newStringBuilder();
sb.append("Test String");File f =newFile("d:\\test.zip");ZipOutputStream out =newZipOutputStream(newFileOutputStream(f));ZipEntry e =newZipEntry("mytext.txt");
out.putNextEntry(e);byte[] data = sb.toString().getBytes();
out.write(data,0, data.length);
out.closeEntry();
out.close();
Dadurch wird im Stammverzeichnis von D:named eine Zip- test.zipDatei erstellt, die eine einzelne aufgerufene Datei enthält mytext.txt. Natürlich können Sie weitere Zip-Einträge hinzufügen und auch ein Unterverzeichnis wie das folgende angeben:
ZipEntry e =newZipEntry("folderName/mytext.txt");
Weitere Informationen zur Komprimierung mit Java finden Sie hier .
Warum sind die beiden Zeilen byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);in diesem Codebeispiel enthalten? Was ist ihr Zweck?
Kaadzia
@kdzia, die erste Zeile konvertiert den StringBuilder-Wert in ein Byte-Array, und die zweite Zeile nimmt dieses Byte-Array und schreibt es in den ZipEntry in der Datei "test.zip". Diese Zeilen sind erforderlich, da Zip-Dateien mit Byte-Arrays und nicht mit Zeichenfolgen arbeiten.
OrangeWombat
3
Aber ... wie enthält der StringBuilder im obigen Beispiel etwas anderes als "Test String"? Das verwirrt mich auch ein wenig. Wenn Sie das sb.toString().getBytes()in die ZIP-Datei schreiben , würde ich erwarten, dass es die Bytes der Datei enthält, die Sie komprimieren? Oder fehlt mir etwas?
RobA
3
@RobA dir fehlt nichts. Der StringBuilder soll in der Tat den Text enthalten, den das OP aus seiner Datenbank erhalten hat. OP müsste einfach "Test String" (einschließlich der Anführungszeichen) für etwas wie getTextFromDatabase ()
Blueriver
Vielen Dank, @Blueriver
RobA
143
In Java 7 ist ZipFileSystem integriert, mit dem Dateien aus Zip-Dateien erstellt, geschrieben und gelesen werden können.
Map<String,String> env =newHashMap<>();// Create the zip file if it doesn't exist
env.put("create","true");
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");try(FileSystem zipfs =FileSystems.newFileSystem(uri, env)){Path externalTxtFile =Paths.get("/codeSamples/zipfs/SomeTextFile.txt");Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");// Copy a file into the zip fileFiles.copy(externalTxtFile, pathInZipfile,StandardCopyOption.REPLACE_EXISTING);}
Gibt es eine Möglichkeit, diese Funktion auszuführen, wenn die Erweiterung nicht vorhanden ist .zip? Ich muss eine .fooDatei schreiben , die genau wie eine Zip-Datei formatiert ist, aber eine andere Erweiterung hat. Ich weiß, dass ich eine .zipDatei erstellen und umbenennen könnte, aber es wäre einfacher, sie nur mit dem richtigen Namen zu erstellen.
Troy Daniels
2
@TroyDaniels Das obige Beispiel funktioniert auch mit einer anderen Erweiterung, da das jar:file:Präfix zum Erstellen des URI verwendet wird.
Sivabalan
10
Das einzige Problem, das hier auftreten kann, ist, dass es nicht funktioniert, wenn Sie Verzeichnisse haben. Wenn Sie beispielsweise "/dir/SomeTextFile.txt" in der pathInZipfileVariablen haben, müssen Sie das 'dir' im .zip-Archiv erstellen. Fügen Sie dazu einfach die nächste Zeile hinzu: Files.createDirectories(pathInZipfile.getParent())bevor Sie die Files.copyMethode aufrufen .
D. Naumovich
Wie stelle ich die Komprimierungsstufe ein?
cdalxndr
34
Zum Schreiben einer ZIP-Datei verwenden Sie einen ZipOutputStream. Für jeden Eintrag, den Sie in die ZIP-Datei einfügen möchten, erstellen Sie ein ZipEntry-Objekt. Sie übergeben den Dateinamen an den ZipEntry-Konstruktor. Es legt die anderen Parameter wie Dateidatum und Dekomprimierungsmethode fest. Sie können diese Einstellungen überschreiben, wenn Sie möchten. Anschließend rufen Sie die putNextEntry-Methode des ZipOutputStream auf, um mit dem Schreiben einer neuen Datei zu beginnen. Senden Sie die Dateidaten an den ZIP-Stream. Wenn Sie fertig sind, rufen Sie closeEntry auf. Wiederholen Sie diesen Vorgang für alle Dateien, die Sie speichern möchten. Hier ist ein Code-Skelett:
FileOutputStream fout =newFileOutputStream("test.zip");ZipOutputStream zout =newZipOutputStream(fout);for all files
{ZipEntry ze =newZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();}
zout.close();
Hier ist ein Beispielcode zum Komprimieren eines gesamten Verzeichnisses (einschließlich Unterdateien und Unterverzeichnissen). Er verwendet die Walk-Dateibaumfunktion von Java NIO.
Sie müssen hauptsächlich zwei Funktionen erstellen. Das erste ist writeToZipFile () und das zweite ist createZipfileForOutPut .... und dann das createZipfileForOutPut ('Dateiname von .zip') `…
publicstaticvoid writeToZipFile(String path,ZipOutputStream zipStream)throwsFileNotFoundException,IOException{System.out.println("Writing file : '"+ path +"' to zip file");File aFile =newFile(path);FileInputStream fis =newFileInputStream(aFile);ZipEntry zipEntry =newZipEntry(path);
zipStream.putNextEntry(zipEntry);byte[] bytes =newbyte[1024];int length;while((length = fis.read(bytes))>=0){
zipStream.write(bytes,0, length);}
zipStream.closeEntry();
fis.close();}publicstaticvoid createZipfileForOutPut(String filename){String home =System.getProperty("user.home");// File directory = new File(home + "/Documents/" + "AutomationReport");File directory =newFile("AutomationReport");if(!directory.exists()){
directory.mkdir();}try{FileOutputStream fos =newFileOutputStream("Path to your destination"+ filename +".zip");ZipOutputStream zos =newZipOutputStream(fos);
writeToZipFile("Path to file which you want to compress / zip", zos);
zos.close();
fos.close();}catch(FileNotFoundException e){
e.printStackTrace();}catch(IOException e){
e.printStackTrace();}}
Wenn Sie ohne Software dekomprimieren möchten, verwenden Sie diesen Code besser. Anderer Code mit PDF-Dateien sendet beim manuellen Dekomprimieren einen Fehler
Da ich eine Weile gebraucht habe, um es herauszufinden, hielt ich es für hilfreich, meine Lösung mit Java 7+ ZipFileSystem zu veröffentlichen
openZip(runFile);
addToZip(filepath);//loop construct;
zipfs.close();privatevoid openZip(File runFile)throwsIOException{Map<String,String> env =newHashMap<>();
env.put("create","true");
env.put("encoding","UTF-8");Files.deleteIfExists(runFile.toPath());
zipfs =FileSystems.newFileSystem(URI.create("jar:"+ runFile.toURI().toString()), env);}privatevoid addToZip(String filename)throwsIOException{Path externalTxtFile =Paths.get(filename).toAbsolutePath();Path pathInZipfile = zipfs.getPath(filename.substring(filename.lastIndexOf("results")));//all files to be stored have a common base folder, results/ in my caseif(Files.isDirectory(externalTxtFile)){Files.createDirectories(pathInZipfile);try(DirectoryStream<Path> ds =Files.newDirectoryStream(externalTxtFile)){for(Path child : ds){
addToZip(child.normalize().toString());//recursive call}}}else{// copy file to zip fileFiles.copy(externalTxtFile, pathInZipfile,StandardCopyOption.REPLACE_EXISTING);}}
Gegeben exportPathund queryResultsals String-Variablen erstellt der folgende Block eine results.zipDatei unter exportPathund schreibt den Inhalt queryResultsin eine results.txtDatei innerhalb der Zip-Datei.
URI uri = URI.create("jar:file:"+ exportPath +"/results.zip");Map<String,String> env =Collections.singletonMap("create","true");try(FileSystem zipfs =FileSystems.newFileSystem(uri, env)){Path filePath = zipfs.getPath("/results.txt");byte[] fileContent = queryResults.getBytes();Files.write(filePath, fileContent,StandardOpenOption.CREATE);}
Erstellen einer Zip-Datei mit einer einzelnen Datei / Hinzufügen einer einzelnen Datei zu einer vorhandenen Zip
new ZipFile("filename.zip").addFile("filename.ext");
Oder
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Erstellen einer Zip-Datei mit mehreren Dateien / Hinzufügen mehrerer Dateien zu einer vorhandenen Zip
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Erstellen einer Zip-Datei durch Hinzufügen eines Ordners / Hinzufügen eines Ordners zu einer vorhandenen Zip-Datei
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Erstellen einer Zip-Datei aus Stream / Hinzufügen eines Streams zu einer vorhandenen Zip
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);
in diesem Codebeispiel enthalten? Was ist ihr Zweck?sb.toString().getBytes()
in die ZIP-Datei schreiben , würde ich erwarten, dass es die Bytes der Datei enthält, die Sie komprimieren? Oder fehlt mir etwas?In Java 7 ist ZipFileSystem integriert, mit dem Dateien aus Zip-Dateien erstellt, geschrieben und gelesen werden können.
Java Doc: ZipFileSystem Provider
quelle
.zip
? Ich muss eine.foo
Datei schreiben , die genau wie eine Zip-Datei formatiert ist, aber eine andere Erweiterung hat. Ich weiß, dass ich eine.zip
Datei erstellen und umbenennen könnte, aber es wäre einfacher, sie nur mit dem richtigen Namen zu erstellen.jar:file:
Präfix zum Erstellen des URI verwendet wird.pathInZipfile
Variablen haben, müssen Sie das 'dir' im .zip-Archiv erstellen. Fügen Sie dazu einfach die nächste Zeile hinzu:Files.createDirectories(pathInZipfile.getParent())
bevor Sie dieFiles.copy
Methode aufrufen .Zum Schreiben einer ZIP-Datei verwenden Sie einen ZipOutputStream. Für jeden Eintrag, den Sie in die ZIP-Datei einfügen möchten, erstellen Sie ein ZipEntry-Objekt. Sie übergeben den Dateinamen an den ZipEntry-Konstruktor. Es legt die anderen Parameter wie Dateidatum und Dekomprimierungsmethode fest. Sie können diese Einstellungen überschreiben, wenn Sie möchten. Anschließend rufen Sie die putNextEntry-Methode des ZipOutputStream auf, um mit dem Schreiben einer neuen Datei zu beginnen. Senden Sie die Dateidaten an den ZIP-Stream. Wenn Sie fertig sind, rufen Sie closeEntry auf. Wiederholen Sie diesen Vorgang für alle Dateien, die Sie speichern möchten. Hier ist ein Code-Skelett:
quelle
Hier ist ein Beispielcode zum Komprimieren eines gesamten Verzeichnisses (einschließlich Unterdateien und Unterverzeichnissen). Er verwendet die Walk-Dateibaumfunktion von Java NIO.
Um dies zu nutzen, rufen Sie einfach an
und Sie erhalten eine Zip-Datei directoryToCompress.zip
quelle
Spring Boot Controller, komprimieren Sie die Dateien in einem Verzeichnis und können heruntergeladen werden.
quelle
quelle
So erstellen Sie eine Zip-Datei aus einer Quelldatei:
quelle
Einzelne Datei:
Mehrere Dateien:
quelle
Sie müssen hauptsächlich zwei Funktionen erstellen. Das erste ist writeToZipFile () und das zweite ist createZipfileForOutPut .... und dann das createZipfileForOutPut ('Dateiname von .zip') `…
quelle
Wenn Sie ohne Software dekomprimieren möchten, verwenden Sie diesen Code besser. Anderer Code mit PDF-Dateien sendet beim manuellen Dekomprimieren einen Fehler
quelle
Da ich eine Weile gebraucht habe, um es herauszufinden, hielt ich es für hilfreich, meine Lösung mit Java 7+ ZipFileSystem zu veröffentlichen
quelle
quelle
Gegeben
exportPath
undqueryResults
als String-Variablen erstellt der folgende Block eineresults.zip
Datei unterexportPath
und schreibt den InhaltqueryResults
in eineresults.txt
Datei innerhalb der Zip-Datei.quelle
Mit Jeka https://jeka.dev JkPathTree ist das ganz einfach.
quelle
Es ist eine weitere Option , indem Sie
zip4j
bei https://github.com/srikanth-lingala/zip4jErstellen einer Zip-Datei mit einer einzelnen Datei / Hinzufügen einer einzelnen Datei zu einer vorhandenen Zip
new ZipFile("filename.zip").addFile("filename.ext");
Odernew ZipFile("filename.zip").addFile(new File("filename.ext"));
Erstellen einer Zip-Datei mit mehreren Dateien / Hinzufügen mehrerer Dateien zu einer vorhandenen Zip
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Erstellen einer Zip-Datei durch Hinzufügen eines Ordners / Hinzufügen eines Ordners zu einer vorhandenen Zip-Datei
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Erstellen einer Zip-Datei aus Stream / Hinzufügen eines Streams zu einer vorhandenen Zip
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
quelle