【问题标题】:How to Rename Files and Folder in .rar .7z, .tar, .zip using C#如何使用 C# 重命名 .rar .7z、.tar、.zip 中的文件和文件夹
【发布时间】:2020-04-14 11:23:52
【问题描述】:

我有一个压缩文件 .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,我想在问题上列出的存档中执行此操作,您有什么解决方案可以建议吗?
  • 对不起,我没有一个干净的解决方案,我相信你可以在 Extract() 之后做 the rename zip
  • 是的,我想重命名压缩存档中的文件而不提取存档,并且存档格式可以是任何 .rar .7z、.tar 或 .zip。
  • 在大多数格式中,如果不是全部,文件和目录名称在生成的二进制文件中以可变大小进行编码,因此您不能只是“修补”它,您必须重建部分文件。标准库不这样做。您必须了解每种存档格式并了解如何做到这一点。困难的任务。示例:stackoverflow.com/questions/32829839/…

标签: c# zip tar 7zip rar


【解决方案1】:

这是一个简单的控制台应用程序,用于重命名 .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 存档中的文件,如您在回答中显示的那样,但如果我的文件很大,那么?它将打开原始文件,从中复制整个内容并将相同的内容写入另一个文件并保存新文件,我认为这将是一个耗时的过程。请问您还有其他解决方案吗?
  • 尝试 Parallel.ForEach 而不是顺序循环。我已经相应地更改了代码。
  • 感谢 Binara,我将尝试使用此解决方案重命名 .zip 存档中的文件,但是仍然存在一个问题,例如当我修改存档中的任何文件时,它会重新压缩我的整个 zip那么有什么解决办法吗?
【解决方案2】:

考虑 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”提取了存档,然后您进行了进一步修改,但这不是一个可靠的解决方案,您能否建议任何其他替代方式,女巫是规范的?所以它也可以提高性能。也。
  • @NikunjSatasiya - 很抱歉这么晚才回来。如果不重新编写存档,就没有办法做到这一点。想想必须发生什么。存档文件中有一个目录,其中包含文件名和压缩内容的索引。这不是一个“填充”/固定长度条目,您可以在其中更改长度。也许您可以使用二进制编辑器 - 但是“目录”中的文件索引及其压缩数据将被搞砸。也许您可以像这样更改文件名并保持相同的长度。严重的混乱,不可能是一个功能。
  • 然后再考虑文件目录是压缩还是加密。外部的改变是不可能的。我想如果 .7z 文件格式从一开始就设计为处理就地重命名,并且这是由项目的开发人员完成的,这可能是可能的,但我们离那还有很长的路要走。我感觉到你的痛苦!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多