压缩和UTF8编码

7

有人能告诉我为什么在这个过程中会丢失信息吗?一些UTF8字符似乎没有被解码: "Biography":"\u003clink type=... 或者 Steve Blunt \u0026 Marty Kelley, 但是另一些却可以: "Name":"朱敬

// Creating a 64bit string containing gzip data
string bar;
using (MemoryStream ms = new MemoryStream())
{
    using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress))
    using (StreamWriter writer = new StreamWriter(gzip, System.Text.Encoding.UTF8))
    {
        writer.Write(s);
    }
    ms.Flush();
    bar = Convert.ToBase64String(ms.ToArray());
}

// Reading it
string foo;
byte[] itemData = Convert.FromBase64String(bar);
using (MemoryStream src = new MemoryStream(itemData))
using (GZipStream gzs = new GZipStream(src, CompressionMode.Decompress))
using (MemoryStream dest = new MemoryStream(itemData.Length*2))
{
    gzs.CopyTo(dest);
    foo = Encoding.UTF8.GetString(dest.ToArray());
}

Console.WriteLine(foo);

1
你的第一个 using 语句后面有一个分号,这个分号可能不应该在那里。 - Rik
1
我无法使用您的代码重现此问题,对我来说它运行良好。您确定这些字符不是已经编码在源字符串中了吗? - Rik
可能吧,我会尝试的,谢谢。 - dekajoo
2个回答

4
这可能是因为你使用 StreamWriter 编写字符串,但使用 CopyTo()Encoding.GetString() 读取它导致的。如果你尝试这样做会发生什么呢?
// Reading it
string foo;
byte[] itemData = Convert.FromBase64String(bar);
using (MemoryStream src = new MemoryStream(itemData))
using (GZipStream gzs = new GZipStream(src, CompressionMode.Decompress))
using (StreamReader reader = new StreamReader(gzs, Encoding.UTF8))
{
    foo = reader.ReadLine();
}

虽然我认为你应该使用BinaryReaderBinaryWriter

string s = "Biography:\u003clink type...";
string bar;
using (MemoryStream ms = new MemoryStream())
{
    using (GZipStream gzip = new GZipStream(ms, CompressionMode.Compress))
    using (var writer = new BinaryWriter(gzip, Encoding.UTF8))
    {
        writer.Write(s);
    }
    ms.Flush();
    bar = Convert.ToBase64String(ms.ToArray());
}

// Reading it
string foo;
byte[] itemData = Convert.FromBase64String(bar);
using (MemoryStream src = new MemoryStream(itemData))
using (GZipStream gzs = new GZipStream(src, CompressionMode.Decompress))
using (var reader = new BinaryReader(gzs, Encoding.UTF8))
{
    foo = reader.ReadString();
}

Console.WriteLine(foo);

reader.ReadString --> “字符串以长度为前缀”(至少在VB.NET中)。这会完全破坏我的解压缩,因为我没有使用BinaryWriter。 - Fuhrmanator
@Fuhrmanator确实会搞砸它。这就是为什么我上面的例子小心地使用BinaryWriter和BinaryReader的原因。 - Matthew Watson

0
问题很简单,就是字符已经在源字符串中编码了。
Ps:感谢rik提供的答案 :)
编辑:我也遇到了matthew-watson建议的StreamReader问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接