Archive

Archive for the ‘zip’ Category

Работа с форматом ZIP в C#

February 25th, 2010 No comments

icsharpcode

Для упаковки и распаковки ZIP архивов средствами Net Framework существует множество библиотек. Одна из наиболее популярных – ICSharpCode.SharpZipLib. Распространяется библиотека по лицензии GPL и в целом производит приятное впечатление.

Она позволяет работать с форматом ZIP на относительно низком уровне, исползуя классы ZipInputStream, ZipOutputStream, ZipEntry и др. А можно ограничиться функциями «запаковать директорию в архивчик» и «распаковать архивчик в директорию», это умеет класс FastZip.

Все настолько просто, что если бы у меня не возникло загадочных проблем с кириллицей в именах файлов, то не было бы и этой статьи про ZIP и C#.

В веб-приложении (ASP.NET) по некой команде пользователя нужно запаковывать два файла в архив и отдавать его на скачивание. Для этого создается временная директория, туда помещаются файлы, далее они пакуются в архив.

tempDir = Path.GetTempPath() + Guid.NewGuid().ToString() + "\\";
Directory.CreateDirectory(tempDir);
 
...
 
FastZip fz = new FastZip();
fz.CreateZip(filename, tempDir, true, "");

Этот код прекрасно работал при запуске веб-сервера по F5 в VisualStudio. Однако на реальном сервере FastZip отказывался понимать кириллицу в именах файлов и заменял такие символы на знаки вопроса.

Для выявления проблемы я создал папку (»D:\test») с двумя файлами (»первый.txt», «второй.txt») и поставил задачу заархивировать ее. Вместо веб-сервера было написано конслоьное приложение. Вот его код:

public static void Main()
{
	FastZip fz = new FastZip();
	fz.CreateZip("D:\\test.zip", "D:\\test", true, "");
}

К моему удивлению, оно отработало на сервере безупречно! Значит, предположение, что проблема кроется в том, что на локальном компьютере у меня русская версия Windows, а на сервере – американская, было неверным.

Как оказалось, в библиотеке SharpZipLib есть такой класс ZipConstants, а у него есть свойство DefaultCodePage. В консольном приложении ZipConstants.DefaultCodePage = 866 (что хорошо), а на веб-сервере ZipConstants.DefaultCodePage = 437 (что нехорошо).

Решение проблемы оказалось совсем простым. Нужно добавить куда-нибудь перед архивацией эту строчку:

ZipConstants.DefaultCodePage = 866;

Передаю приветы:
- Гоше, проблема была в его коде :)
- Пользователю volser с форума ru-board; спасибо за ссылку, которая решила мою проблему!