You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决C# MemoryStream无法写入带负号字节导致无法解压缩获取UTF字符串的问题?

解决C#写入带符号字节及ZLIB解压缩问题

我来帮你搞定这个问题!核心卡点其实是C#和ActionScript对字节的表示差异:ActionScript的writeByte用的是有符号字节(范围-128到127),而C#的byte类型是无符号的(0到255)。那些你以为的“负字节”,本质上就是AS3对大于127的无符号字节的另一种写法,只要转成C#对应的无符号值就能正常处理。

第一步:把AS3的负字节转成C#无符号字节

先把你AS3代码里的负字节转换成C#能识别的无符号值,转换规则很简单:无符号值 = 256 + 有符号值(因为有符号字节的-1对应无符号的255,以此类推)。对应关系如下:

  • -38 → 218
  • -118 → 138
  • -56 → 200
  • -30 → 226
  • -16 → 240

第二步:C#中解压缩并读取UTF字符串

AS3的ByteArray.uncompress()默认使用ZLIB压缩格式,所以C#里要用DeflateStream来解压缩(注意要跳过ZLIB的前两个头字节),再按照AS3readUTF()的规则读取字符串(先读16位大端长度,再读UTF-8字节)。

以下是完整的C#代码示例:

using System;
using System.IO;
using System.IO.Compression;
using System.Text;

class Program
{
    static void Main()
    {
        // 对应AS3代码里的ByteArray内容,已转换为无符号字节
        byte[] compressedBytes = new byte[]
        {
            120, 218, 99, 16, 12, 51, 41,
            138, 12, 50, 81, 73, 49,
            200, 13, 48, 54, 54, 14, 48, 46, 2, 0,
            45, 226, 4, 240
        };

        string resultString;
        using (var compressedMs = new MemoryStream(compressedBytes))
        {
            // 跳过ZLIB的前两个头字节(CMF和FLG)
            compressedMs.Position = 2;
            
            using (var deflateStream = new DeflateStream(compressedMs, CompressionMode.Decompress))
            using (var decompressedMs = new MemoryStream())
            {
                // 解压缩到内存流
                deflateStream.CopyTo(decompressedMs);
                decompressedMs.Position = 0;

                // 按照AS3 readUTF()的规则读取:先读16位大端长度,再读UTF-8字节
                using (var reader = new BinaryReader(decompressedMs, Encoding.UTF8))
                {
                    // 读取长度(AS3用UTF-16大端存储)
                    ushort strLength = reader.ReadUInt16();
                    // 读取对应长度的字节并转成字符串
                    resultString = Encoding.UTF8.GetString(reader.ReadBytes(strLength));
                }
            }
        }

        Console.WriteLine("解压缩后的UTF字符串:");
        Console.WriteLine(resultString);
    }
}

关键细节说明

  1. 字节表示差异:C#里不存在“写负字节”的问题,因为负字节只是AS3对高位无符号字节的有符号表示,转换后直接写入MemoryStream即可。
  2. ZLIB格式处理:AS3的uncompress()默认用ZLIB,而C#的DeflateStream处理的是原始deflate数据,所以必须跳过ZLIB的前两个头字节(120和218)。
  3. UTF读取规则:AS3的readUTF()不是直接读UTF-8,而是先读一个16位大端整数表示字符串的字节长度,再读取对应长度的UTF-8字节,C#里要严格遵循这个规则才能正确解析。

如果是你自己在C#中生成需要AS3解压缩的字节流,记得在压缩数据前加上ZLIB的头字节(120和218),这样AS3的uncompress()才能正常识别。

内容的提问来源于stack exchange,提问作者Wojtek Kozłowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 19:17:46