जावा में ज़िप फाइल कैसे बनाएं


149

मेरे पास एक डायनामिक टेक्स्ट फ़ाइल है जो उपयोगकर्ता की क्वेरी के अनुसार डेटाबेस से सामग्री चुनती है। मुझे इस सामग्री को एक टेक्स्ट फ़ाइल में लिखना है और इसे एक सर्वलेट में एक फ़ोल्डर में ज़िप करना है। मुझे यह कैसे करना चाहिए?

जवाबों:


231

इस उदाहरण को देखें:

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();

यह D:नाम की जड़ में एक ज़िप test.zipबनाएगा जिसमें एक एकल फ़ाइल होगी mytext.txt। बेशक आप अधिक ज़िप प्रविष्टियाँ जोड़ सकते हैं और इस तरह एक उपनिर्देशिका भी निर्दिष्ट कर सकते हैं:

ZipEntry e = new ZipEntry("folderName/mytext.txt");

आप यहाँ जावा के साथ संपीड़न के बारे में अधिक जानकारी पा सकते हैं ।


1
दो byte[] data = sb.toString().getBytes(); out.write(data, 0, data.length);कोड क्यों हैं: इस कोड नमूने में शामिल हैं? उनका उद्देश्य क्या है?
कादज़िया

@kdzia, पहली पंक्ति StringBuilder मान को बाइट सरणी में रूपांतरित करती है, और दूसरी पंक्ति उस बाइट सरणी को ले जाती है और इसे "test.zip" फ़ाइल के भीतर ZipEntry पर लिखती है। ये लाइनें आवश्यक हैं क्योंकि ज़िप फाइलें बाइट सरणियों के साथ काम करती हैं, तार नहीं।
ऑरेंजवॉम्बैट

3
लेकिन ... ऊपर दिए गए उदाहरण में, "टेस्ट स्ट्रिंग" के अलावा स्ट्रिंगरब्युट्रल में कुछ भी कैसे है? मैं इससे थोड़ा भ्रमित भी हूँ। यदि आप sb.toString().getBytes()ज़िप फ़ाइल में लिख रहे हैं , तो मुझे उम्मीद है कि आप इसे उस फ़ाइल के बाइट्स में शामिल करेंगे जो आप ज़िप कर रहे हैं? या क्या मैं कुछ न कुछ भूल रहा हूं?
रोबा

3
@ रोबा आप कुछ भी याद नहीं कर रहे हैं। StringBuilder वास्तव में ओपी अपने डेटाबेस से मिला पाठ शामिल करने के लिए है। ओपी को बस "टेस्ट स्ट्रिंग" (उद्धरण सहित) को कुछ के लिए बदलना होगा जैसे getTextFromDatabase ()
Blueriver

धन्यवाद, @Blueriver
रोबा

143

Java 7 में ZIPFileSystem बनाया गया है, जिसका उपयोग ज़िप फ़ाइल से फ़ाइल बनाने, लिखने और पढ़ने के लिए किया जा सकता है।

जावा डॉक्टर: जिपफाइलसिस्टम प्रदाता

Map<String, String> env = new HashMap<>();
// 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 file
    Files.copy(externalTxtFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING); 
}

1
अगर विस्तार नहीं है तो क्या यह काम करने का कोई तरीका है .zip? मुझे एक .fooफ़ाइल लिखने की ज़रूरत है , जो बिल्कुल ज़िप फ़ाइल की तरह स्वरूपित है, लेकिन एक अलग एक्सटेंशन के साथ। मुझे पता है कि मैं एक .zipफ़ाइल बना सकता हूं और उसका नाम बदल सकता हूं , लेकिन सिर्फ सही नाम से इसे बनाना सरल होगा।
ट्रॉय डेनियल

2
@TroyDaniels ऊपर का उदाहरण अलग-अलग एक्सटेंशन के साथ काम करता है, क्योंकि इसके jar:file:उपसर्ग का उपयोग करके URI बनाया जाता है।
शिवबालन

10
एकमात्र मुद्दा जो यहां दिखाई दे सकता है वह यह है कि आपके पास निर्देशिकाओं के मामले में यह काम नहीं करेगा। इसलिए, उदाहरण के लिए, यदि आपके पास pathInZipfileचर में "/dir/SomeTextFile.txt" है, तो आपको .zip संग्रह के अंदर 'dir' बनाने की आवश्यकता है। इसके लिए, अगली विधि जोड़ें: विधि Files.createDirectories(pathInZipfile.getParent())लागू Files.copyकरने से पहले ।
डी। नौमोविच

संपीड़न स्तर कैसे सेट करें?
cdalxndr

34

ज़िप फ़ाइल लिखने के लिए, आप एक ZIPOutputStream का उपयोग करें। प्रत्येक प्रविष्टि के लिए जिसे आप ZIP फ़ाइल में रखना चाहते हैं, आप एक ZipEntry ऑब्जेक्ट बनाते हैं। आप फ़ाइल नाम को ZipEntry कंस्ट्रक्टर से गुजारें; यह फ़ाइल तिथि और विघटन विधि जैसे अन्य मापदंडों को निर्धारित करता है। आप चाहें तो इन सेटिंग्स को ओवरराइड कर सकते हैं। उसके बाद, आप एक नई फ़ाइल लिखना प्रारंभ करने के लिए ZipOutputStream की putNextEntry विधि को कॉल करें। जिप स्ट्रीम में फाइल डेटा भेजें। जब आप काम पूरा कर लेते हैं, तो कॉल करें बंद करें। उन सभी फाइलों को दोहराएं जिन्हें आप स्टोर करना चाहते हैं। यहाँ एक कोड कंकाल है:

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();

22

यहां एक संपूर्ण निर्देशिका (उप फ़ाइलों और उप निर्देशिकाओं सहित ) को संपीड़ित करने के लिए एक उदाहरण कोड है , यह जावा एनआईओ की वॉक फाइल ट्री सुविधा का उपयोग कर रहा है।

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) {
        final Path sourceDir = Paths.get(dirPath);
        String zipFileName = dirPath.concat(".zip");
        try {
            final 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();
        }
    }
}

इसका उपयोग करने के लिए, बस कॉल करें

ZipCompress.compress("target/directoryToCompress");

और आपको एक ज़िप फ़ाइल निर्देशिका मिल जाएगी ToCompress.zip


4

स्प्रिंग बूट नियंत्रक, फ़ाइलों को एक निर्देशिका में ज़िप करें, और डाउनलोड किया जा सकता है।

@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();
}

2
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");
    }
 }    

}

2

यह है कि आप स्रोत फ़ाइल से ज़िप फ़ाइल कैसे बनाते हैं:

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);
}

1

एक दस्तावेज:

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);
}

कई फाइलें:

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);
    }
}

1

आपको मुख्य रूप से दो कार्य करने होंगे। पहला है राइटटोजीपफाइल () और दूसरा है क्रिएटजिफाइलफॉरऑउटपुत .... और फिर क्रिएटजाइफाइलफॉरऑउटपुत ('.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();
    }
}

0

यदि आप सॉफ्टवेयर के बिना डीकंप्रेस करना चाहते हैं तो इस कोड का बेहतर उपयोग करें। पीडीएफ फाइलों के साथ अन्य कोड मैन्युअल डिकम्प्रेस पर त्रुटि भेजता है

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();
    }

0

चूंकि मुझे इसका पता लगाने में थोड़ा समय लगा, इसलिए मैंने सोचा कि जावा 7+ ज़िपफाइल सिस्टम का उपयोग करके अपने समाधान को पोस्ट करना उपयोगी होगा।

 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);            
    }
 }

0
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());
        }
    }
}

0

दिए गए exportPathऔर queryResultsस्ट्रिंग चर के रूप में, निम्न ब्लॉक के results.zipतहत एक फ़ाइल बनाता है exportPathऔर ज़िप के अंदर queryResultsएक results.txtफ़ाइल की सामग्री लिखता है ।

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);
}


0

Https://github.com/srikanth-lingala/zip4jzip4j पर उपयोग करके एक और विकल्प है

इसमें सिंगल फाइल के साथ जिप फाइल बनाना / मौजूदा जिप में सिंगल फाइल जोड़ना

new ZipFile("filename.zip").addFile("filename.ext"); या

new ZipFile("filename.zip").addFile(new File("filename.ext"));

कई फ़ाइलों के साथ एक ज़िप फ़ाइल बनाना / मौजूदा ज़िप में कई फ़ाइलों को जोड़ना

new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));

इसमें एक फ़ोल्डर जोड़कर एक ज़िप फ़ाइल बनाना / मौजूदा ज़िप में एक फ़ोल्डर जोड़ना

new ZipFile("filename.zip").addFolder(new File("/user/myuser/folder_to_add"));

धारा से एक ज़िप फ़ाइल बनाना / एक मौजूदा ज़िप में एक धारा जोड़ना new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.