J'ai un fichier texte dynamique qui sélectionne le contenu d'une base de données en fonction de la requête de l'utilisateur. Je dois écrire ce contenu dans un fichier texte et le compresser dans un dossier dans une servlet. Comment dois-je faire cela?
Regardez cet exemple:
StringBuilder sb = new StringBuilder();
sb.append("Test String");
File f = new File("d:\\test.Zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
ZipEntry e = new ZipEntry("mytext.txt");
out.putNextEntry(e);
byte[] data = sb.toString().getBytes();
out.write(data, 0, data.length);
out.closeEntry();
out.close();
Cela créera un fichier Zip situé dans la racine de D: nommé 'test.Zip', qui contiendra un seul fichier appelé 'mytext.txt'. Bien sûr, vous pouvez ajouter plus d'entrées Zip et également spécifier un sous-répertoire comme:
ZipEntry e = new ZipEntry("folderName/mytext.txt");
Vous trouverez plus d'informations sur la compression avec Java ici:
http://www.Oracle.com/technetwork/articles/Java/compress-1565076.html
Java 7 a ZipFileSystem intégré, qui peut être utilisé pour créer, écrire et lire des fichiers à partir de fichiers Zip.
Java Doc: Fournisseur ZipFileSystem
Map<String, String> env = new HashMap<>();
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 file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
Pour écrire un fichier Zip, vous utilisez un ZipOutputStream. Pour chaque entrée que vous souhaitez placer dans le fichier Zip, vous créez un objet ZipEntry. Vous transmettez le nom du fichier au constructeur ZipEntry. il définit les autres paramètres tels que la date du fichier et la méthode de décompression. Vous pouvez remplacer ces paramètres si vous le souhaitez. Ensuite, vous appelez la méthode putNextEntry de ZipOutputStream pour commencer à écrire un nouveau fichier. Envoyez les données du fichier au flux Zip. Lorsque vous avez terminé, appelez closeEntry. Répétez l'opération pour tous les fichiers que vous souhaitez stocker. Voici un squelette de code:
FileOutputStream fout = new FileOutputStream("test.Zip");
ZipOutputStream zout = new ZipOutputStream(fout);
for all files
{
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
send data to zout;
zout.closeEntry();
}
zout.close();
Voici un exemple de code permettant de compresser un répertoire entier (y compris les sous-fichiers et les sous-répertoires), qui utilise la fonctionnalité d'arborescence de fichiers de type Java NIO.
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.nio.file.*;
import Java.nio.file.attribute.BasicFileAttributes;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipOutputStream;
public class ZipCompress {
public static void compress(String dirPath) {
Path sourceDir = Paths.get(dirPath);
String zipFileName = dirPath.concat(".Zip");
try {
ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
try {
Path targetFile = sourceDir.relativize(file);
outputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = Files.readAllBytes(file);
outputStream.write(bytes, 0, bytes.length);
outputStream.closeEntry();
} catch (IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
});
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pour l'utiliser, il suffit d'appeler
ZipCompress.compress("target/directoryToCompress");
et vous obtiendrez un répertoire de fichiers Zip vers Compress.Zip
public static void main(String args[])
{
omtZip("res/", "omt.Zip");
}
public static void omtZip(String path,String outputFile)
{
final int BUFFER = 2048;
boolean isEntry = false;
ArrayList<String> directoryList = new ArrayList<String>();
File f = new File(path);
if(f.exists())
{
try {
FileOutputStream fos = new FileOutputStream(outputFile);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte data[] = new byte[BUFFER];
if(f.isDirectory())
{
//This is Directory
do{
String directoryName = "";
if(directoryList.size() > 0)
{
directoryName = directoryList.get(0);
System.out.println("Directory Name At 0 :"+directoryName);
}
String fullPath = path+directoryName;
File fileList = null;
if(directoryList.size() == 0)
{
//Main path (Root Directory)
fileList = f;
}else
{
//Child Directory
fileList = new File(fullPath);
}
String[] filesName = fileList.list();
int totalFiles = filesName.length;
for(int i = 0 ; i < totalFiles ; i++)
{
String name = filesName[i];
File filesOrDir = new File(fullPath+name);
if(filesOrDir.isDirectory())
{
System.out.println("New Directory Entry :"+directoryName+name+"/");
ZipEntry entry = new ZipEntry(directoryName+name+"/");
zos.putNextEntry(entry);
isEntry = true;
directoryList.add(directoryName+name+"/");
}else
{
System.out.println("New File Entry :"+directoryName+name);
ZipEntry entry = new ZipEntry(directoryName+name);
zos.putNextEntry(entry);
isEntry = true;
FileInputStream fileInputStream = new FileInputStream(filesOrDir);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER);
int size = -1;
while( (size = bufferedInputStream.read(data, 0, BUFFER)) != -1 )
{
zos.write(data, 0, size);
}
bufferedInputStream.close();
}
}
if(directoryList.size() > 0 && directoryName.trim().length() > 0)
{
System.out.println("Directory removed :"+directoryName);
directoryList.remove(0);
}
}while(directoryList.size() > 0);
}else
{
//This is File
//Zip this file
System.out.println("Zip this file :"+f.getPath());
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis,BUFFER);
ZipEntry entry = new ZipEntry(f.getName());
zos.putNextEntry(entry);
isEntry = true;
int size = -1 ;
while(( size = bis.read(data,0,BUFFER)) != -1)
{
zos.write(data, 0, size);
}
}
//CHECK IS THERE ANY ENTRY IN Zip ? ----START
if(isEntry)
{
zos.close();
}else
{
zos = null;
System.out.println("No Entry Found in Zip");
}
//CHECK IS THERE ANY ENTRY IN Zip ? ----START
}catch(Exception e)
{
e.printStackTrace();
}
}else
{
System.out.println("File or Directory not found");
}
}
}
Contrôleur de démarrage du printemps, compresser les fichiers dans un répertoire et les télécharger.
@RequestMapping(value = "/files.Zip")
@ResponseBody
byte[] filesZip() throws IOException {
File dir = new File("./");
File[] filesArray = dir.listFiles();
if (filesArray == null || filesArray.length == 0)
System.out.println(dir.getAbsolutePath() + " have no file!");
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ZipOutputStream zipOut= new ZipOutputStream(bo);
for(File xlsFile:filesArray){
if(!xlsFile.isFile())continue;
ZipEntry zipEntry = new ZipEntry(xlsFile.getName());
zipOut.putNextEntry(zipEntry);
zipOut.write(IOUtils.toByteArray(new FileInputStream(xlsFile)));
zipOut.closeEntry();
}
zipOut.close();
return bo.toByteArray();
}
Voici comment créer un fichier Zip à partir d'un fichier source:
String srcFilename = "C:/myfile.txt";
String zipFile = "C:/myfile.Zip";
try {
byte[] buffer = new byte[1024];
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(srcFilename);
FileInputStream fis = new FileInputStream(srcFile);
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
zos.close();
}
catch (IOException ioe) {
System.out.println("Error creating Zip file" + ioe);
}
Zip4j utilise entièrement du code Java sans aucune prise en charge du code natif, et c’est ce qui en fait un meilleur choix pour moi . Zip4j fournit les fonctionnalités suivantes:
CreatePasswordProtectedZipExample.Java
import Java.io.File;
import Java.util.ArrayList;
import net.lingala.Zip4j.core.ZipFile;
import net.lingala.Zip4j.exception.ZipException;
import net.lingala.Zip4j.model.ZipParameters;
import net.lingala.Zip4j.util.Zip4jConstants;
public class CreatePasswordProtectedZipExample
{
public static void main(String[] args)
{
try {
//This is name and path of Zip file to be created
ZipFile zipFile = new ZipFile("C:/temp/test.Zip");
//Add files to be archived into Zip file
ArrayList<File> filesToAdd = new ArrayList<File>();
filesToAdd.add(new File("C:/temp/test1.txt"));
filesToAdd.add(new File("C:/temp/test2.txt"));
//Initiate Zip Parameters which define various properties
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to deflate compression
//DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression
//DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression
//DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed
//DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed
//DEFLATE_LEVEL_ULTRA - Highest compression level but low speed
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//Set the encryption flag to true
parameters.setEncryptFiles(true);
//Set the encryption method to AES Zip Encryption
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//AES_STRENGTH_128 - For both encryption and decryption
//AES_STRENGTH_192 - For decryption only
//AES_STRENGTH_256 - For both encryption and decryption
//Key strength 192 cannot be used for encryption. But if a Zip file already has a
//file encrypted with key strength of 192, then Zip4j can decrypt this file
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//Set password
parameters.setPassword("howtodoinjava");
//Now add files to the Zip file
zipFile.addFiles(filesToAdd, parameters);
}
catch (ZipException e)
{
e.printStackTrace();
}
}
}
Vous devez principalement créer deux fonctions. La première est writeToZipFile () et la deuxième est createZipfileForOutPut ...., puis appelez le createZipfileForOutPut ('nom de fichier de .Zip') `…
public static void writeToZipFile(String path, ZipOutputStream zipStream)
throws FileNotFoundException, IOException {
System.out.println("Writing file : '" + path + "' to Zip file");
File aFile = new File(path);
FileInputStream fis = new FileInputStream(aFile);
ZipEntry zipEntry = new ZipEntry(path);
zipStream.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipStream.write(bytes, 0, length);
}
zipStream.closeEntry();
fis.close();
}
public static void createZipfileForOutPut(String filename) {
String home = System.getProperty("user.home");
// File directory = new File(home + "/Documents/" + "AutomationReport");
File directory = new File("AutomationReport");
if (!directory.exists()) {
directory.mkdir();
}
try {
FileOutputStream fos = new FileOutputStream("Path to your destination" + filename + ".Zip");
ZipOutputStream zos = new ZipOutputStream(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();
}
}
Un seul fichier:
String filePath = "/absolute/path/file1.txt";
String zipPath = "/absolute/path/output.Zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
Plusieurs fichiers:
List<String> filePaths = Arrays.asList("/absolute/path/file1.txt", "/absolute/path/file2.txt");
String zipPath = "/absolute/path/output.Zip";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))) {
for (String filePath : filePaths) {
File fileToZip = new File(filePath);
zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));
Files.copy(fileToZip.toPath(), zipOut);
}
}
Comme il m'a fallu un certain temps pour le comprendre, j'ai pensé qu'il serait utile de publier ma solution avec Java 7 + ZipFileSystem
openZip(runFile);
addToZip(filepath); //loop construct;
zipfs.close();
private void openZip(File runFile) throws IOException {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
env.put("encoding", "UTF-8");
Files.deleteIfExists(runFile.toPath());
zipfs = FileSystems.newFileSystem(URI.create("jar:" + runFile.toURI().toString()), env);
}
private void addToZip(String filename) throws IOException {
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 case
if (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 file
Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
}
}
Si vous voulez décompresser sans logiciel, utilisez mieux ce code. L'autre code avec les fichiers pdf envoie une erreur en décompressant manuellement
byte[] buffer = new byte[1024];
try
{
FileOutputStream fos = new FileOutputStream("123.Zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry("file.pdf");
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream("file.pdf");
int len;
while ((len = in.read(buffer)) > 0)
{
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
Étant donné que exportPath
et queryResults
sont des variables de chaîne, le bloc suivant crée un fichier results.Zip
sous exportPath
et écrit le contenu de queryResults
dans un fichier results.txt
à l'intérieur du 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);
}
Utiliser Jeka https://jeka.dev JkPathTree, c'est assez simple.
Path wholeDirToZip = Paths.get("dir/to/Zip");
Path zipFile = Paths.get("file.Zip");
JkPathTree.of(wholeDirToZip).zipTo(zipFile);
public static void zipFromTxt(String zipFilePath, String txtFilePath) {
Assert.notNull(zipFilePath, "Zip file path is required");
Assert.notNull(txtFilePath, "Txt file path is required");
zipFromTxt(new File(zipFilePath), new File(txtFilePath));
}
public static void zipFromTxt(File zipFile, File txtFile) {
ZipOutputStream out = null;
FileInputStream in = null;
try {
Assert.notNull(zipFile, "Zip file is required");
Assert.notNull(txtFile, "Txt file is required");
out = new ZipOutputStream(new FileOutputStream(zipFile));
in = new FileInputStream(txtFile);
out.putNextEntry(new ZipEntry(txtFile.getName()));
int len;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
out.flush();
}
} catch (Exception e) {
log.info("Zip from txt occur error,Detail message:{}", e.toString());
} finally {
try {
if (in != null) in.close();
if (out != null) {
out.closeEntry();
out.close();
}
} catch (Exception e) {
log.info("Zip from txt close error,Detail message:{}", e.toString());
}
}
}