Странная ошибка при сжатии файла в 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);
- }
- //<<<<----- вот только здесь потоки полностью записаны
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д