我知道之前在Stackoverflow上已经问过这个问题,但找不到解释。
当我尝试从压缩字节数组中读取字符串时,我在第一次尝试时得到一个空字符串,在第二次尝试时我得到了字符串。
代码示例:
public static string Decompress(byte[] gzBuffer)
{
if (gzBuffer == null)
return null;
using (var ms = new MemoryStream(gzBuffer))
{
using (var decompress = new GZipStream(ms, CompressionMode.Decompress))
{
using (var sr = new StreamReader(decompress, Encoding.UTF8))
{
string ret = sr.ReadToEnd();
// this is the extra check that is needed !?
if (ret == "")
ret = sr.ReadToEnd();
return ret;
}
}
}
}
所有建议都表示赞赏。 - Victor Cassel
答案 0 :(得分:4)
我发现了这个错误。正如迈克尔在压缩程序中所建议的那样。我错过了在GZipStream上调用Close()。
public static byte[] Compress(string text)
{
if (string.IsNullOrEmpty(text))
return null;
byte[] raw = Encoding.UTF8.GetBytes(text);
using (var ms = new MemoryStream())
{
using (var compress = new GZipStream (ms, CompressionMode.Compress))
{
compress.Write(raw, 0, raw.Length);
compress.Close();
return ms.ToArray();
}
}
}
发生了什么事情,数据似乎被保存在一个糟糕的状态,以后需要在解压缩程序中调用ReadToEnd()以提取相同的数据。很奇怪!
答案 1 :(得分:2)
尝试在ms.Position = 0
string ret = sr.ReadToEnd();
答案 2 :(得分:2)
gzBuffer
来自哪里?您是否也编写了生成压缩数据的代码?
也许您拥有的缓冲区数据无效或不完整,或者它可能包含多个连接在一起的deflate流。
答案 3 :(得分:1)
The MSDN Page on the function提及以下内容:
如果当前方法抛出OutOfMemoryException,则读取器在底层Stream对象中的位置按方法能够读取的字符数提前,但已经读入内部ReadLine缓冲区的字符将被丢弃。如果在将数据读入缓冲区后操纵基础流的位置,则基础流的位置可能与内部缓冲区的位置不匹配。要重置内部缓冲区,请调用DiscardBufferedData方法;但是,这种方法会降低性能,只有在绝对必要时才应调用。
或许尝试在DiscardBufferedData()
之前调用ReadToEnd()
并查看它的作用(我知道你没有得到例外,但这是我能想到的全部......)?
答案 4 :(得分:1)
我希望这会有所帮助。
对于ByteArray:
static byte[] CompressToByte(string data)
{
MemoryStream outstream = new MemoryStream();
GZipStream compressionStream =
new GZipStream(outstream, CompressionMode.Compress, true);
StreamWriter writer = new StreamWriter(compressionStream);
writer.Write(data);
writer.Close();
return StreamToByte(outstream);
}
static string Decompress(byte[] data)
{
MemoryStream instream = new MemoryStream(data);
GZipStream compressionStream =
new GZipStream(instream, CompressionMode.Decompress);
StreamReader reader = new StreamReader(compressionStream);
string outtext = reader.ReadToEnd();
reader.Close();
return outtext;
}
public static byte[] StreamToByte(Stream stream)
{
stream.Position = 0;
byte[] buffer = new byte[128];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (!(read > 0))
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
您可以将if(!(read > 0))
替换为if(read <= 0)
。
出于某种原因,上面没有显示if(read <= 0)
。
For Stream:
static Stream CompressToStream(string data)
{
MemoryStream outstream = new MemoryStream();
GZipStream compressionStream =
new GZipStream(outstream, CompressionMode.Compress, true);
StreamWriter writer = new StreamWriter(compressionStream);
writer.Write(data);
writer.Close();
return outstream;
}
static string Decompress(Stream data)
{
data.Position = 0;
GZipStream compressionStream =
new GZipStream(data, CompressionMode.Decompress);
StreamReader reader = new StreamReader(compressionStream);
string outtext = reader.ReadToEnd();
reader.Close();
return outtext;
}