Как написать свой собственный класс zip в .net - PullRequest
1 голос
/ 27 августа 2009

Я хотел использовать .net System.IO.Compression.GZipStream для сжатия и распаковки каталога. Но я считаю, что он способен сжимать только один файл. Как мне написать класс zip, который может сжимать конкретный каталог в файл zip?

ps: нам не разрешено использовать любую стороннюю zip-библиотеку

Ответы [ 5 ]

4 голосов
/ 27 августа 2009

Вы должны сначала заархивировать файлы.

EDIT

Если вы чувствуете себя авантюрным, почему бы вам не создать свой собственный заголовок и не записывать каждый zip-файл последовательно. Сохраните все имена файлов в заголовке и указатель того, где они начинаются.

3 голосов
/ 27 августа 2009

Существует множество документов по формату .zip. Википедия - хорошее место для начала: http://en.wikipedia.org/wiki/ZIP_file_format.

Вы можете использовать System.IO.Compression.DeflateStream для фактического сжатия, но вам потребуется реализация CRC32, и вам нужно будет расположить файл с правильными заголовками и т. Д.

Это нетривиальный объем работы.

Вы можете рассмотреть возможность приобретения коммерческой библиотеки .zip, если вы не можете использовать библиотеку с открытым исходным кодом. У вас не должно быть никаких юридических проблем с использованием коммерческой библиотеки **, а стоимость покупки лицензии почти наверняка дешевле, чем стоимость разработки и тестирования библиотеки самостоятельно. Кроме того, проверьте вокруг. Возможно, у вашей компании уже есть лицензия на коммерческую библиотеку.

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

2 голосов
/ 27 августа 2009

Если вы используете версию 3.0+, вы можете использовать System.IO.Packaging для создания zip-файлов.

1 голос
/ 27 августа 2009

У вас есть несколько вариантов

1. Использовать Shell.Application
Вы можете обратиться к Shell. В VBScript это выглядит так:

dim sa
set sa = CreateObject("Shell.Application")

Dim zip
Set zip = sa.NameSpace(pathToZipFile)

Dim d
Set d = sa.NameSpace(dirToZip)


For Each s In d.items
    WScript.Echo  s
Next


' http://msdn.microsoft.com/en-us/library/bb787866(VS.85).aspx
' ===============================================================
' 2nd arg is a bit field: 
' 4 = do not display a progress box
' 16 = Respond with "Yes to All" for any dialog box that is displayed.
' 128 = Perform the operation on files only if a wildcard file name (*.*) is specified. 
' 256 = Display a progress dialog box but do not show the file names.
' 2048 = Version 4.71. Do not copy the security attributes of the file.
' 4096 = Only operate in the local directory. Don't operate recursively into subdirectories.

WScript.Echo "copying files..."

zip.CopyHere d.items, 4

' CopyHere is asynchronous. Gotta wait til it's done. 
sLoop = 0
Do Until d.Items.Count <= zip.Items.Count
    Wscript.Sleep(1000)
Loop

Я не знаю, доступно ли это из управляемого кода, но я бы предположил, что так. Хотя мне это кажется немного хакерским.

Кроме того, вам необходимо предварительно инициализировать zip-файл перед добавлением в него файлов:

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Dim file
Set file = fso.CreateTextFile(pathToZipFile)

file.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)

file.Close
Set fso = Nothing
Set file = Nothing

2. Реализуй это сам
Если вы не хотите использовать Shell.Application, теоретически вы можете создать собственную реализацию класса zip без особых проблем, особенно если у вас ограниченные требования. Формат zip не очень сложен, если вы не используете шифрование, zip64, Unicode, временные метки с высоким разрешением, потоковую передачу и т. Д.

3. Сделайте юридический обзор и повторно используйте
Вместо того, чтобы тратить время на разработку новой реализации, изучите реализации, которые существуют сейчас. Некоторые люди беспокоятся о GPL с SharpZipLib. DotNetZip выпущен под открытой лицензией Microsoft, очень разрешительный и без вирусных условий.

1 голос
/ 27 августа 2009

Используйте классы System.IO.Directory и System.IO.File для перечисления всех файлов и папок, делайте это рекурсивно, чтобы гарантировать, что вы получите файл в подпапках Когда у вас есть все файлы, по одному заархивируйте их (или используйте пул потоков), и вы получите то, что вам нужно.

...