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를 원하지만 많은 라이브러리를 시도했지만 여전히 정확한 해결책을 얻지 못했습니다.

도와주세요.


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

안녕하세요 panoskarajohn, 질문에 나열된 아카이브 내의 파일 로이 작업을 수행하고 싶습니다. 어떻게 제안 할 수 있습니까?
Nikunj Satasiya

깨끗한 해결책이 없기 때문에 죄송합니다 . the renameExtract () 다음으로 할 수 있다고 확신합니다 zip.
panoskarajohn

1
예, 압축 파일을 추출하지 않고 압축 보관 파일 내부의 파일 이름을 바꾸고 싶습니다. 아카이브 형식은 .rar .7z, .tar 또는 .zip 일 수 있습니다.
Nikunj Satasiya

4
전부는 아니더라도 대부분의 형식에서 파일 및 디렉토리 이름은 결과 바이너리 파일에 가변 크기로 인코딩되므로 파일을 "패치"할 수 없으므로 파일의 일부를 재구성해야합니다. 표준 라이브러리는 그렇게하지 않습니다. 각 보관 형식으로 들어가서 어떻게 할 수 있는지 확인해야합니다. 어려운 작업. 예 : stackoverflow.com/questions/32829839/…
Simon 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();
        }
    }
}

감사합니다, Binara, 귀하의 답변에 대해 귀하의 소중한 답변에서 알 수 있듯이 귀하의 답변에 표시된 것처럼 Zip 아카이브의 파일 이름을 바꿀 수 있습니다. 그러나 내 파일이 큰 경우? 원본 파일을 열고 해당 내용에서 전체 내용을 복사하고 동일한 내용을 다른 파일에 쓰고 새 파일을 저장하면 시간이 많이 걸리는 프로세스라고 생각합니다. 다른 해결책이 있습니까?
Nikunj Satasiya

1
순차 루프 대신 Parallel.ForEach를 시도하십시오. 이에 따라 코드를 변경했습니다.
Binara Thambugala

감사합니다 Binara, .zip 아카이브 내의 파일 이름을 바꾸려면이 솔루션을 시도하지만 여전히 아카이브 내의 파일을 수정하는 경우 하나의 문제가 있으며 전체 압축을 다시 압축하므로 솔루션이 있습니까?
Nikunj Satasiya

3

7zipsharp을 고려하십시오.

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

7zip 자체는 많은 아카이브 형식을 지원하며 (내가 언급 한 모든 것을 믿습니다) 7zipsharp는 실제 7zip을 사용합니다. .7z 파일에만 7zipsharp를 사용했지만 다른 사람에게는 효과가 있습니다.

다음은 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-늦게 돌아와서 죄송합니다. 아카이브를 다시 쓰지 않고는 이렇게 할 수 없습니다. 어떻게해야하는지 생각해보십시오. 아카이브 파일에는 파일 이름과 압축 된 컨텐츠에 대한 색인이있는 디렉토리가 있습니다. 길이를 변경할 수있는 '패딩'/ 고정 길이 항목이 아닙니다. 아마도 이진 편집기를 사용할 수는 있지만 '디렉토리'에서 압축 된 데이터 및 파일의 지표는 망가졌습니다. 어쩌면 파일 이름을 변경하고 같은 길이를 유지할 수 있습니다. 심각한 kludge, 기능이 아닙니다.
FastAl

1
그런 다음 파일 디렉토리가 압축 또는 암호화되었는지 고려하십시오. 외부로부터의 변화는 불가능하다. .7z 파일 형식이 처음부터 내부 이름 변경을 처리하도록 설계되었고 이것이 프로젝트의 개발자에 의해 수행 된 경우 가능할 수 있지만 그로부터 멀리 떨어져 있습니다. 나는 너의 고통을 느낀다!
FastAl
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.