Cách đổi tên tệp và thư mục trong .rar .7z, .tar, .zip bằng C #


12

Tôi có một tệp nén .rar .7z, .tar và .zip và tôi muốn đổi tên tên tệp vật lý có sẵn trong phần lưu trữ được nén ở trên bằng C #.

Tôi đã thử điều này bằng thư viện sharpcompress nhưng tôi không thể tìm thấy một tính năng như vậy để đổi tên tệp hoặc tên thư mục trong tệp .rar .7z, .tar và .zip.

Tôi cũng đã thử sử dụng thư viện DotNetZip nhưng hỗ trợ duy nhất của nó. Zip xem những gì tôi đã thử sử dụng thư viện 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());
            }

        }

Nhưng thực tế giống như trên tôi cũng muốn cho .7z, .rar và .tar, tôi đã thử nhiều thư viện nhưng tôi vẫn không nhận được bất kỳ giải pháp chính xác nào.

Làm ơn giúp tôi.


Có một var result = Path.ChangeExtension(myffile, ".jpg");-> docs.microsoft.com/en-us/dotnet/api/ Kẻ
panoskarajohn

Xin chào panoskarajohn, tôi muốn làm điều này trong hồ sơ trong kho lưu trữ được liệt kê trong câu hỏi, bạn có đề xuất giải pháp nào không?
Nikunj Satasiya

Tôi xin lỗi tôi không có một giải pháp sạch cho việc này, tôi chắc chắn bạn có thể làm the renamesau khi Extract () như zip.
panoskarajohn

1
Có, tôi muốn đổi tên các tệp bên trong kho lưu trữ được nén mà không giải nén tệp lưu trữ và định dạng lưu trữ có thể là bất cứ thứ gì .rar .7z, .tar hoặc .zip.
Nikunj Satasiya

4
Trong hầu hết các định dạng, nếu không phải tất cả, tên tệp và thư mục được mã hóa với kích thước thay đổi trong tệp nhị phân kết quả, vì vậy bạn không thể "vá" nó, bạn phải xây dựng lại một số phần của tệp. Thư viện tiêu chuẩn không làm điều đó. Bạn sẽ phải vào từng định dạng lưu trữ và xem cách bạn có thể làm điều đó. Nhiệm vụ khó khăn. Ví dụ: stackoverflow.com/questions/32829839/ khăn
Simon Mourier

Câu trả lời:


3

Đây là một ứng dụng bảng điều khiển đơn giản để đổi tên các tệp trong .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();
        }
    }
}

Cảm ơn, Binara, vì câu trả lời của bạn nhưng như tôi có thể thấy trong câu trả lời có giá trị của bạn, bạn có đúng không, chúng tôi có thể đổi tên một tệp trong kho lưu trữ zip như bạn đã trình bày trong câu trả lời của mình, nhưng nếu tệp của tôi lớn thì sao? nó sẽ mở tệp gốc, sao chép toàn bộ nội dung từ đó và viết cùng một nội dung vào một tệp khác và lưu tệp mới, tôi nghĩ đó sẽ là một quá trình tốn thời gian. Bạn có giải pháp nào khác không?
Nikunj Satasiya

1
Hãy thử Parallel.ForEach thay vì vòng lặp tuần tự. Tôi đã thay đổi mã cho phù hợp.
Binara Thambugala

Cảm ơn Binara, tôi sẽ thử giải pháp này để đổi tên tệp trong kho lưu trữ .zip, nhưng vẫn có một vấn đề như khi tôi sẽ sửa đổi bất kỳ tệp nào trong kho lưu trữ, sau đó nó sẽ nén lại toàn bộ zip của tôi để có giải pháp nào cho điều đó?
Nikunj Satasiya

3

Hãy xem xét 7zipsharp:

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

Bản thân 7zip hỗ trợ rất nhiều định dạng lưu trữ (tôi tin rằng tất cả những gì bạn đã đề cập) và 7zipsharp sử dụng 7zip thực. Tôi đã chỉ sử dụng 7zipsharp cho các tệp .7z nhưng tôi cá là nó hoạt động cho các tệp khác.

Đây là một mẫu thử nghiệm có vẻ như đổi tên một tệp bằng phương thức ModifyArchive, tôi khuyên bạn nên đi học trong đó:

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

Đây là mã đơn giản hóa một chút. Lưu ý rằng thử nghiệm nén tệp 7z cho thử nghiệm của nó; đó là phi vật chất, nó có thể là .txt, v.v. Cũng lưu ý rằng nó tìm thấy tệp theo chỉ mục trong từ điển được chuyển cho ModifyArchive. Tham khảo tài liệu về cách lấy chỉ mục đó từ tên tệp (có thể bạn phải lặp và so sánh).

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

Xin chào FastAI, Cảm ơn phản hồi của bạn nhưng tôi cũng đã thử thư viện này trước đây nhưng nói chung khi chúng tôi sửa đổi bất kỳ tệp nào trong kho lưu trữ, đó là nội dung hoặc tên, kho lưu trữ đang nén lại vì vậy cần có thời gian để nén lại nếu lưu trữ lớn . Khi bạn được cung cấp mã mẫu trong câu trả lời của mình thì tôi nghĩ rằng trước tiên bạn đã trích xuất kho lưu trữ bằng cách sử dụng 'ExtractArchive' và sau đó bạn sửa đổi thêm nhưng đây không phải là một giải pháp đáng tin cậy, bạn có thể đề nghị bất kỳ cách nào khác phù thủy là hợp quy không? do đó, nó cũng có thể cải thiện hiệu suất.
Nikunj Satasiya

1
@NikunjSatasiya - Xin lỗi vì quay lại quá muộn. Không có cách nào để làm điều này mà không viết lại kho lưu trữ. Hãy suy nghĩ về những gì phải xảy ra. Có một thư mục trong tệp lưu trữ với tên tệp và chỉ mục cho nội dung được nén. Đây không phải là mục nhập 'đệm' / chiều dài cố định mà bạn có thể thay đổi độ dài. Có lẽ bạn có thể với một trình soạn thảo nhị phân - nhưng sau đó chỉ ra các tệp và dữ liệu nén của chúng từ 'thư mục' sẽ bị vặn. Có lẽ bạn có thể thay đổi tên tệp như thế và giữ nguyên độ dài. Bùn nghiêm trọng, không phải là một tính năng có thể.
FastAl

1
Và sau đó xem xét nếu thư mục của các tập tin được nén hoặc mã hóa. Không có thay đổi từ bên ngoài sẽ có thể. Tôi cho rằng nếu định dạng tệp .7z được thiết kế ngay từ đầu để xử lý các đổi tên tại chỗ và điều này được thực hiện bởi một nhà phát triển trong dự án, điều này có thể là có thể, nhưng chúng ta đang đi xuống từ đó. Tôi cảm nhận được nỗi đau của bạn!
FastAl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.