إعادة تسمية ملف/مجلد داخل ملف مضغوط في جافا ؟

StackOverflow https://stackoverflow.com/questions/847892

  •  21-08-2019
  •  | 
  •  

سؤال

لدي ملف مضغوط يحتوي على مجلد بنية مثل

  • الرئيسية-مجلد/
    • subFolder1/
    • subFolder2/
    • subFolder3/
      • file3.1
      • file3.2

وأود أن إعادة تسمية المجلد main-folder إلى دعنا نقول versionXY داخل هذا الملف المضغوط باستخدام جافا.

هل هناك طريقة أسهل من استخراج كل ملف مضغوط ثم إعادة إنشاء واحدة جديدة باستخدام المجلد الجديد أسماء ؟

هل كانت مفيدة؟

المحلول

الرمز البريدي الأرشيف شكل, حتى تحور عموما ينطوي على إعادة كتابة الملف.

بعض السمات الرمز البريدي أيضا في الحصول على الطريق (zip هو الكامل من "ميزات").وكذلك الدليل المركزي في نهاية الأرشيف ، كل عنصر الملف يسبقه اسم الملف.الرمز البريدي لا مفهوم الدلائل - أسماء الملفات فقط السلاسل التي يحدث "/" الشخصيات (و سلاسل فرعية مثل "../".

إذا كنت بحاجة إلى نسخ ملف باستخدام ZipInputStream و ZipOutputStream, تسمية كما تذهب.إذا كنت تريد حقا أن يمكنك كتابة الملف في مكان العمل الخاص بك في التخزين المؤقت.العملية لا تسبب المحتويات إلى أن الذي أوصت ضغط القياسية API لا يعني الحصول على البيانات في نموذج مضغوط.

نصائح أخرى

أعلم أنك سألت عن جافا ولكن فقط لأغراض الأرشيف فكرت في أن تسهم مذكرة حول .صافي.

DotNetZip هو .صافي مكتبة ملفات zip التي تسمح تسمية إدخالات.كما توم هوتن رد الدول الدلائل ليست من الدرجة الأولى الكيانات في ملف مضغوط الفوقية ، ونتيجة لذلك ، لم الرمز البريدي من المكتبات التي كنت أعرف من فضح "إعادة تسمية الدليل" الفعل.ولكن بعض المكتبات تتيح لك إعادة تسمية كافة الإدخالات التي لها أسماء تدل على معين الدليل ، والتي تعطيك النتيجة التي تريدها.

في DotNetZip, انها تبدو مثل هذا:

 var regex = new Regex("/OldDirName/.*$");
 int renameCount= 0;
 using (ZipFile zip = ZipFile.Read(ExistingZipFile))
 {
    foreach (ZipEntry e in zip)
    {
        if (regex.IsMatch(e.FileName))
        {
            // rename here
            e.FileName = e.FileName.Replace("/OldDirName/", "/NewDirName/");
            renameCount++;
        }
    }
    if (renameCount > 0)
    {
        zip.Comment = String.Format("This archive has been modified. {0} entries have been renamed.", renameCount);
        // any changes to the entries are made permanent by Save()
        zip.Save();  // could also save to a new zip file here
    }
 }

يمكنك أيضا إضافة أو إزالة إدخالات داخل باستخدام الشرط.

إذا قمت بحفظ نفس الملف ، ثم DotNetZip كتابة فقط تغيير البيانات الوصفية - دخول رؤوس الدليل المركزي سجلات تسمية إدخالات ، مما يوفر وقت كبير مع المحفوظات.إذا قمت بحفظ ملف جديد أو تيار ، ثم كل من الرمز البريدي يحصل على بيانات مكتوبة.

أعتقد أنك سوف تكون قادرة على العثور على مساعدة هذه المهمة باستخدام المشاع ضغط, خاصة ZipArchiveEntry

هذا هو تفعل خدعة.اشتعلت فيه النيران بسرعة لأنه يعمل فقط على الدليل المركزي وليس الملفات.

//  rezip( zipfile, "/main-folder", "/versionXY" );

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;


protected void rezip( String zipfile, String olddir, String newdir ) {

    Path zipFilePath = Paths.get( zipfile );
    try (FileSystem fs = FileSystems.newFileSystem( zipFilePath, null )) {
        Path oldpathInsideZipPath = fs.getPath( olddir );
        if( ! Files.exists( Paths.get( newdir ) ) )
            Files.createDirectory( Paths.get( newdir ) );

        if ( Files.exists( oldpathInsideZipPath, LinkOption.NOFOLLOW_LINKS ) ) {
            Files.walkFileTree(oldpathInsideZipPath, new SimpleFileVisitor<Path>() {
                 @Override
                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                     throws IOException
                 {
                     if( file.toString().indexOf( olddir ) > -1 ){
                         String a = file.toString().replaceAll( olddir, newdir );
                         Path b = fs.getPath( a );
                         if( ! Files.exists( b.getParent() ) ){
                             Files.createDirectories( b.getParent() );
                         }
                         Files.move( file, b, LinkOption.NOFOLLOW_LINKS );
                     }
                     return FileVisitResult.CONTINUE;
                 }
                 @Override
                 public FileVisitResult postVisitDirectory(Path dir, IOException e)
                     throws IOException
                 {
                     if (e == null) {
                         Files.delete(dir);
                         return FileVisitResult.CONTINUE;
                     } else {
                         // directory iteration failed
                         throw e;
                     }
                 }
             });
        }
        fs.close();
    } catch ( Exception e ) {
        e.printStackTrace();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top