Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Создание архива


Автор: CYBERDREAM 25.2.2008, 19:58
Приветствую всех.
Создаю архив с помощью библиотечки: ICSharpCode.SharpZipLib.Zip;
http://www.icsharpcode.net/OpenSource/SharpZipLib/
Русские буквы выводятся неверно
Цитата

ура -> єЁр

как то можно этого избежать.
Заранее спасибо

Автор: vponomarov 26.2.2008, 16:32
Не знаю, как в этой библиотеке, но писал недавно свой архиватор и разбирался с примером из МСДНа.
Так вот там для записи строк в файл использовалась такая конструкция
Код

private byte[] ConvertToArray(string name)
{
            return System.Text.Encoding.ASCII.GetBytes(name);
}


и русские буквы превращались в квадратики.
После замены ASCII на Default проблема решилась.

Если есть доступ к исходникам библиотеки, попробуй выполнить нечто подобное.

Автор: marcusmae 26.2.2008, 16:56
Извините, я, может, не всё понимаю, но почему-то мне всегда казалось, что архиваторы работают с любыми файлами, как с бинарными. И разархивированные байты должны быть в точности такими же, как исходные. Если же байты - это текст, то он должен быть в той же кодировке, что и исходный. Иначе, фтопку такой архиватор, т.к. де факто он повредил данные. Или я ошибаюсь?

Автор: vponomarov 26.2.2008, 17:01
Цитата

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


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

Автор: marcusmae 26.2.2008, 17:12
Цитата(vponomarov @  26.2.2008,  17:01 Найти цитируемый пост)
русские имена файлов становились нечитаемыми после разархивации

Если это не .NET изменил кодировку строк ДО архивации, то тоже похоже на проблему архиватора (ведь он хранит имена файлов у себя в таблицах), или даже на специфику файловой системы. Всякие там NTFSы хранят инфу о локализованных именах и/или хвосты длинных имён в реестре. Я ничего против не имею, просто как бы не получился "костыль" - неуниверсальное решение, работающее лишь в частных случаях.

Автор: vponomarov 26.2.2008, 17:26
Цитата

.NET изменил кодировку строк ДО архивации


именно это и делает зловредная функция:
Код

private byte[] ConvertToArray(string name)
{
            return System.Text.Encoding.ASCII.GetBytes(name);
}


т.е. проблема возникает на стадии записи имен файлов во "внутренние таблицы архива".

я не утверждаю, что указанная библиотека поступает так же. Повторюсь еще раз: с данной проблемой я столкнулся разбирая пример МСДНа. Но есть подозрение, что в ICSharpCode.SharpZipLib.Zip делают примерно тоже.

Автор: CYBERDREAM 26.2.2008, 17:54
Спасибо за содействие. Внутри файлов все без проблем, а вот наименования страдают.
Вот собственно класс, которым осуществляю архивацию:
Код

using System;
using System.Collections;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;

namespace FolderZipper
{
    public static class ZipUtil
    {
        public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)
        {
            ArrayList ar = GenerateFileList(inputFolderPath); // generate file list
            int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;
            // find number of chars to remove     // from orginal file path
            TrimLength += 1; //remove '\'
            FileStream ostream;
            byte[] obuffer;
            string outPath = inputFolderPath + @"\" + outputPathAndFile;
            ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outPath)); // create zip stream
            if (password != null && password != String.Empty)
                oZipStream.Password = password;
            oZipStream.SetLevel(9); // maximum compression
            ZipEntry oZipEntry;
            foreach (string Fil in ar) // for each file, generate a zipentry
            {
                oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
                oZipStream.PutNextEntry(oZipEntry);

                if (!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory
                {
                    ostream = File.OpenRead(Fil);
                    obuffer = new byte[ostream.Length];
                    ostream.Read(obuffer, 0, obuffer.Length);
                    oZipStream.Write(obuffer, 0, obuffer.Length);
                }
            }
            oZipStream.Finish();
            oZipStream.Close();
        }


        private static ArrayList GenerateFileList(string Dir)
        {
            ArrayList fils = new ArrayList();
            bool Empty = true;
            foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
            {
                fils.Add(file);
                Empty = false;
            }

            if (Empty)
            {
                if (Directory.GetDirectories(Dir).Length == 0)
                    // if directory is completely empty, add it
                {
                    fils.Add(Dir + @"/");
                }
            }

            foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
            {
                foreach (object obj in GenerateFileList(dirs))
                {
                    fils.Add(obj);
                }
            }
            return fils; // return file list
        }
    }
}

Пока что ничего путного не получилось, вечером пострадаю.

Автор: vponomarov 27.2.2008, 10:47
проблему, по-моему, нужно искать внутри одного из этих методов:
Код

oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
oZipStream.PutNextEntry(oZipEntry);

Автор: Sherlock 27.2.2008, 12:42
Да, я тоже думаю, что надо покопаться в самой библиотеке, исходники я так понял есть...

Автор: andrey_pro 3.5.2010, 13:24
Хочу поднять тему!

Тоже столкнулся с такой проблемой. Архивирую файлы. В именах файллв встречаются символы « и ».
При архивировании они непонятно почему заменяются на символя < и >.

Сами русские буквы остаются в нормальном виде.
В коде: ZipConstants.DefaultCodePage = 866

Кто нибудь с этим сталкивался?

Автор: uranpro 4.5.2010, 11:53
из сорца

ZipOutputStream.PutNextEntry
Код

byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

ZipConstants.ConvertToArray
Код

        /// <summary>
        /// Convert a string to a byte array
        /// </summary>
        /// <param name="str">
        /// String to convert to an array
        /// </param>
        /// <returns>Converted array</returns>
        public static byte[] ConvertToArray(string str)
        {
            if ( str == null ) {
                return new byte[0];
            }

            return Encoding.GetEncoding(DefaultCodePage).GetBytes(str);
        }

        /// <summary>
        /// Convert a string to a byte array
        /// </summary>
        /// <param name="flags">The applicable <see cref="GeneralBitFlags">general purpose bits flags</see></param>
        /// <param name="str">
        /// String to convert to an array
        /// </param>
        /// <returns>Converted array</returns>
        public static byte[] ConvertToArray(int flags, string str)
        {
            if (str == null) {
                return new byte[0];
            }

            if ((flags & (int)GeneralBitFlags.UnicodeText) != 0) {
                return Encoding.UTF8.GetBytes(str);
            }
            else {
                return ConvertToArray(str);
            }
        }


Автор: andrey_pro 4.5.2010, 14:10
в сорцах пробывал менять метод ZipConstants.ConvertToArray
изменял кодировку, но если ставить кодировку не 866 то вместо русских букв - абракабра

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)