Eu tenho um arquivo de texto dinâmico que seleciona o conteúdo de um banco de dados de acordo com a consulta do usuário. Eu tenho que escrever esse conteúdo em um arquivo de texto e zipá-lo em uma pasta em um servlet. Como devo fazer isso?
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();
Isso criará um zip na raiz do D:named test.zipque conterá um único arquivo chamado mytext.txt. Obviamente, você pode adicionar mais entradas zip e também especificar um subdiretório como este:
ZipEntry e =newZipEntry("folderName/mytext.txt");
Você pode encontrar mais informações sobre compactação com Java aqui .
Por que as duas linhas estão byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);incluídas neste exemplo de código? Qual é o seu propósito?
precisa saber é
@kdzia, a primeira linha converte o valor StringBuilder em uma matriz de bytes e a segunda linha pega essa matriz de bytes e a grava no ZipEntry no arquivo "test.zip". Essas linhas são necessárias porque os arquivos Zip funcionam com matrizes de bytes, não com seqüências de caracteres.
OrangeWombat
3
Mas ... no exemplo acima, como o StringBuilder tem algo além de "Test String"? Também estou um pouco confuso com isso. Se você estiver gravando no sb.toString().getBytes()arquivo ZIP, seria de esperar que ele contenha os bytes do arquivo que está sendo compactado? Ou eu estou esquecendo de alguma coisa?
RobA 01/08/19
3
@ RobA você não está perdendo nada. O StringBuilder realmente deve conter o texto que o OP recebeu do banco de dados. O OP simplesmente precisaria substituir "Test String" (incluindo as aspas) por algo como getTextFromDatabase ()
Blueriver
Obrigado, @Blueriver
RobA
143
O Java 7 possui o ZipFileSystem embutido, que pode ser usado para criar, gravar e ler arquivos do arquivo zip.
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);}
Existe uma maneira de fazer isso funcionar se a extensão não for .zip? Preciso escrever um .fooarquivo, formatado exatamente como um arquivo zip, mas com uma extensão diferente. Eu sei que poderia criar um .ziparquivo e renomeá-lo, mas apenas criá-lo com o nome correto seria mais simples.
Troy Daniels
2
@TroyDaniels o exemplo acima também funciona com extensões diferentes, já que está usando o jar:file:prefixo para criar URI.
sivabalan
10
O único problema que pode aparecer aqui é que não funcionará caso você tenha diretórios. Portanto, por exemplo, se você tiver "/dir/SomeTextFile.txt" na pathInZipfilevariável, precisará criar o 'dir' dentro do arquivo .zip. Para isso, basta adicionar a próxima linha: Files.createDirectories(pathInZipfile.getParent())antes de chamar o Files.copymétodo.
D. Naumovich
como definir o nível de compressão?
cdalxndr
34
Para escrever um arquivo ZIP, use um ZipOutputStream. Para cada entrada que você deseja colocar no arquivo ZIP, você cria um objeto ZipEntry. Você passa o nome do arquivo para o construtor ZipEntry; Ele define os outros parâmetros, como data do arquivo e método de descompactação. Você pode substituir essas configurações, se quiser. Em seguida, chame o método putNextEntry do ZipOutputStream para começar a gravar um novo arquivo. Envie os dados do arquivo para o fluxo ZIP. Quando terminar, chame closeEntry. Repita para todos os arquivos que você deseja armazenar. Aqui está um esqueleto de código:
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();
Aqui está um código de exemplo para compactar um diretório inteiro (incluindo subarquivos e subdiretórios), usando o recurso walk file tree do Java NIO.
Você precisa principalmente criar duas funções. O primeiro é writeToZipFile () e o segundo é createZipfileForOutPut .... e depois chama o createZipfileForOutPut ('file name of .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();}}
Como demorei um pouco para descobrir, achei útil postar minha solução usando o Java 7+ ZipFileSystem
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);}}
Dadas exportPathe queryResultscomo variáveis String, o bloco a seguir cria um results.ziparquivo exportPathe grava o conteúdo de queryResultsum results.txtarquivo dentro do zip.
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);}
Criando um arquivo zip com um único arquivo / Adicionando arquivo único a um zip existente
new ZipFile("filename.zip").addFile("filename.ext");
Ou
new ZipFile("filename.zip").addFile(new File("filename.ext"));
Criando um arquivo zip com vários arquivos / Adicionando vários arquivos a um zip existente
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Criando um arquivo zip adicionando uma pasta a ele / Adicionando uma pasta a um zip existente
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Criando um arquivo zip a partir do fluxo / Adicionando um fluxo a um zip existente
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);
incluídas neste exemplo de código? Qual é o seu propósito?sb.toString().getBytes()
arquivo ZIP, seria de esperar que ele contenha os bytes do arquivo que está sendo compactado? Ou eu estou esquecendo de alguma coisa?O Java 7 possui o ZipFileSystem embutido, que pode ser usado para criar, gravar e ler arquivos do arquivo zip.
Documento Java: Provedor ZipFileSystem
fonte
.zip
? Preciso escrever um.foo
arquivo, formatado exatamente como um arquivo zip, mas com uma extensão diferente. Eu sei que poderia criar um.zip
arquivo e renomeá-lo, mas apenas criá-lo com o nome correto seria mais simples.jar:file:
prefixo para criar URI.pathInZipfile
variável, precisará criar o 'dir' dentro do arquivo .zip. Para isso, basta adicionar a próxima linha:Files.createDirectories(pathInZipfile.getParent())
antes de chamar oFiles.copy
método.Para escrever um arquivo ZIP, use um ZipOutputStream. Para cada entrada que você deseja colocar no arquivo ZIP, você cria um objeto ZipEntry. Você passa o nome do arquivo para o construtor ZipEntry; Ele define os outros parâmetros, como data do arquivo e método de descompactação. Você pode substituir essas configurações, se quiser. Em seguida, chame o método putNextEntry do ZipOutputStream para começar a gravar um novo arquivo. Envie os dados do arquivo para o fluxo ZIP. Quando terminar, chame closeEntry. Repita para todos os arquivos que você deseja armazenar. Aqui está um esqueleto de código:
fonte
Aqui está um código de exemplo para compactar um diretório inteiro (incluindo subarquivos e subdiretórios), usando o recurso walk file tree do Java NIO.
Para usar isso, basta ligar
e você obterá um arquivo zip directoryToCompress.zip
fonte
Controlador de inicialização Spring, zip os arquivos em um diretório e pode ser baixado.
fonte
fonte
É assim que você cria um arquivo zip a partir de um arquivo de origem:
fonte
Único arquivo:
Vários arquivos:
fonte
Você precisa principalmente criar duas funções. O primeiro é writeToZipFile () e o segundo é createZipfileForOutPut .... e depois chama o createZipfileForOutPut ('file name of .zip') `…
fonte
Se você deseja descompactar sem software, use melhor este código. Outro código com arquivos pdf envia erro ao descomprimir manualmente
fonte
Como demorei um pouco para descobrir, achei útil postar minha solução usando o Java 7+ ZipFileSystem
fonte
fonte
Dadas
exportPath
equeryResults
como variáveis String, o bloco a seguir cria umresults.zip
arquivoexportPath
e grava o conteúdo dequeryResults
umresults.txt
arquivo dentro do zip.fonte
Usando o Jeka https://jeka.dev JkPathTree, é bastante simples.
fonte
Não há outra opção, usando
zip4j
a https://github.com/srikanth-lingala/zip4jCriando um arquivo zip com um único arquivo / Adicionando arquivo único a um zip existente
new ZipFile("filename.zip").addFile("filename.ext");
Ounew ZipFile("filename.zip").addFile(new File("filename.ext"));
Criando um arquivo zip com vários arquivos / Adicionando vários arquivos a um zip existente
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));
Criando um arquivo zip adicionando uma pasta a ele / Adicionando uma pasta a um zip existente
new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));
Criando um arquivo zip a partir do fluxo / Adicionando um fluxo a um zip existente
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());
fonte