using System; using System.IO; using System.Text; namespace 电子展板.Utility { public class ByteArrayStream : Stream { private byte[] _buffer; private int _position; private int _length; private int _capacity; private Encoding _defaultEncoding = Encoding.UTF8; // 默认编码方式(用于字符串读写) public Encoding DefaultEncoding { get => _defaultEncoding; set => _defaultEncoding = value ?? throw new ArgumentNullException(nameof(value)); } // 构造函数:创建指定初始容量的流 public ByteArrayStream(int initialCapacity = 4096) { if (initialCapacity < 0) throw new ArgumentOutOfRangeException(nameof(initialCapacity)); _capacity = initialCapacity; _buffer = new byte[initialCapacity]; _position = 0; _length = 0; } // 构造函数:从现有字节数组创建流 public ByteArrayStream(byte[] buffer) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); _buffer = buffer; _capacity = buffer.Length; _length = buffer.Length; _position = 0; } // 指示当前流是否支持读取 public override bool CanRead => true; // 指示当前流是否支持查找 public override bool CanSeek => true; // 指示当前流是否支持写入 public override bool CanWrite => true; // 获取流的长度 public override long Length => _length; // 获取或设置当前流中的位置 public override long Position { get => _position; set { if (value < 0 || value > _length) throw new ArgumentOutOfRangeException(nameof(value)); _position = (int)value; } } // 确保有足够的容量 private void EnsureCapacity(int required) { if (required <= _capacity) return; // 每次扩容为当前容量的2倍或所需容量(取较大值) int newCapacity = Math.Max(_capacity * 2, required); byte[] newBuffer = new byte[newCapacity]; Array.Copy(_buffer, newBuffer, _length); _buffer = newBuffer; _capacity = newCapacity; } public override void Flush() { // 内存流无需实际刷新 } public override int Read(byte[] buffer, int offset, int count) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); if (offset + count > buffer.Length) throw new ArgumentException("偏移量和计数的总和超过缓冲区长度"); int bytesToRead = Math.Min(count, _length - _position); if (bytesToRead > 0) { Array.Copy(_buffer, _position, buffer, offset, bytesToRead); _position += bytesToRead; } return bytesToRead; } public override long Seek(long offset, SeekOrigin origin) { long newPosition; switch (origin) { case SeekOrigin.Begin: newPosition = offset; break; case SeekOrigin.Current: newPosition = _position + offset; break; case SeekOrigin.End: newPosition = _length + offset; break; default: throw new ArgumentOutOfRangeException(nameof(origin)); } if (newPosition < 0 || newPosition > _length) throw new IOException("seek 位置无效"); _position = (int)newPosition; return _position; } public override void SetLength(long value) { if (value < 0 || value > int.MaxValue) throw new ArgumentOutOfRangeException(nameof(value)); int newLength = (int)value; EnsureCapacity(newLength); _length = newLength; if (_position > newLength) _position = newLength; } public override void Write(byte[] buffer, int offset, int count) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); if (offset + count > buffer.Length) throw new ArgumentException("偏移量和计数的总和超过缓冲区长度"); if (count == 0) return; int newPosition = _position + count; if (newPosition > _length) { EnsureCapacity(newPosition); _length = newPosition; } Array.Copy(buffer, offset, _buffer, _position, count); _position = newPosition; } #region 基础数据类型读写方法 - 完整实现 /// /// 读取一个字节 /// public new byte ReadByte() { if (_position >= _length) throw new EndOfStreamException("已到达流的末尾"); return _buffer[_position++]; } /// /// 写入一个字节 /// public new void WriteByte(byte value) { EnsureCapacity(_position + 1); if (_position == _length) _length++; _buffer[_position++] = value; } /// /// 读取16位有符号整数(小端字节序) /// public short ReadInt16() { return ReadInt16(Endianness.LittleEndian); } /// /// 读取16位有符号整数 /// public short ReadInt16(Endianness endianness) { byte[] bytes = ReadBytes(2); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToInt16(bytes, 0); } /// /// 写入16位有符号整数(小端字节序) /// public void WriteInt16(short value) { WriteInt16(value, Endianness.LittleEndian); } /// /// 写入16位有符号整数 /// public void WriteInt16(short value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取16位无符号整数(小端字节序) /// public ushort ReadUInt16() { return ReadUInt16(Endianness.LittleEndian); } /// /// 读取16位无符号整数 /// public ushort ReadUInt16(Endianness endianness) { byte[] bytes = ReadBytes(2); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToUInt16(bytes, 0); } /// /// 写入16位无符号整数(小端字节序) /// public void WriteUInt16(ushort value) { WriteUInt16(value, Endianness.LittleEndian); } /// /// 写入16位无符号整数 /// public void WriteUInt16(ushort value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取32位有符号整数(小端字节序) /// public int ReadInt32() { return ReadInt32(Endianness.LittleEndian); } /// /// 读取32位有符号整数 /// public int ReadInt32(Endianness endianness) { byte[] bytes = ReadBytes(4); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToInt32(bytes, 0); } /// /// 写入32位有符号整数(小端字节序) /// public void WriteInt32(int value) { WriteInt32(value, Endianness.LittleEndian); } /// /// 写入32位有符号整数 /// public void WriteInt32(int value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取32位无符号整数(小端字节序) /// public uint ReadUInt32() { return ReadUInt32(Endianness.LittleEndian); } /// /// 读取32位无符号整数 /// public uint ReadUInt32(Endianness endianness) { byte[] bytes = ReadBytes(4); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToUInt32(bytes, 0); } /// /// 写入32位无符号整数(小端字节序) /// public void WriteUInt32(uint value) { WriteUInt32(value, Endianness.LittleEndian); } /// /// 写入32位无符号整数 /// public void WriteUInt32(uint value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取64位有符号整数(小端字节序) /// public long ReadInt64() { return ReadInt64(Endianness.LittleEndian); } /// /// 读取64位有符号整数 /// public long ReadInt64(Endianness endianness) { byte[] bytes = ReadBytes(8); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToInt64(bytes, 0); } /// /// 写入64位有符号整数(小端字节序) /// public void WriteInt64(long value) { WriteInt64(value, Endianness.LittleEndian); } /// /// 写入64位有符号整数 /// public void WriteInt64(long value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取64位无符号整数(小端字节序) /// public ulong ReadUInt64() { return ReadUInt64(Endianness.LittleEndian); } /// /// 读取64位无符号整数 /// public ulong ReadUInt64(Endianness endianness) { byte[] bytes = ReadBytes(8); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToUInt64(bytes, 0); } /// /// 写入64位无符号整数(小端字节序) /// public void WriteUInt64(ulong value) { WriteUInt64(value, Endianness.LittleEndian); } /// /// 写入64位无符号整数 /// public void WriteUInt64(ulong value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取单精度浮点数(小端字节序) /// public float ReadFloat() { return ReadFloat(Endianness.LittleEndian); } /// /// 读取单精度浮点数 /// public float ReadFloat(Endianness endianness) { byte[] bytes = ReadBytes(4); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToSingle(bytes, 0); } /// /// 写入单精度浮点数(小端字节序) /// public void WriteFloat(float value) { WriteFloat(value, Endianness.LittleEndian); } /// /// 写入单精度浮点数 /// public void WriteFloat(float value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取双精度浮点数(小端字节序) /// public double ReadDouble() { return ReadDouble(Endianness.LittleEndian); } /// /// 读取双精度浮点数 /// public double ReadDouble(Endianness endianness) { byte[] bytes = ReadBytes(8); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToDouble(bytes, 0); } /// /// 写入双精度浮点数(小端字节序) /// public void WriteDouble(double value) { WriteDouble(value, Endianness.LittleEndian); } /// /// 写入双精度浮点数 /// public void WriteDouble(double value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取布尔值(1字节,0表示false,非0表示true) /// public bool ReadBoolean() { return ReadByte() != 0; } /// /// 写入布尔值(1字节,0表示false,1表示true) /// public void WriteBoolean(bool value) { WriteByte(value ? (byte)1 : (byte)0); } /// /// 读取字符(小端字节序) /// public char ReadChar() { return ReadChar(Endianness.LittleEndian); } /// /// 读取字符 /// public char ReadChar(Endianness endianness) { byte[] bytes = ReadBytes(2); if (NeedReverse(endianness)) Array.Reverse(bytes); return BitConverter.ToChar(bytes, 0); } /// /// 写入字符(小端字节序) /// public void WriteChar(char value) { WriteChar(value, Endianness.LittleEndian); } /// /// 写入字符 /// public void WriteChar(char value, Endianness endianness) { byte[] bytes = BitConverter.GetBytes(value); if (NeedReverse(endianness)) Array.Reverse(bytes); Write(bytes, 0, bytes.Length); } /// /// 读取十进制数(小端字节序) /// public decimal ReadDecimal() { return ReadDecimal(Endianness.LittleEndian); } /// /// 读取十进制数 /// public decimal ReadDecimal(Endianness endianness) { int[] bits = new int[4]; for (int i = 0; i < 4; i++) { bits[i] = ReadInt32(endianness); } return new decimal(bits); } /// /// 写入十进制数(小端字节序) /// public void WriteDecimal(decimal value) { WriteDecimal(value, Endianness.LittleEndian); } /// /// 写入十进制数 /// public void WriteDecimal(decimal value, Endianness endianness) { int[] bits = decimal.GetBits(value); foreach (int bit in bits) { WriteInt32(bit, endianness); } } /// /// 读取指定长度的字节数组 /// public byte[] ReadBytes(int count) { if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); if (_position + count > _length) throw new EndOfStreamException("没有足够的字节可供读取"); byte[] result = new byte[count]; Array.Copy(_buffer, _position, result, 0, count); _position += count; return result; } #endregion #region 字符串读写方法 /// /// 读取以null结尾的字符串(C风格字符串) /// public string ReadNullTerminatedString() { return ReadNullTerminatedString(DefaultEncoding); } /// /// 读取以null结尾的字符串(C风格字符串) /// public string ReadNullTerminatedString(Encoding encoding) { if (encoding == null) throw new ArgumentNullException(nameof(encoding)); int startPos = _position; // 查找null终止符 while (_position < _length && _buffer[_position] != 0) { _position++; } int byteCount = _position - startPos; string result = encoding.GetString(_buffer, startPos, byteCount); // 跳过null终止符 if (_position < _length) { _position++; } return result; } /// /// 写入以null结尾的字符串(C风格字符串) /// public void WriteNullTerminatedString(string value) { WriteNullTerminatedString(value, DefaultEncoding); } /// /// 写入以null结尾的字符串(C风格字符串) /// public void WriteNullTerminatedString(string value, Encoding encoding) { if (value == null) throw new ArgumentNullException(nameof(value)); if (encoding == null) throw new ArgumentNullException(nameof(encoding)); byte[] bytes = encoding.GetBytes(value); Write(bytes, 0, bytes.Length); WriteByte(0); // 写入null终止符 } /// /// 读取前缀长度的字符串(先读取长度,再读取内容) /// 使用Int32作为长度前缀 /// public string ReadLengthPrefixedString() { return ReadLengthPrefixedString(DefaultEncoding, Endianness.LittleEndian); } /// /// 读取前缀长度的字符串(先读取长度,再读取内容) /// 使用Int32作为长度前缀 /// public string ReadLengthPrefixedString(Encoding encoding, Endianness endianness) { return ReadLengthPrefixedString(encoding, endianness); } /// /// 读取前缀长度的字符串(先读取长度,再读取内容) /// 支持指定长度类型(Int16, Int32, Int64等) /// public string ReadLengthPrefixedString(Encoding encoding, Endianness endianness) where TLength : struct, IConvertible { if (encoding == null) throw new ArgumentNullException(nameof(encoding)); // 读取长度前缀 TLength lengthValue = Read(endianness); int length = Convert.ToInt32(lengthValue); if (length < 0) throw new IOException("字符串长度不能为负数"); byte[] bytes = ReadBytes(length); return encoding.GetString(bytes); } /// /// 写入前缀长度的字符串(先写入长度,再写入内容) /// 使用Int32作为长度前缀 /// public void WriteLengthPrefixedString(string value) { WriteLengthPrefixedString(value, DefaultEncoding, Endianness.LittleEndian); } /// /// 写入前缀长度的字符串(先写入长度,再写入内容) /// 使用Int32作为长度前缀 /// public void WriteLengthPrefixedString(string value, Encoding encoding, Endianness endianness) { WriteLengthPrefixedString(value, encoding, endianness); } /// /// 写入前缀长度的字符串(先写入长度,再写入内容) /// 支持指定长度类型(Int16, Int32, Int64等) /// public void WriteLengthPrefixedString(string value, Encoding encoding, Endianness endianness) where TLength : struct, IConvertible { if (value == null) throw new ArgumentNullException(nameof(value)); if (encoding == null) throw new ArgumentNullException(nameof(encoding)); byte[] bytes = encoding.GetBytes(value); // 检查长度是否在指定类型范围内 TLength lengthValue = (TLength)Convert.ChangeType(bytes.Length, typeof(TLength)); // 写入长度前缀和字符串内容 Write(lengthValue, endianness); Write(bytes, 0, bytes.Length); } /// /// 读取固定长度的字符串 /// public string ReadFixedLengthString(int byteCount) { return ReadFixedLengthString(byteCount, DefaultEncoding); } /// /// 读取固定长度的字符串 /// public string ReadFixedLengthString(int byteCount, Encoding encoding) { if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount)); if (encoding == null) throw new ArgumentNullException(nameof(encoding)); byte[] bytes = ReadBytes(byteCount); return encoding.GetString(bytes); } /// /// 写入固定长度的字符串,不足则填充,超出则截断 /// public void WriteFixedLengthString(string value, int byteCount) { WriteFixedLengthString(value, byteCount, DefaultEncoding, (byte)0); } /// /// 写入固定长度的字符串,不足则填充,超出则截断 /// public void WriteFixedLengthString(string value, int byteCount, Encoding encoding, byte paddingByte) { if (byteCount < 0) throw new ArgumentOutOfRangeException(nameof(byteCount)); if (encoding == null) throw new ArgumentNullException(nameof(encoding)); if (value == null) value = string.Empty; // 获取字符串的字节表示 byte[] originalBytes = encoding.GetBytes(value); // 创建目标字节数组 byte[] targetBytes = new byte[byteCount]; if (paddingByte != 0) { // // 填充默认值 for (int i = 0; i < byteCount; i++) targetBytes[i] = paddingByte; } // 复制字节,超出部分截断 int copyLength = Math.Min(originalBytes.Length, byteCount); Array.Copy(originalBytes, targetBytes, copyLength); Write(targetBytes, 0, targetBytes.Length); } #endregion #region 泛型读写方法 /// /// 泛型读取方法(小端字节序) /// public T Read() where T : struct { return Read(Endianness.LittleEndian); } /// /// 泛型读取方法 /// public T Read(Endianness endianness) where T : struct { Type type = typeof(T); if (type == typeof(byte)) return (T)(object)ReadByte(); if (type == typeof(short)) return (T)(object)ReadInt16(endianness); if (type == typeof(ushort)) return (T)(object)ReadUInt16(endianness); if (type == typeof(int)) return (T)(object)ReadInt32(endianness); if (type == typeof(uint)) return (T)(object)ReadUInt32(endianness); if (type == typeof(long)) return (T)(object)ReadInt64(endianness); if (type == typeof(ulong)) return (T)(object)ReadUInt64(endianness); if (type == typeof(float)) return (T)(object)ReadFloat(endianness); if (type == typeof(double)) return (T)(object)ReadDouble(endianness); if (type == typeof(bool)) return (T)(object)ReadBoolean(); if (type == typeof(char)) return (T)(object)ReadChar(endianness); if (type == typeof(decimal)) return (T)(object)ReadDecimal(endianness); throw new NotSupportedException($"不支持的类型: {type.Name}"); } /// /// 泛型写入方法(小端字节序) /// public void Write(T value) where T : struct { Write(value, Endianness.LittleEndian); } /// /// 泛型写入方法 /// public void Write(T value, Endianness endianness) where T : struct { Type type = typeof(T); if (type == typeof(byte)) { WriteByte((byte)(object)value); return; } if (type == typeof(short)) { WriteInt16((short)(object)value, endianness); return; } if (type == typeof(ushort)) { WriteUInt16((ushort)(object)value, endianness); return; } if (type == typeof(int)) { WriteInt32((int)(object)value, endianness); return; } if (type == typeof(uint)) { WriteUInt32((uint)(object)value, endianness); return; } if (type == typeof(long)) { WriteInt64((long)(object)value, endianness); return; } if (type == typeof(ulong)) { WriteUInt64((ulong)(object)value, endianness); return; } if (type == typeof(float)) { WriteFloat((float)(object)value, endianness); return; } if (type == typeof(double)) { WriteDouble((double)(object)value, endianness); return; } if (type == typeof(bool)) { WriteBoolean((bool)(object)value); return; } if (type == typeof(char)) { WriteChar((char)(object)value, endianness); return; } if (type == typeof(decimal)) { WriteDecimal((decimal)(object)value, endianness); return; } throw new NotSupportedException($"不支持的类型: {type.Name}"); } #endregion /// /// 将流内容转换为字节数组 /// public byte[] ToByteArray() { byte[] result = new byte[_length]; Array.Copy(_buffer, result, _length); return result; } /// /// 辅助方法:判断是否需要反转字节顺序 /// private bool NeedReverse(Endianness endianness) { return (endianness == Endianness.BigEndian && BitConverter.IsLittleEndian) || (endianness == Endianness.LittleEndian && !BitConverter.IsLittleEndian); } } /// /// 字节序枚举 /// public enum Endianness { LittleEndian, // 小端字节序 BigEndian // 大端字节序 } }