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