java.util.zip.ZipException:هناك عدد كبير جدًا من الإدخالات في ملف ZIP
-
20-08-2019 - |
سؤال
أحاول كتابة فئة Java لاستخراج ملف مضغوط كبير يحتوي على 74000 ملف XML تقريبًا.أحصل على الاستثناء التالي عند محاولة فك ضغطه باستخدام مكتبة Java Zip:
java.util.zip.ZipException:هناك عدد كبير جدًا من الإدخالات في ملف ZIP
لسوء الحظ، نظرًا لمتطلبات المشروع، لا يمكنني فك الملف المضغوط قبل أن يصل إليّ، ويجب أن تتم عملية فك الضغط تلقائيًا (بدون خطوات يدوية).هل هناك أي طريقة للتغلب على هذا القيد باستخدام java.util.zip أو مع بعض مكتبات Java المضغوطة التابعة لجهات خارجية؟
شكرًا.
المحلول
استخدام ZipInputStream
بدلاً من ZipFile
ربما ينبغي أن تفعل ذلك.
نصائح أخرى
باستخدام أباتشي IOUtils:
FileInputStream fin = new FileInputStream(zip);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
FileOutputStream fout = new FileOutputStream(new File(
outputDirectory, ze.getName()));
IOUtils.copy(zin, fout);
IOUtils.closeQuietly(fout);
zin.closeEntry();
}
IOUtils.closeQuietly(zin);
يدعم معيار Zip بحد أقصى 65536 إدخالًا في الملف.ما لم تدعم مكتبة Java امتدادات ZIP64، فلن تعمل بشكل صحيح إذا كنت تحاول قراءة أو كتابة أرشيف يحتوي على 74000 إدخال.
لقد قمت بإعادة صياغة الطريقة للتعامل مع هياكل الدليل بشكل أكثر ملاءمة ولضغط مجموعة كاملة من الأهداف في وقت واحد.ستتم إضافة الملفات العادية إلى جذر الملف المضغوط، وإذا قمت بتمرير دليل، فسيتم الحفاظ على البنية الأساسية.
def zip (String zipFile, String [] filesToZip){
def result = new ZipOutputStream(new FileOutputStream(zipFile))
result.withStream { zipOutStream ->
filesToZip.each {fileToZip ->
ftz = new File(fileToZip)
if(ftz.isDirectory()){
pathlength = new File(ftz.absolutePath).parentFile.absolutePath.size()
ftz.eachFileRecurse {f ->
if(!f.isDirectory()) writeZipEntry(f, zipOutStream, f.absolutePath[pathlength..-1])
}
}
else writeZipEntry(ftz, zipOutStream, '')
}
}
}
def writeZipEntry(File plainFile, ZipOutputStream zipOutStream, String path) {
zipOutStream.putNextEntry(new ZipEntry(path+plainFile.name))
new FileInputStream(plainFile).withStream { inStream ->
def buffer = new byte[1024]
def count
while((count = inStream.read(buffer, 0, 1024)) != -1)
zipOutStream.write(buffer)
}
zipOutStream.closeEntry()
}