Cara Mengganti Nama File dan Folder di .rar .7z, .tar, .zip menggunakan C #

12

Saya memiliki file terkompresi .rar .7z, .tar dan .zip dan saya ingin mengganti nama file fisik yang tersedia di arsip terkompresi di atas menggunakan C #.

Saya telah mencoba ini menggunakan pustaka sharpcompress tetapi saya tidak dapat menemukan fitur seperti itu untuk mengganti nama file atau nama folder dalam file .rar .7z, .tar dan .zip.

Saya juga telah mencoba menggunakan perpustakaan DotNetZip tetapi satu-satunya dukungan. Zip melihat apa yang saya coba menggunakan perpustakaan DotNetZip.

private static void RenameZipEntries(string file)
        {
            try
            {
                int renameCount = 0;
                using (ZipFile zip2 = ZipFile.Read(file))
                {

                    foreach (ZipEntry e in zip2.ToList())
                    {
                        if (!e.IsDirectory)
                        {
                            if (e.FileName.EndsWith(".txt"))
                            {
                                var newname = e.FileName.Split('.')[0] + "_new." + e.FileName.Split('.')[1];
                                e.FileName = newname;
                                e.Comment = "renamed";
                                zip2.Save();
                                renameCount++;
                            }
                        }
                    }
                    zip2.Comment = String.Format("This archive has been modified. {0} files have been renamed.", renameCount);
                    zip2.Save();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }

Tetapi sebenarnya sama seperti di atas saya juga ingin untuk .7z, .rar dan .tar, Saya mencoba banyak perpustakaan tetapi masih saya tidak mendapatkan solusi yang akurat.

Tolong bantu aku.

Nikunj Satasiya
sumber
Ada var result = Path.ChangeExtension(myffile, ".jpg");-> docs.microsoft.com/en-us/dotnet/api/…
panoskarajohn
Halo panoskarajohn, saya ingin melakukan ini pada file dalam arsip yang tercantum pada pertanyaan, apakah ada solusi yang bisa Anda sarankan?
Nikunj Satasiya
Maaf saya tidak punya solusi bersih untuk ini, saya yakin Anda bisa melakukannya the renamesetelah Extract () as zip.
panoskarajohn
1
Ya, saya ingin mengganti nama file di dalam arsip zip tanpa mengekstrak arsip dan format arsip bisa berupa apa saja .rar .7z, .tar atau .zip.
Nikunj Satasiya
4
Dalam sebagian besar format, jika tidak semua, nama file dan direktori dikodekan dengan ukuran variabel dalam file biner yang dihasilkan, jadi Anda tidak bisa hanya "menambal" itu, Anda harus merekonstruksi beberapa bagian file. Perpustakaan standar tidak melakukan itu. Anda harus masuk ke setiap format arsip dan melihat bagaimana Anda bisa melakukannya. Tugas yang sulit. Contoh: stackoverflow.com/questions/32829839/…
Simon Mourier

Jawaban:

3

Ini adalah aplikasi konsol sederhana untuk mengganti nama file di .zip

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;

namespace Renamer
{
    class Program
    {
        static void Main(string[] args)
        {
            using var archive = new ZipArchive(File.Open(@"<Your File>.zip", FileMode.Open, FileAccess.ReadWrite), ZipArchiveMode.Update);
            var entries = archive.Entries.ToArray();

            //foreach (ZipArchiveEntry entry in entries)
            //{
            //    //If ZipArchiveEntry is a directory it will have its FullName property ending with "/" (e.g. "some_dir/") 
            //    //and its Name property will be empty string ("").
            //    if (!string.IsNullOrEmpty(entry.Name))
            //    {
            //        var newEntry = archive.CreateEntry($"{entry.FullName.Replace(entry.Name, $"{RandomString(10, false)}{Path.GetExtension(entry.Name)}")}");
            //        using (var a = entry.Open())
            //        using (var b = newEntry.Open())
            //            a.CopyTo(b);
            //        entry.Delete();
            //    }
            //}

            Parallel.ForEach(entries, entry =>
            {
                //If ZipArchiveEntry is a directory it will have its FullName property ending with "/" (e.g. "some_dir/") 
                //and its Name property will be empty string ("").
                if (!string.IsNullOrEmpty(entry.Name))
                {
                    ZipArchiveEntry newEntry = archive.CreateEntry($"{entry.FullName.Replace(entry.Name, $"{RandomString(10, false)}{Path.GetExtension(entry.Name)}")}");
                    using (var a = entry.Open())
                    using (var b = newEntry.Open())
                        a.CopyTo(b);
                    entry.Delete();
                }
            });
        }

        //To Generate random name for the file
        public static string RandomString(int size, bool lowerCase)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            if (lowerCase)
                return builder.ToString().ToLower();
            return builder.ToString();
        }
    }
}
Binara Thambugala
sumber
Terima kasih, Binara, atas tanggapan Anda, tetapi seperti yang saya lihat di jawaban berharga Anda, Anda benar kami dapat mengganti nama file di arsip zip seperti yang Anda tunjukkan dalam jawaban Anda, tetapi jika file saya besar, lalu? itu akan membuka file asli, menyalin seluruh konten dari itu dan menulis konten yang sama di file lain dan menyimpan file baru, saya pikir itu akan menjadi proses yang memakan waktu. Apakah Anda punya solusi lain?
Nikunj Satasiya
1
Coba Paralel .ForEach alih-alih Sequential loop. Saya telah mengubah kodenya.
Binara Thambugala
Terima kasih Binara, saya akan mencoba solusi ini untuk mengganti nama file di dalam arsip .zip, tapi tetap saja, ada satu masalah seperti ketika saya akan memodifikasi file apa pun di dalam arsip maka akan mengkompres ulang seluruh zip saya jadi apakah ada solusi untuk itu?
Nikunj Satasiya
3

Pertimbangkan 7zipsharp:

https://www.nuget.org/packages/SevenZipSharp.Net45/

7zip sendiri mendukung banyak format arsip (saya percaya semua yang Anda sebutkan) dan 7zipsharp menggunakan 7zip yang asli. Saya telah menggunakan 7zipsharp hanya untuk file .7z tapi saya yakin itu bekerja untuk orang lain.

Berikut contoh tes yang muncul untuk mengubah nama file menggunakan metode ModifyArchive, saya sarankan Anda pergi ke sekolah di dalamnya:

https://github.com/squid-box/SevenZipSharp/blob/f2bee350e997b0f4b1258dff520f36409198f006/SevenZip.Tests/SevenZipCompressorTests.cs

Ini kode yang disederhanakan sedikit. Perhatikan bahwa tes memampatkan file 7z untuk pengujiannya; itu tidak penting itu bisa .txt, dll. Juga perhatikan itu menemukan file dengan indeks dalam kamus diteruskan ke ModifyArchive. Konsultasikan dokumentasi untuk cara mendapatkan indeks itu dari nama file (mungkin Anda harus mengulang dan membandingkan).

var compressor = new SevenZipCompressor( ... snip ...);

compressor.CompressFiles("tmp.7z", @"Testdata\7z_LZMA2.7z");

compressor.ModifyArchive("tmp.7z", new Dictionary<int, string> { { 0, "renamed.7z" }});

using (var extractor = new SevenZipExtractor("tmp.7z"))
{
    Assert.AreEqual(1, extractor.FilesCount);
    extractor.ExtractArchive(OutputDirectory);
}

Assert.IsTrue(File.Exists(Path.Combine(OutputDirectory, "renamed.7z")));
Assert.IsFalse(File.Exists(Path.Combine(OutputDirectory, "7z_LZMA2.7z")));
FastAl
sumber
Hai FastAI, Terima kasih atas tanggapan Anda, tetapi saya juga telah mencoba perpustakaan ini sebelumnya, tetapi secara umum ketika kami memodifikasi file apa pun di dalam arsip baik konten atau nama, arsip sedang dikompresi ulang sehingga perlu waktu untuk mengkompresi ulang jika arsipnya besar . Ketika Anda diberi kode sampel dalam jawaban Anda maka saya pikir Anda telah mengekstraksi arsip terlebih dahulu menggunakan 'ExtractArchive' dan kemudian Anda melakukan modifikasi lebih lanjut tetapi ini bukan solusi yang dapat diandalkan, bisakah Anda menyarankan cara alternatif lain penyihir yang kanonik? jadi itu juga bisa meningkatkan kinerja.
Nikunj Satasiya
1
@NikunjSatasiya - Maaf kembali terlambat. Tidak ada cara untuk melakukan ini tanpa menulis ulang arsip. Pikirkan apa yang harus terjadi. Ada direktori dalam file arsip dengan nama file, dan indeks ke konten terkompresi. Ini bukan entri 'empuk' / panjang tetap di mana Anda dapat mengubah panjangnya. Mungkin Anda bisa dengan editor biner - tetapi kemudian indeks file dan data terkompresi dari 'direktori' akan kacau. Mungkin Anda bisa mengubah nama file seperti itu dan tetap sama. Kludge serius, mungkin bukan fitur.
FastAl
1
Dan kemudian pertimbangkan apakah direktori file dikompresi atau dienkripsi. Tidak ada perubahan dari luar yang dimungkinkan. Saya kira jika format file .7z dirancang dari awal untuk menangani penggantian nama di tempat, dan ini dilakukan oleh seorang pengembang proyek, ini mungkin terjadi, tetapi kami masih jauh dari itu. Aku merasakan sakitmu!
FastAl