如何使用C#重命名.rar .7z,.tar,.zip中的文件和文件夹


12

我有一个压缩文件.rar .7z,.tar和.zip,我想重命名使用C#压缩的上述压缩文件中可用的物理文件名。

我使用Sharpcompress库进行了尝试,但是在.rar .7z,.tar和.zip文件中找不到用于重命名文件或文件夹名称的功能。

我也尝试过使用DotNetZip库,但是它唯一的支持。Zip请参阅我尝试过使用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,我想在问题所列档案中的文件上进行此操作,您有什么建议吗?
Nikunj Satasiya

抱歉,我对此没有干净的解决方案,我相信您可以the rename在Extract()之后执行zip
panoskarajohn

1
是的,我想重命名压缩存档中的文件而不提取存档,存档格式可以是.rar .7z,.tar或.zip。
Nikunj Satasiya

4
在大多数格式中,即使不是全部,文件和目录名称也会在生成的二进制文件中以可变大小进行编码,因此您不能仅对其进行“修补”,而必须重构文件的某些部分。标准库不这样做。您必须进入每种存档格式,然后看看如何做到。困难的任务。例如:stackoverflow.com/questions/32829839/...
西蒙Mourier

Answers:


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();
        }
    }
}

谢谢Binara,您的回答是正确的,但是正如我在您的宝贵答复中所看到的那样,您是对的,我们可以按照您在答复中显示的方式在zip归档文件中重命名文件,但是如果我的文件很大,那可以吗?它将打开原始文件,从中复制整个内容,然后将相同内容写入另一个文件中,然后保存新文件,我认为这将是一个耗时的过程。请问您还有其他解决方案吗?
Nikunj Satasiya

1
尝试使用Parallel.ForEach而不是顺序循环。我已经相应地更改了代码。
Binara Thambugala

感谢Binara,我将尝试使用该解决方案重命名.zip存档中的文件,但是仍然存在一个问题,例如当我修改存档中的任何文件然后重新压缩整个zip时,是否有解决方案?
Nikunj Satasiya

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'提取了存档,然后进行了进一步修改,但这不是一个可靠的解决方案,能否请您提出女巫规范的其他替代方式?这样也可以提高性能。
Nikunj Satasiya

1
@NikunjSatasiya-抱歉这么晚回来。如果不重写存档,则无法执行此操作。考虑必须发生什么。存档文件中有一个包含文件名的目录,以及指向压缩内容的索引。这不是您可以更改长度的“填充” /固定长度条目。也许您可以使用二进制编辑器-但是文件索引及其来自“目录”的压缩数据将被弄乱。也许您可以像这样更改文件名并保持相同的长度。严重的跳动,不太可能出现。
FastAl

1
然后考虑文件目录是压缩还是加密。外部无法进行任何更改。我想,如果从一开始就设计了.7z文件格式来处理就地重命名,而这是由项目上的开发人员完成的,则可能会实现,但距离此还有很长的路要走。我感到你很痛苦!
FastAl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.