Странная ошибка при сжатии файла в GZipStream - C#

Узнай цену своей работы

Формулировка задачи:

В процессе разработки проекта возникла странная ошибка при сжатии файла.
class ZipStrings
    {
                //Эта функция загружает байты в строку по 2 байта в один символ ut8-16
        public static string get_bytes_utf16(byte[] bytes)
        {
            string res = "";
            for (int i = 0; i < bytes.Length; i += 2)
            {
                char a = (i == bytes.Length - 1) ? (char)(bytes[i] << 8) : (char)(bytes[i] << 8 | bytes[i + 1]);
                res += a;
            }
            return res;
        }
                //Эта функция выгружает байты из строки по 2 байта из символа ut8-16
        public static byte[] get_utf16_bytes(string utf16)
        {
            int k = ((utf16[utf16.Length - 1] & 0xff) > 0) ? 0 : 1;
            byte[] res = new byte[utf16.Length * 2 - k];
            for (int i = 0; i < utf16.Length; i++)
            {
                res[i * 2] = (byte)(utf16[i] >> 8);
                if (k > 0 && i == utf16.Length - 1) break;
                res[i * 2 + 1] = (byte)(utf16[i] & 0xff);
            }
            return res;
        }
                //Пробная функция
        static public void experiment(System.Windows.Forms.IWin32Window owner)
        {
            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            if (ofd.ShowDialog(owner) == System.Windows.Forms.DialogResult.OK)
            {
                FileStream fs1 = new FileStream(ofd.FileName, FileMode.Open);
                System.Windows.Forms.MessageBox.Show("FileStream1 Size: "+fs1.Length.ToString());
                FileStream fs2 = new FileStream(ofd.FileName+".fb2",FileMode.Create);
                string buf = string.Empty;
                Inflate(fs1, out buf);
                Deflate(fs2, buf);
                fs2.Close();
                fs1.Close();
            }
        }
                
                //Функция сжатия. Сжимает данные из потока src и загружает в строку
        static public void Inflate(Stream src, out string dst)
        {
            src.Seek(0, SeekOrigin.Begin);
            MemoryStream dsts = new MemoryStream();
            GZipStream gzip_str = new GZipStream(dsts, CompressionMode.Compress);
            byte[] buf = new byte[src.Length];
            src.Read(buf, 0, buf.Length);
            gzip_str.Write(buf, 0, buf.Length);  //!!! Ошибка возникает здесь. В gzip_str попадает только 70627 байтов из буфера из 142994 необходимых.
            dsts.Seek(0, SeekOrigin.Begin); 
            buf = new byte[dsts.Length];
            dsts.Read(buf, 0, buf.Length);
            dst = get_bytes_utf16(buf);
        }
                //Функция распаковки сжатых данных. Распаковывает строку в поток данных
        static public void Deflate(Stream dst, string src)
        {
            const int BUF_LENGTH = 100000;
            byte[] fileBytes = new byte[BUF_LENGTH];
            int bytesRead;
            
            MemoryStream srcs = new MemoryStream(get_utf16_bytes(src));
            GZipStream gzip = new GZipStream(srcs, CompressionMode.Decompress);
            while ((bytesRead = gzip.Read(fileBytes, 0, BUF_LENGTH)) > 0)
                dst.Write(fileBytes, 0, bytesRead);
        }
    }
Если кто знает, в чем дело, прошу помочь.

Решение задачи: «Странная ошибка при сжатии файла в GZipStream»

textual
Листинг программы
            src.Seek(0, SeekOrigin.Begin);
            using (var dsts = new MemoryStream(capacity:(int)src.Length))
            using (var gzip = new GZipStream(dsts, CompressionLevel.Optimal))
            {
                src.CopyTo(gzip, BUF_LENGTH);//Почему-то он извлекает все данные из потока src, а в gzip записывает не все! Почему?
 
                dsts.Seek(0, SeekOrigin.Begin);
                dst = String.Empty;
                while ((bytesRead = dsts.Read(buf, 0, BUF_LENGTH)) > 0)<<------ вот здесь вы уже пытаетесь работать с dsts, хотя Flush для gzip еще не вызван, и данные еще не полностью переданы
                    dst += get_bytes_utf16(buf, bytesRead);
            }
            //<<<<----- вот только здесь потоки полностью записаны

Оцени полезность:

14   голосов , оценка 4.143 из 5
Похожие ответы