【发布时间】:2021-02-21 03:10:47
【问题描述】:
在我正在处理的 Blazor WebAssembly 项目中,我在后端 WebAPI 服务器上压缩数据并将其传递到前端 Blazor 服务器(运行 Blazor WebAssembly,而不是“Blazor 服务器”)术语),传送给用户,然后由用户解压。我遇到了以下异常:
System.IO.IOException:损坏的数据 ReadInternal at System.IO.Compression.DeflateStreamNative.CheckResult (System.Int32 结果,System.String where) in :0 at System.IO.Compression.DeflateStreamNative.ReadZStream (System.IntPtr 缓冲区,System.Int32 长度) in :0 在 System.IO.Compression.DeflateStream.ReadInternal(System.Byte[] 数组, System.Int32 偏移量,System.Int32 计数) in :0 在 System.IO.Compression.DeflateStream.Read (System.Byte[] 数组,System.Int32 偏移量,System.Int32 计数) 在 :0 处 System.IO.Compression.GZipStream.Read (System.Byte[] 数组, System.Int32 偏移量,System.Int32 计数) in :0 在 OptionalyticsFrontend.Shared.Services.Compression.DecompressString (System.Byte[] 输入) [0x0001b] in C:\Users\codef\source\repos\OptionalyticsFrontend\OptionalyticsFrontend\Shared\Services\Compression.cs:24 在 OptionalyticsFrontend.Client.Pages.Application.GetFilteredOptions () [0x00183] 在 C:\Users\codef\source\repos\OptionalyticsFrontend\OptionalyticsFrontend\Client\Pages\Application.razor:310
我一遍又一遍地查看指定的行,又查看了一段时间的 Google 和 Stack Overflow,但无法弄清楚。以下是后端和前端使用的压缩/解压缩方法:
public static string DecompressString(this byte[] input)
{
var result = new byte[input.Length];
using (var source = new MemoryStream(input))
{
using (var decompressionStream = new GZipStream(source,
CompressionMode.Decompress))
{
decompressionStream.Read(result, 0, input.Length); // <---------- THIS IS THE ERROR LINE
}
}
return Encoding.UTF8.GetString(result);
}
public static byte[] CompressString(this string inputString)
{
byte[] input = Encoding.UTF8.GetBytes(inputString);
using (var result = new MemoryStream())
{
using (var compressionStream = new GZipStream(result,
CompressionMode.Compress))
{
compressionStream.Write(input, 0, input.Length);
compressionStream.Flush();
}
return result.ToArray();
}
}
以下行是在我的 Razor 组件中调用解压缩的地方:
var responseString = OptionalyticsFrontend.Shared.Services.Compression.DecompressString(responseBytes);
我已经查看并尝试实施以下 Stack Overflow 答案,但没有一个有效,我每次仍然遇到相同的异常。
GZipStream And DeflateStream will not decompress all bytes
GZipStream does gzipping but ungzipping file end up with "Unexpected end of data"
GZipStream zip file invalid or corrupted
Gzip compression and decompression in C#
这里发生了什么?我将前端 Blazor 服务器作为 .NET Standard 和 .NET Core 运行(实际的客户端和共享代码是 .NET Standard,服务器端是 .NET Core)
编辑:正如安迪的评论所要求的,我添加了一个新流并尝试复制到新流,但这会导致同样的错误。
public static string DecompressString(byte[] input)
{
var result = new byte[input.Length];
using (var newStream = new MemoryStream())
{
using (var source = new MemoryStream(input))
{
using (var decompressionStream = new GZipStream(source,
CompressionMode.Decompress))
{
decompressionStream.CopyTo(newStream);
}
}
newStream.Position = 0;
return Encoding.UTF8.GetString(newStream.ToArray());
}
}
【问题讨论】:
-
不要使用
decompressionStream.Read,而是创建一个新的内存流并执行decompressionStream.CopyTo(theNewMemoryStream);,然后执行theNewMemoryStream.Position = 0; Encoding.UTF8.GetString(theNewMemoryStream.ToArray()); -
@Andy 试过了,没用。完全相同的例外。将添加新代码以在一秒钟内回答。
-
我试过你的代码,它运行良好。不知道你的项目发生了什么。如果你这样做:
var ret = "hello".CompressString().DecompressString();我没有错误。当您使用上面的CopyTo代码时,它可以完美运行。 -
@Andy 原来是因为在我的一个文件中,在服务器之间的所有数据交换中,我使用了
await response.Content.ReadAsByteArrayAsync()而不是await response.Content.ReadAsAsync<byte[]>(),这破坏了一切。
标签: c# .net gzip blazor gzipinputstream