C#中的字符串长度前缀

作者:追风剑情 发布于:2024-5-22 14:40 分类:C#

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

  1. using System;
  2. using System.Text;
  3. using System.IO;
  4.  
  5. namespace ConsoleApp14
  6. {
  7. internal class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. string s = "abcd";
  12. byte[] bytes = Encoding.UTF8.GetBytes(s);
  13.  
  14. //将字符串写入内存流
  15. var ms = new MemoryStream();
  16. Write7BitEncodedInt(bytes.Length, ms);
  17. ms.Write(bytes, 0, bytes.Length);
  18. ms.Position = 0;
  19.  
  20. //从内存流中读取字符串
  21. var reader = new BinaryReader(ms);
  22. Console.WriteLine(reader.ReadString());
  23. Console.ReadKey();
  24. }
  25.  
  26. /// <summary>
  27. /// 写入字符串长度前缀到内存流,这个长度前缀所占字节数是动态的。
  28. /// 每个字节的第8bit表示后面是否还跟有长度前缀字节,只有字节中的右边7bit用来表示大小。
  29. /// 例如,一个长度为128的字符串,它的长度前缀为 [10000000, 00000001],
  30. /// 需要注意的是长度前缀用的是小端表示,所以数组中第2个字节代表 00000001=1x128
  31. /// </summary>
  32. /// <param name="value"></param>
  33. /// <param name="ms"></param>
  34. public static void Write7BitEncodedInt(int value, MemoryStream ms)
  35. {
  36. uint num;
  37. for (num = (uint)value; num >= 128; num >>= 7)
  38. {
  39. //以小端顺序写入到流中
  40. //每次存储7bit到写入的字节中,并在第8bit上做上标记
  41. ms.WriteByte((byte)(num | 0x80u));
  42. }
  43.  
  44. ms.WriteByte((byte)num);
  45. }
  46.  
  47. /// <summary>
  48. /// 从内存流中读取字符串长度前缀
  49. /// </summary>
  50. /// <param name="ms"></param>
  51. /// <returns></returns>
  52. /// <exception cref="FormatException"></exception>
  53. public static int Read7BitEncodedInt(MemoryStream ms)
  54. {
  55. int num = 0;
  56. int num2 = 0;
  57. byte b;
  58. do
  59. {
  60. if (num2 == 35)
  61. {
  62. throw new FormatException("Format_Bad7BitInt32");
  63. }
  64.  
  65. b = (byte)ms.ReadByte();
  66. //提取出7bit有效位放入num中
  67. num |= (b & 0x7F) << num2;
  68. num2 += 7;
  69. }
  70. while ((b & 0x80u) != 0);
  71. return num;
  72. }
  73. }
  74. }

运行测试
1111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号