ফাইলগুলি জিপ / আনজিপ করার জন্য একটি ভাল জাভা গ্রন্থাগার কী? [বন্ধ]


232

আমি ডিফল্ট জিপ লাইব্রেরিটি দেখেছি যা জেডিকে এবং অ্যাপাচি সংক্ষেপণের লিবসের সাথে আসে এবং আমি 3 কারণে তাদের সাথে অসন্তুষ্ট:

  1. এগুলি ফুলে গেছে এবং খারাপ এপিআই নকশা রয়েছে। আমাকে 50 লাইনের বয়লার প্লেট বাইট অ্যারের আউটপুট, জিপ ইনপুট, ফাইলগুলি প্রবাহ এবং প্রাসঙ্গিক স্ট্রিমগুলি বন্ধ করতে হবে এবং ব্যতিক্রমগুলি ধরতে হবে এবং বাইট বাফারগুলি আমার নিজের থেকে সরাতে হবে ? আমার কাছে এমন সরল API থাকতে পারে না যা দেখতে এই জাতীয় দেখায় Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null)এবং Zipper.zip(File targetDirectory, String password = null)এটি কার্যকরভাবে কাজ করে?

  2. মনে হচ্ছে জিপ করা আনজিপিং ফাইলের মেটা-ডেটা ধ্বংস করে এবং পাসওয়ার্ড হ্যান্ডলিং নষ্ট হয়ে গেছে।

  3. এছাড়াও, আমি যে সমস্ত লাইব্রেরি চেষ্টা করেছি সেগুলি ইউনিক্সের সাথে প্রাপ্ত কমান্ড লাইন জিপ সরঞ্জামগুলির তুলনায় 2-3x ধীর ছিল?

আমার জন্য (2) এবং (3) ছোটখাটো পয়েন্ট তবে আমি সত্যিই একটি লাইনের ইন্টারফেসের সাথে একটি ভাল পরীক্ষিত লাইব্রেরি চাই।


13
# 1 হিসাবে, এটি কারণ যে প্রত্যেকে কেবল একটি ডিরেক্টরিতে কোনও ফাইল আনজিপ করে না। আপনি যদি সর্বদা একই প্যাটার্নটি ব্যবহার করেন তবে কেন কেবল একটি ইউটিলিটি ক্লাস লিখবেন না যা অন্যদের মধ্যে একটিকে আবৃত করে এবং আপনার যা প্রয়োজন এবং কেবল এটি ব্যবহার করে ?
এডওয়ার্ড থমসন

14
@ অ্যাডওয়ার্ড থমসন কারণ কোড, টেস্ট কোড এবং কোড বজায় রাখার চেয়ে লাইব্রেরি ব্যবহার করা সহজ।
জাক

11
@ অ্যাডওয়ার্ড থমসন: আপনার যুক্তিটি অবৈধ। পাইথন জিপ এপিআই দেখুন: docs.python.org/3/library/zipfile । ফাইলগুলি জিপ বা আনজিপ করতে আপনার 1 লাইন কোডের প্রয়োজন। এপিআইগুলিকে সাধারণ কেসটি খুব ভালভাবে পরিচালনা করা উচিত এবং আমি জিপ এআইপি বা জিপিং বা আনজিপিংয়ের পাশাপাশি কোনও জিপ এপিআইয়ের কোনও ব্যবহারের ক্ষেত্রে ভাবতে পারি না।
প্যাথিক্রিট

7
@ উইট: একটি ফাইল জিপ করা বা কোনও ফাইল আনজিপ করা কোনও স্ট্রিমটি জিপ করা বা আনজিপ করা বিশেষ বিষয়। যদি আপনার এপিআই আমাকে এতে একটি স্ট্রিম লিখতে দেয় না এবং তার পরিবর্তে আমাকে কেবল একটি ফাইলে একটি স্ট্রিম লিখতে বাধ্য করে যাতে আমি আপনার এপিআইতে এটি খাওয়াতে পারি তবে আপনার এপিআই মস্তিষ্কে ক্ষতিগ্রস্থ হয়েছে।
এডওয়ার্ড থমসন

52
@ অ্যাডওয়ার্ড থমসন - ভাল, সুতরাং লাইব্রেরিকে ফাইল এবং স্ট্রিম উভয়ই সমর্থন করুন। এটি প্রত্যেকের সময় নষ্ট - আমার, আপনার, প্রশ্নকারী এবং অন্যান্য সমস্ত গুগল যারা এই বিষয়ে হোঁচট খাবেন যে আমাদের প্রত্যেককে আমাদের নিজস্ব জিপ ইউটিলিটিগুলি প্রয়োগ করতে হবে। DRY যেমন রয়েছে তেমনি ড্রপও রয়েছে - অন্য লোকদের পুনরাবৃত্তি করবেন না।
আর্টঅফ ওয়ারফেয়ার

উত্তর:


291

আমি এর দেরী জানি এবং প্রচুর উত্তর রয়েছে তবে আমি জিপ জিপ করার জন্য এই জিপ 4 জে অন্যতম সেরা গ্রন্থাগার। এটি সাধারণ (কোনও বয়লার কোড নেই) এবং সহজেই পাসওয়ার্ড সুরক্ষিত ফাইলগুলি পরিচালনা করতে পারে।

import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.core.ZipFile;


public static void unzip(){
    String source = "some/compressed/file.zip";
    String destination = "some/destination/folder";
    String password = "password";

    try {
         ZipFile zipFile = new ZipFile(source);
         if (zipFile.isEncrypted()) {
            zipFile.setPassword(password);
         }
         zipFile.extractAll(destination);
    } catch (ZipException e) {
        e.printStackTrace();
    }
}

ম্যাভেন নির্ভরতা হ'ল:

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>1.3.2</version>
</dependency>

1
আমি org.zeroturnaround.zip.ZipException পেয়েছি: java.io.FileNotFoundException: images \ 001GL.JPG: ওপেন ব্যর্থ হয়েছে: EINVAL (অবৈধ যুক্তি) ত্রুটি
স্মিত প্যাটেল

4
এটি কি অ্যান্ড্রয়েডের সাথে কাজ করে?
এর্কান

1
না এটি অ্যান্ড্রয়েডের সাথে কাজ করে না, এটি চীনা ভাষাকে সমর্থন করে না।
ধীরাজ হিমানি

3
জিপ 4 জে কেবলমাত্র ডিস্ক থেকে ইনপুটস্ট্রিমে একটি জিপ পড়া সমর্থন করে না।
রেনেউদ সেরারাতো

2
ওয়েবসাইটে কোনও জাভাদোক আছে বলে মনে হচ্ছে না।
জনসি

76

সঙ্গে এ্যাপাচি কমন্স-আই 's IOUtilsআপনি এটা করতে পারেন:

try (java.util.zip.ZipFile zipFile = new ZipFile(file)) {
  Enumeration<? extends ZipEntry> entries = zipFile.entries();
  while (entries.hasMoreElements()) {
    ZipEntry entry = entries.nextElement();
    File entryDestination = new File(outputDir,  entry.getName());
    if (entry.isDirectory()) {
        entryDestination.mkdirs();
    } else {
        entryDestination.getParentFile().mkdirs();
        try (InputStream in = zipFile.getInputStream(entry);
             OutputStream out = new FileOutputStream(entryDestination)) {
            IOUtils.copy(in, out);
        }
    }
  }
}

এটি এখনও কিছু বয়লারপ্লিট কোড, তবে এটিতে কেবল 1 বহিরাগত নির্ভরশীলতা রয়েছে: কমন্স-আইও


1
@ ভিটালিস্যাজনোভিচ আপনি জাভা 7 জিপইন্ট্রি সম্পর্কে উল্লেখ করছেন।
রেন্ডি

2
ধন্যবাদ। শেষে zipFile.close () দরকার।
জোশুয়াডি

4
আইওউটিলস.ক্লোসিওয়েটলি (আউট) কেন নয়?
হুয়ান মেন্ডিজ

2
@ জুয়ানমেন্ডেজ কারন যদি বন্ধে ত্রুটি থাকে তবে আপনি নিশ্চিত হতে পারবেন না যে ফাইলটি পুরো এবং সঠিকভাবে সংরক্ষণ করা হয়েছিল। তবে অতিরিক্ত হিসাবে close()এটি আঘাত করবে না।
ভাদিপ

3
এই সমাধানটি জিপস্লিপের পক্ষে ঝুঁকিপূর্ণ (zip4j এছাড়াও প্রভাবিত )
Marcono1234

40

জিপি ফাইল এবং এর সমস্ত সাবফোল্ডারগুলি কেবল জেডিকে ব্যবহার করে এক্সট্রাক্ট করুন:

private void extractFolder(String zipFile,String extractFolder) 
{
    try
    {
        int BUFFER = 2048;
        File file = new File(zipFile);

        ZipFile zip = new ZipFile(file);
        String newPath = extractFolder;

        new File(newPath).mkdir();
        Enumeration zipFileEntries = zip.entries();

        // Process each entry
        while (zipFileEntries.hasMoreElements())
        {
            // grab a zip file entry
            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
            String currentEntry = entry.getName();

            File destFile = new File(newPath, currentEntry);
            //destFile = new File(newPath, destFile.getName());
            File destinationParent = destFile.getParentFile();

            // create the parent directory structure if needed
            destinationParent.mkdirs();

            if (!entry.isDirectory())
            {
                BufferedInputStream is = new BufferedInputStream(zip
                .getInputStream(entry));
                int currentByte;
                // establish buffer for writing file
                byte data[] = new byte[BUFFER];

                // write the current file to disk
                FileOutputStream fos = new FileOutputStream(destFile);
                BufferedOutputStream dest = new BufferedOutputStream(fos,
                BUFFER);

                // read and write until last byte is encountered
                while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, currentByte);
                }
                dest.flush();
                dest.close();
                is.close();
            }


        }
    }
    catch (Exception e) 
    {
        Log("ERROR: "+e.getMessage());
    }

}

জিপ ফাইল এবং এর সমস্ত সাবফোল্ডার:

 private void addFolderToZip(File folder, ZipOutputStream zip, String baseName) throws IOException {
    File[] files = folder.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            addFolderToZip(file, zip, baseName);
        } else {
            String name = file.getAbsolutePath().substring(baseName.length());
            ZipEntry zipEntry = new ZipEntry(name);
            zip.putNextEntry(zipEntry);
            IOUtils.copy(new FileInputStream(file), zip);
            zip.closeEntry();
        }
    }
}

7
বন্ধ করার কলগুলি খুব কমপক্ষে "অবশেষে" ব্লকের ভিতরে থাকা উচিত। ব্যতিক্রমগুলি ভালভাবে পরিচালনা করা হয় না। -> আমার ধারণা, ওপি কেন লাইব্রেরিটি ব্যবহার করতে বলেছিল ।

4
এটি অনেক বেশি কোড। এটি 2 লাইনে করা যেতে পারে।
মাক্কি

/mnt/sdcard/final_unzip_data/Product_images\001GL.JPG: ওপেন ব্যর্থ হয়েছে: EINVAL (অবৈধ যুক্তি)
স্মিত প্যাটেল

@ জো মাইকেল এটি পোস্ট করার জন্য ধন্যবাদ বন্ধু। এটি আমার সমস্যা সমাধান করে। আমি আপনাকে +1 দেবextractFolder(String zipFile,String extractFolder)
OO7

এই কোডটি ফাইলের বৈশিষ্ট্য এবং অনুমতিগুলি রাখে না ... আপনি যদি রান চালিত অ্যাপ্লিকেশনটি আনজিপ করতে এই জাতীয় কিছু ব্যবহার করেন তবে ফাইল অনুমতি সম্পর্কিত অদ্ভুত ত্রুটির জন্য প্রস্তুত থাকুন। এতে আমার এক সপ্তাহ মাথা ব্যাথা ব্যয় হয়েছে।
রেনাটো

23

আরেকটি বিকল্প যা আপনি যাচাই করতে পারবেন তা হ'ল ম্যাকেন কেন্দ্রীয় এবং প্রকল্প পৃষ্ঠা থেকে জিটিটি-জিপ https://github.com/zeroturnaround/zt-zip এ উপলব্ধ

এটিতে স্ট্যান্ডার্ড প্যাকিং এবং আনপ্যাকিং কার্যকারিতা রয়েছে (স্ট্রিমে এবং ফাইল সিস্টেমে) + একটি সংরক্ষণাগারে ফাইলগুলির জন্য পরীক্ষার জন্য বা এন্ট্রিগুলি যুক্ত / সরিয়ে ফেলতে প্রচুর সহায়ক সহায়ক পদ্ধতি।


17

জিপ / পুরো ফাইলটি জিপ 4 জে একটি ফোল্ডার / ফাইল আনজিপ করুন lement


এখান থেকে জারটি ডাউনলোড করুন এবং এটি আপনার প্রকল্পের পথে যুক্ত করুন। classনিচে কম্প্রেস এবং বা পাসওয়ার্ড ছাড়াই যেকোনো ফাইল অথবা ফোল্ডার, নিষ্কাশন করতে পারেন protection-

import java.io.File;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import net.lingala.zip4j.core.ZipFile;  

public class Compressor {
    public static void zip(String targetPath, String destinationFilePath, String password) {
        try {
            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

            if(password.length()>0){
                parameters.setEncryptFiles(true);
                parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
                parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
                parameters.setPassword(password);
            }

            ZipFile zipFile = new ZipFile(destinationFilePath);

            File targetFile = new File(targetPath);
            if(targetFile.isFile()){
                zipFile.addFile(targetFile, parameters);
            }else if(targetFile.isDirectory()){
                zipFile.addFolder(targetFile, parameters);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void unzip(String targetZipFilePath, String destinationFolderPath, String password) {
        try {
            ZipFile zipFile = new ZipFile(targetZipFilePath);
            if (zipFile.isEncrypted()) {
                zipFile.setPassword(password);
            }
            zipFile.extractAll(destinationFolderPath);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**/ /// for test only
    public static void main(String[] args) {

        String targetPath = "target\\file\\or\\folder\\path";
        String zipFilePath = "zip\\file\\Path"; 
        String unzippedFolderPath = "destination\\folder\\path";
        String password = "your_password"; // keep it EMPTY<""> for applying no password protection

        Compressor.zip(targetPath, zipFilePath, password);
        Compressor.unzip(zipFilePath, unzippedFolderPath, password);
    }/**/
}

1
একটি দুর্দান্ত উত্তর এবং গ্রন্থাগার। জিপআইপুট স্ট্রিম ব্যবহার করার সময় 20+ মিনিটের তুলনায় 1868 ফাইলগুলি আঁকতে 15 সেকেন্ড সময় লেগেছে (কোনও কারণে)
জোনটি 800

8

একটি খুব সুন্দর প্রকল্প হ'ল ট্রুজিপ

ট্রুজেআইপি হ'ল ভার্চুয়াল ফাইল সিস্টেমগুলির জন্য একটি জাভা ভিত্তিক প্লাগ-ইন কাঠামো (ভিএফএস) যা সংরক্ষণাগার ফাইলগুলিতে স্বচ্ছ অ্যাক্সেস সরবরাহ করে যেমন তারা কেবল সরল ডিরেক্টরি

উদাহরণস্বরূপ ( ওয়েবসাইট থেকে ):

File file = new TFile("archive.tar.gz/README.TXT");
OutputStream out = new TFileOutputStream(file);
try {
   // Write archive entry contents here.
   ...
} finally {
   out.close();
}

লাইব্রেরিটি দেখতে দুর্দান্ত দেখাচ্ছে - এখনও কোনও জিপিনপুটসট্রিম / ফাইল / পাথের সাহায্যে কীভাবে জিপ-ফাইলটি আনজিপ করা যায় তা এখনও স্পষ্ট নয়।
প্যাথিক্রিট

1
ট্রুজেপআইপি স্ট্রীমগুলি থেকে পড়া খুব ভালভাবে পরিচালনা করছে বলে মনে হয় না।
টিও ক্লেস্ট্রাপ রাইজেজন

5
এটি জাভা in-এ আপনি যা করতে পারেন তেমন নয়? ( জিপফাইলে সিস্টেমপ্রভাইডারটি দেখুন )।
পিটার

1
@ পেটার: স্ট্যান্ডার্ড-জেডিকে জিপফাইলে সিস্টেমপ্রভাইডারটি একটি ভাল উত্তর হবে। এটি কম লোকই মন্তব্য হিসাবে দেখেন।
আইউজুজ

3

আরেকটি বিকল্প হ'ল জেডলিব । আমার অভিজ্ঞতায় এটি zip4J এর চেয়ে কম "ফাইল-কেন্দ্রিক", সুতরাং আপনার যদি ফাইলগুলির চেয়ে মেমরি ব্লবগুলিতে কাজ করার দরকার হয় তবে আপনি এটি একবার দেখে নিতে পারেন।



0

আপনি কি http://commons.apache.org/vfs/ এ একবার দেখেছেন? ? এটি আপনার জন্য অনেক কিছু সহজ করার দাবি করে। তবে আমি কখনই এটি কোনও প্রকল্পে ব্যবহার করি নি।

আমি জেডি কে বা অ্যাপাচি সংকোচনের বাদে জাভা-নেটিভ সংক্ষেপণের লিবস সম্পর্কে অবগত নই।

আমার মনে আছে একবার আমরা অ্যাপাচি পিঁপড়ের কিছু বৈশিষ্ট্য ছিঁড়ে ফেলেছি - তাদের মধ্যে সংকোচনের / ডিকম্প্রেশনটির জন্য প্রচুর ব্যবহার রয়েছে।

ভিএফএস সহ নমুনা কোডটি দেখতে পাবেন:

File zipFile = ...;
File outputDir = ...;
FileSystemManager fsm = VFS.getManager();
URI zip = zipFile.toURI();
FileObject packFileObject = fsm.resolveFile(packLocation.toString());
FileObject to = fsm.toFileObject(destDir);
FileObject zipFS;
try {
    zipFS = fsm.createFileSystem(packFileObject);
    fsm.toFileObject(outputDir).copyFrom(zipFS, new AllFileSelector());
} finally {
    zipFS.close();
}

1
দেখে মনে হচ্ছে ভিএফএস স্টাফের
টিজে ক্রাউডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.