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.