Как мне заархивировать файл в C#, не используя сторонние API?



Я уверен, что это не дубликат, так что потерпите со мной всего минуту.



Как я могу программно (C#) ZIP файл (в Windows) без использования каких-либо сторонних библиотек? Мне нужен собственный вызов windows или что-то в этом роде; мне действительно не нравится идея запуска процесса, но я буду, если мне это абсолютно необходимо. А Пиновке позвонить было бы гораздо лучше.



в противном случае, позвольте мне сказать вам, что я действительно пытаюсь достичь: мне нужна возможность позволить пользователю скачать сборник документов в одном запросе. Есть идеи, как это сделать?

859   7  

7 ответов:

вы используете .NET 3.5? Вы могли бы использовать ZipPackage класс и связанные с ним классы. Это больше, чем просто сжатие списка файлов, потому что он хочет тип MIME для каждого файла, который вы добавляете. Это может сделать то, что вы хотите.

в настоящее время я использую эти классы на похожие проблемы в архиве несколько связанных файлов в один файл для скачивания. Мы используем расширение файла, чтобы связать файл загрузки с нашим настольным приложением. Одна маленькая проблема, с которой мы столкнулись, заключалась в том, что его не можно просто использовать сторонний инструмент, такой как 7-zip, чтобы создать файлы zip, потому что код на стороне клиента не может его открыть-ZipPackage добавляет скрытый файл, описывающий тип контента каждого файла компонента, и не может открыть файл zip, если этот файл типа контента отсутствует.

как я могу программно (C#) ZIP файл (в Windows) без использования любые сторонние библиотеки?

Если вы используете фреймворк 4.5+, теперь есть ZipArchive и ZipFile классы.

using (ZipArchive zip = ZipFile.Open("test.zip", ZipArchiveMode.Create))
{
    zip.CreateEntryFromFile(@"c:\something.txt", "data/path/something.txt");
}

вам нужно добавить ссылки на:

  • System. IO. Compression
  • System. IO. Compression. FileSystem

для .NET Core таргетинг net46, вам нужно добавить зависимости для

  • System. IO. Compression
  • System. IO. Compression.ZipFile

пример проекта.json:

"dependencies": {
  "System.IO.Compression": "4.1.0",
  "System.IO.Compression.ZipFile": "4.0.1"
},

"frameworks": {
  "net46": {}
}

для .Объем ядра 2.0, просто добавив простой использовать заявление-это все что нужно:

  • использование System. IO. Compression;

Я был в той же ситуации, желая .NET вместо сторонней библиотеки. Как уже упоминалось выше, простого использования класса ZipPackage (представленного в .NET 3.5) недостаточно. Существует дополнительный файл, который должен быть включен в архив для того, чтобы ZipPackage работать. Если этот файл добавлен, то полученный ZIP - пакет можно открыть непосредственно из Проводника Windows-без проблем.

все, что вам нужно сделать, это добавить файл [content_types].файл XML корень архива с узлом "по умолчанию" для каждого расширения файла, которое вы хотите включить. После добавления я мог просматривать пакет из Проводника Windows или программно распаковывать и читать его содержимое.

дополнительная информация о [Content_Types].xml-файл можно найти здесь:http://msdn.microsoft.com/en-us/magazine/cc163372.aspx

вот пример [Content_Types].xml (должен быть назван точно) файл:

<?xml version="1.0" encoding="utf-8" ?>
<Types xmlns=
    "http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="xml" ContentType="text/xml" /> 
  <Default Extension="htm" ContentType="text/html" /> 
  <Default Extension="html" ContentType="text/html" /> 
  <Default Extension="rels" ContentType=
    "application/vnd.openxmlformats-package.relationships+xml" /> 
  <Default Extension="jpg" ContentType="image/jpeg" /> 
  <Default Extension="png" ContentType="image/png" /> 
  <Default Extension="css" ContentType="text/css" /> 
</Types>

и C# для создание ZIP-файла:

var zipFilePath = "c:\myfile.zip"; 
var tempFolderPath = "c:\unzipped"; 

    using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read)) 
    { 
        foreach (PackagePart part in package.GetParts()) 
        { 
            var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/'))); 
            var targetDir = target.Remove(target.LastIndexOf('\')); 

            if (!Directory.Exists(targetDir)) 
                Directory.CreateDirectory(targetDir); 

            using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read)) 
            { 
                source.CopyTo(File.OpenWrite(target)); 
            } 
        } 
    } 

Примечание:

    private static string CompressFile(string sourceFileName)
    {
        using (ZipArchive archive = ZipFile.Open(Path.ChangeExtension(sourceFileName, ".zip"), ZipArchiveMode.Create))
        {
            archive.CreateEntryFromFile(sourceFileName, Path.GetFileName(sourceFileName));
        }
        return Path.ChangeExtension(sourceFileName, ".zip");
    }

для приложения .NET 2.0 я использовал SharpZipLib. Простой в использовании и с открытым исходным кодом.

на основе ответа Саймона Маккензи на этот вопрос, Я бы предложил использовать пару методов, как это:

    public static void ZipFolder(string sourceFolder, string zipFile)
    {
        if (!System.IO.Directory.Exists(sourceFolder))
            throw new ArgumentException("sourceDirectory");

        byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        using (System.IO.FileStream fs = System.IO.File.Create(zipFile))
        {
            fs.Write(zipHeader, 0, zipHeader.Length);
        }

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic source = shellApplication.NameSpace(sourceFolder);
        dynamic destination = shellApplication.NameSpace(zipFile);

        destination.CopyHere(source.Items(), 20);
    }

    public static void UnzipFile(string zipFile, string targetFolder)
    {
        if (!System.IO.Directory.Exists(targetFolder))
            System.IO.Directory.CreateDirectory(targetFolder);

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items;
        dynamic destinationFolder = shellApplication.NameSpace(targetFolder);

        destinationFolder.CopyHere(compressedFolderContents);
    }
}

похоже, Windows может просто позволить вам сделать этой...

к сожалению, я не думаю, что вы собираетесь начать отдельный процесс, если вы не перейдете к стороннему компоненту.

Comments

    Ничего не найдено.