Як перейменувати файли та папки в .rar .7z, .tar, .zip за допомогою C #


12

У мене стислий файл .rar .7z, .tar і .zip, і я хочу перейменувати ім'я фізичного файлу, наявне в стисненому вище архіві за допомогою C #.

Я спробував це за допомогою бібліотеки різкого стиснення, але я не можу знайти таку функцію для перейменування імені файлу чи папки в .rar .7z, .tar та .zip-файл.

Я також спробував використовувати бібліотеку DotNetZip, але єдина її підтримка.Зип бачте, що я намагався використовувати бібліотеку 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());
            }

        }

Але насправді так само, як і вище, я також хочу для .7z, .rar та .tar, я спробував багато бібліотек, але все одно не отримав точного рішення.

Будь ласка, допоможи мені.


Є var result = Path.ChangeExtension(myffile, ".jpg");-> docs.microsoft.com/en-us/dotnet/api/…
panoskarajohn

Привіт panoskarajohn, я хочу це зробити у файлі в архіві, перерахованому на запитання, чи можна запропонувати якесь рішення?
Нікунд Сатасія

Вибачте, у мене немає чистого рішення для цього, я впевнений, що ви можете це зробити the renameпісля Extract () як zip.
panoskarajohn

1
Так, я хочу перейменувати файли всередині заархівованого архіву без вилучення архіву та формату архіву, можливо, будь-що .rar .7z, .tar або .zip.
Нікунд Сатасія

4
У більшості форматів, якщо не в усіх, імена файлів і каталогів кодуються змінним розміром у отриманому бінарному файлі, тому ви не можете просто "приклеїти" його, вам доведеться реконструювати деякі частини файлу. Стандартні бібліотеки цього не роблять. Вам доведеться зайти в кожен формат архіву і подивитися, як це можна зробити. Складне завдання. Приклад: stackoverflow.com/questions/32829839 / ...
Саймон Mourier

Відповіді:


3

Це проста консольна програма для перейменування файлів у .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();
        }
    }
}

Дякую, Бінара, за вашу відповідь, але, як я бачу у вашій цінній відповіді, ви праві, ми можемо перейменувати файл у zip-архіві, як ви показали у своїй відповіді, але якщо мій файл тоді великий? він відкриє оригінальний файл, скопіює з нього весь вміст і запише agin того самого вмісту в інший файл і збереже новий файл, я думаю, це буде трудомістким процесом. Будь-яке інше рішення, будь ласка?
Нікунд Сатасія

1
Спробуйте Parallel.ForEach замість послідовного циклу. Я відповідно змінив код.
Бінара Тамбугала

Спасибі Binara, я спробую це рішення для перейменування файлу в архіві .zip, але все-таки є одна проблема, як коли я зміню будь-який файл в архіві, тоді він повторно стисне весь мій zip, чи є рішення для цього?
Нікунд Сатасія

3

Розглянемо 7zipsharp:

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

7zip сам підтримує безліч форматів архівів (я вважаю, все, що ви згадали), а 7zipsharp використовує справжній 7zip. Я використовував 7zipsharp лише для файлів .7z, але я думаю, що він працює для інших.

Ось зразок тесту, який, як видається, перейменує файл методом ModifyArchive, я пропоную вам перейти до школи в ньому:

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

Ось код трохи спрощений. Зауважте, що тест стискає 7z файл для свого тесту; це несуттєво, що це може бути .txt тощо. Також зверніть увагу, що він знаходить файл за індексом у словнику, переданому ModifyArchive. Зверніться до документації щодо отримання цього індексу від імені файлу (можливо, вам доведеться циклічно і порівняти).

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

Привіт FastAI, Дякую за вашу відповідь, але я також спробував цю бібліотеку і раніше, але, як правило, коли ми змінюємо будь-який файл всередині архіву, будь то вміст чи ім'я, архів повторно стискається, тому потрібен час для повторного стиснення, якщо архів великий . Оскільки у вашій відповіді вам надається зразок коду, то, я думаю, ви спочатку вилучили архів за допомогою "ExtractArchive", а потім зробите подальші модифікації, але це не є надійним рішенням. Чи можете ви запропонувати будь-який інший спосіб, який відьом є канонічним? тож це також може покращити продуктивність.
Нікунд Сатасія

1
@NikunjSatasiya - Вибачте, що повернувся так пізно. Неможливо зробити це без переписання архіву. Подумайте, що має статися. У архівному файлі є каталог із назви файлів та індекс до стислого вмісту. Це не "вкладений" / запис із фіксованою довжиною, де ви можете змінити довжину. Можливо, ви могли б з двійковим редактором, але тоді покажчики файлів та їх стиснуті дані з 'каталогу' будуть вкручені. Можливо, ви можете змінити ім'я файлу так, і зберегти однакову довжину. Серйозний хитрість, неімовірність.
FastAl

1
А потім розгляньте, чи стискається чи шифрується каталог файлів. Жодні зміни ззовні були б неможливі. Я гадаю, якби формат файлу .7z був розроблений з самого початку для обробки перейменувань на місці, і це було зроблено розробником проекту, це може бути можливим, але ми далекі від цього. Я відчуваю твій біль!
FastAl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.