Как мне заархивировать файл в C#, не используя сторонние API?
Я уверен, что это не дубликат, так что потерпите со мной всего минуту.
Как я могу программно (C#) ZIP файл (в Windows) без использования каких-либо сторонних библиотек? Мне нужен собственный вызов windows или что-то в этом роде; мне действительно не нравится идея запуска процесса, но я буду, если мне это абсолютно необходимо. А Пиновке позвонить было бы гораздо лучше.
в противном случае, позвольте мне сказать вам, что я действительно пытаюсь достичь: мне нужна возможность позволить пользователю скачать сборник документов в одном запросе. Есть идеи, как это сделать?
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)); } } }Примечание:
- этот код использует поток.Метод CopyTo в .NET 4.0
- это станет намного проще с введением класса ZipArchive в .NET 4.5: http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx
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