鸟语天空
C#中的字符串长度前缀
post by:追风剑情 2024-5-22 14:40

C# 中的字符串长度前缀采用了变长字节数组表示。

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

namespace ConsoleApp14
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string s = "abcd";
            byte[] bytes = Encoding.UTF8.GetBytes(s);

            //将字符串写入内存流
            var ms = new MemoryStream();
            Write7BitEncodedInt(bytes.Length, ms);
            ms.Write(bytes, 0, bytes.Length);
            ms.Position = 0;

            //从内存流中读取字符串
            var reader = new BinaryReader(ms);
            Console.WriteLine(reader.ReadString());
            Console.ReadKey();
        }

        /// <summary>
        /// 写入字符串长度前缀到内存流,这个长度前缀所占字节数是动态的。
        /// 每个字节的第8bit表示后面是否还跟有长度前缀字节,只有字节中的右边7bit用来表示大小。
        /// 例如,一个长度为128的字符串,它的长度前缀为 [10000000, 00000001],
        /// 需要注意的是长度前缀用的是小端表示,所以数组中第2个字节代表 00000001=1x128
        /// </summary>
        /// <param name="value"></param>
        /// <param name="ms"></param>
        public static void Write7BitEncodedInt(int value, MemoryStream ms)
        {
            uint num;
            for (num = (uint)value; num >= 128; num >>= 7)
            {
                //以小端顺序写入到流中
                //每次存储7bit到写入的字节中,并在第8bit上做上标记
                ms.WriteByte((byte)(num | 0x80u));
            }

            ms.WriteByte((byte)num);
        }

        /// <summary>
        /// 从内存流中读取字符串长度前缀
        /// </summary>
        /// <param name="ms"></param>
        /// <returns></returns>
        /// <exception cref="FormatException"></exception>
        public static int Read7BitEncodedInt(MemoryStream ms)
        {
            int num = 0;
            int num2 = 0;
            byte b;
            do
            {
                if (num2 == 35)
                {
                    throw new FormatException("Format_Bad7BitInt32");
                }

                b = (byte)ms.ReadByte();
                //提取出7bit有效位放入num中
                num |= (b & 0x7F) << num2;
                num2 += 7;
            }
            while ((b & 0x80u) != 0);
            return num;
        }
    }
}

运行测试
1111.png

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容