Чтение сжатых данных GZip в потоке - PullRequest
1 голос
/ 31 января 2012

Моя цель - сжать файл с помощью gzip и затем записать сжатые байты в секцию Xml, что означает, что мне нужен сжатый байтовый массив в моем коде. Все примеры для GZip, которые я нашел, просто записывали байты прямо в файл.

Так вот мой код:

public ContainerFile(string[] inputFiles, string Output)
    {
        XmlDocument doc = new XmlDocument();
        XmlNode root;

        FileInfo fi;
        FileStream fstream;
        BinaryReader reader;
        GZipStream gstream;



        root = doc.CreateElement("compressedFile");
        doc.AppendChild(root);

        foreach (string f in inputFiles)
        {
            fstream = File.OpenRead(f);
            MemoryStream s = new MemoryStream();

            byte[] buffer = new byte[fstream.Length];
            // Read the file to ensure it is readable.
            int count = fstream.Read(buffer, 0, buffer.Length);
            if (count != buffer.Length)
            {
                fstream.Close();
                //Console.WriteLine("Test Failed: Unable to read data fromfile");
            return;
            }
            fstream.Close();

            gstream = new GZipStream(s, CompressionMode.Compress, true);
            gstream.Write(buffer, 0, buffer.Length);
            gstream.Flush();


            byte[] bytes = new byte[s.Length];

            s.Read(bytes, 0, bytes.Length);

            File.WriteAllBytes(@"c:\compressed.gz", bytes);

        }

по причинам отладки, я просто попытался записать данные в файл после загрузки.

Итак, длина входного файла составляет ~ 4 Кбайт. Как показывает мне дегуббер, длина массива "bytes" составляет ~ 2k. Таким образом, похоже, что размер сжатого байтового массива правильный, но все значения в нем равны 0.

Может кто-нибудь помогите мне?

1 Ответ

4 голосов
/ 31 января 2012

Ваш Read вызов пытается прочитать с конца из MemoryStream - вы не «перемотали» его.Вы могли бы сделать это с s.Position = 0; - но было бы проще просто позвонить MemoryStream.ToArray.

Обратите внимание, что я лично попробую , а не для чтения из потоков.Предполагая, что все данные будут доступны за один раз, как вы делаете для начала.Вы также должны использовать операторы using для потоков, чтобы избежать утечки дескрипторов при возникновении исключения.Однако, использование File.ReadAllBytes было бы проще в любом случае:

byte[] inputData = File.ReadAllBytes();
using (var output = new MemoryStream())
{
    using (var compression = new GZipStream(output, CompressionMode.Compress,
                                            true))
    {
        compression.Write(inputData, 0, inputData.Length);
    }
    File.WriteAllBytes(@"c:\compressed.gz", output.ToArray());
}

Непонятно, почему вы используете MemoryStream в первую очередь здесь, учитывая, что вы затем записываете данные вфайл ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...