Files
EBoard/电子展板/Utility/ByteArrayStream.cs
2025-09-26 17:42:33 +08:00

928 lines
29 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 -
/// <summary>
/// 读取一个字节
/// </summary>
public new byte ReadByte()
{
if (_position >= _length)
throw new EndOfStreamException("已到达流的末尾");
return _buffer[_position++];
}
/// <summary>
/// 写入一个字节
/// </summary>
public new void WriteByte(byte value)
{
EnsureCapacity(_position + 1);
if (_position == _length)
_length++;
_buffer[_position++] = value;
}
/// <summary>
/// 读取16位有符号整数小端字节序
/// </summary>
public short ReadInt16()
{
return ReadInt16(Endianness.LittleEndian);
}
/// <summary>
/// 读取16位有符号整数
/// </summary>
public short ReadInt16(Endianness endianness)
{
byte[] bytes = ReadBytes(2);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToInt16(bytes, 0);
}
/// <summary>
/// 写入16位有符号整数小端字节序
/// </summary>
public void WriteInt16(short value)
{
WriteInt16(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入16位有符号整数
/// </summary>
public void WriteInt16(short value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取16位无符号整数小端字节序
/// </summary>
public ushort ReadUInt16()
{
return ReadUInt16(Endianness.LittleEndian);
}
/// <summary>
/// 读取16位无符号整数
/// </summary>
public ushort ReadUInt16(Endianness endianness)
{
byte[] bytes = ReadBytes(2);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToUInt16(bytes, 0);
}
/// <summary>
/// 写入16位无符号整数小端字节序
/// </summary>
public void WriteUInt16(ushort value)
{
WriteUInt16(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入16位无符号整数
/// </summary>
public void WriteUInt16(ushort value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取32位有符号整数小端字节序
/// </summary>
public int ReadInt32()
{
return ReadInt32(Endianness.LittleEndian);
}
/// <summary>
/// 读取32位有符号整数
/// </summary>
public int ReadInt32(Endianness endianness)
{
byte[] bytes = ReadBytes(4);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToInt32(bytes, 0);
}
/// <summary>
/// 写入32位有符号整数小端字节序
/// </summary>
public void WriteInt32(int value)
{
WriteInt32(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入32位有符号整数
/// </summary>
public void WriteInt32(int value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取32位无符号整数小端字节序
/// </summary>
public uint ReadUInt32()
{
return ReadUInt32(Endianness.LittleEndian);
}
/// <summary>
/// 读取32位无符号整数
/// </summary>
public uint ReadUInt32(Endianness endianness)
{
byte[] bytes = ReadBytes(4);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToUInt32(bytes, 0);
}
/// <summary>
/// 写入32位无符号整数小端字节序
/// </summary>
public void WriteUInt32(uint value)
{
WriteUInt32(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入32位无符号整数
/// </summary>
public void WriteUInt32(uint value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取64位有符号整数小端字节序
/// </summary>
public long ReadInt64()
{
return ReadInt64(Endianness.LittleEndian);
}
/// <summary>
/// 读取64位有符号整数
/// </summary>
public long ReadInt64(Endianness endianness)
{
byte[] bytes = ReadBytes(8);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToInt64(bytes, 0);
}
/// <summary>
/// 写入64位有符号整数小端字节序
/// </summary>
public void WriteInt64(long value)
{
WriteInt64(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入64位有符号整数
/// </summary>
public void WriteInt64(long value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取64位无符号整数小端字节序
/// </summary>
public ulong ReadUInt64()
{
return ReadUInt64(Endianness.LittleEndian);
}
/// <summary>
/// 读取64位无符号整数
/// </summary>
public ulong ReadUInt64(Endianness endianness)
{
byte[] bytes = ReadBytes(8);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToUInt64(bytes, 0);
}
/// <summary>
/// 写入64位无符号整数小端字节序
/// </summary>
public void WriteUInt64(ulong value)
{
WriteUInt64(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入64位无符号整数
/// </summary>
public void WriteUInt64(ulong value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取单精度浮点数(小端字节序)
/// </summary>
public float ReadFloat()
{
return ReadFloat(Endianness.LittleEndian);
}
/// <summary>
/// 读取单精度浮点数
/// </summary>
public float ReadFloat(Endianness endianness)
{
byte[] bytes = ReadBytes(4);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToSingle(bytes, 0);
}
/// <summary>
/// 写入单精度浮点数(小端字节序)
/// </summary>
public void WriteFloat(float value)
{
WriteFloat(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入单精度浮点数
/// </summary>
public void WriteFloat(float value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取双精度浮点数(小端字节序)
/// </summary>
public double ReadDouble()
{
return ReadDouble(Endianness.LittleEndian);
}
/// <summary>
/// 读取双精度浮点数
/// </summary>
public double ReadDouble(Endianness endianness)
{
byte[] bytes = ReadBytes(8);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToDouble(bytes, 0);
}
/// <summary>
/// 写入双精度浮点数(小端字节序)
/// </summary>
public void WriteDouble(double value)
{
WriteDouble(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入双精度浮点数
/// </summary>
public void WriteDouble(double value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取布尔值1字节0表示false非0表示true
/// </summary>
public bool ReadBoolean()
{
return ReadByte() != 0;
}
/// <summary>
/// 写入布尔值1字节0表示false1表示true
/// </summary>
public void WriteBoolean(bool value)
{
WriteByte(value ? (byte)1 : (byte)0);
}
/// <summary>
/// 读取字符(小端字节序)
/// </summary>
public char ReadChar()
{
return ReadChar(Endianness.LittleEndian);
}
/// <summary>
/// 读取字符
/// </summary>
public char ReadChar(Endianness endianness)
{
byte[] bytes = ReadBytes(2);
if (NeedReverse(endianness))
Array.Reverse(bytes);
return BitConverter.ToChar(bytes, 0);
}
/// <summary>
/// 写入字符(小端字节序)
/// </summary>
public void WriteChar(char value)
{
WriteChar(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入字符
/// </summary>
public void WriteChar(char value, Endianness endianness)
{
byte[] bytes = BitConverter.GetBytes(value);
if (NeedReverse(endianness))
Array.Reverse(bytes);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取十进制数(小端字节序)
/// </summary>
public decimal ReadDecimal()
{
return ReadDecimal(Endianness.LittleEndian);
}
/// <summary>
/// 读取十进制数
/// </summary>
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);
}
/// <summary>
/// 写入十进制数(小端字节序)
/// </summary>
public void WriteDecimal(decimal value)
{
WriteDecimal(value, Endianness.LittleEndian);
}
/// <summary>
/// 写入十进制数
/// </summary>
public void WriteDecimal(decimal value, Endianness endianness)
{
int[] bits = decimal.GetBits(value);
foreach (int bit in bits)
{
WriteInt32(bit, endianness);
}
}
/// <summary>
/// 读取指定长度的字节数组
/// </summary>
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
/// <summary>
/// 读取以null结尾的字符串C风格字符串
/// </summary>
public string ReadNullTerminatedString()
{
return ReadNullTerminatedString(DefaultEncoding);
}
/// <summary>
/// 读取以null结尾的字符串C风格字符串
/// </summary>
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;
}
/// <summary>
/// 写入以null结尾的字符串C风格字符串
/// </summary>
public void WriteNullTerminatedString(string value)
{
WriteNullTerminatedString(value, DefaultEncoding);
}
/// <summary>
/// 写入以null结尾的字符串C风格字符串
/// </summary>
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终止符
}
/// <summary>
/// 读取前缀长度的字符串(先读取长度,再读取内容)
/// 使用Int32作为长度前缀
/// </summary>
public string ReadLengthPrefixedString()
{
return ReadLengthPrefixedString(DefaultEncoding, Endianness.LittleEndian);
}
/// <summary>
/// 读取前缀长度的字符串(先读取长度,再读取内容)
/// 使用Int32作为长度前缀
/// </summary>
public string ReadLengthPrefixedString(Encoding encoding, Endianness endianness)
{
return ReadLengthPrefixedString<int>(encoding, endianness);
}
/// <summary>
/// 读取前缀长度的字符串(先读取长度,再读取内容)
/// 支持指定长度类型Int16, Int32, Int64等
/// </summary>
public string ReadLengthPrefixedString<TLength>(Encoding encoding, Endianness endianness)
where TLength : struct, IConvertible
{
if (encoding == null)
throw new ArgumentNullException(nameof(encoding));
// 读取长度前缀
TLength lengthValue = Read<TLength>(endianness);
int length = Convert.ToInt32(lengthValue);
if (length < 0)
throw new IOException("字符串长度不能为负数");
byte[] bytes = ReadBytes(length);
return encoding.GetString(bytes);
}
/// <summary>
/// 写入前缀长度的字符串(先写入长度,再写入内容)
/// 使用Int32作为长度前缀
/// </summary>
public void WriteLengthPrefixedString(string value)
{
WriteLengthPrefixedString(value, DefaultEncoding, Endianness.LittleEndian);
}
/// <summary>
/// 写入前缀长度的字符串(先写入长度,再写入内容)
/// 使用Int32作为长度前缀
/// </summary>
public void WriteLengthPrefixedString(string value, Encoding encoding, Endianness endianness)
{
WriteLengthPrefixedString<int>(value, encoding, endianness);
}
/// <summary>
/// 写入前缀长度的字符串(先写入长度,再写入内容)
/// 支持指定长度类型Int16, Int32, Int64等
/// </summary>
public void WriteLengthPrefixedString<TLength>(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<TLength>(lengthValue, endianness);
Write(bytes, 0, bytes.Length);
}
/// <summary>
/// 读取固定长度的字符串
/// </summary>
public string ReadFixedLengthString(int byteCount)
{
return ReadFixedLengthString(byteCount, DefaultEncoding);
}
/// <summary>
/// 读取固定长度的字符串
/// </summary>
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);
}
/// <summary>
/// 写入固定长度的字符串,不足则填充,超出则截断
/// </summary>
public void WriteFixedLengthString(string value, int byteCount)
{
WriteFixedLengthString(value, byteCount, DefaultEncoding, (byte)0);
}
/// <summary>
/// 写入固定长度的字符串,不足则填充,超出则截断
/// </summary>
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
/// <summary>
/// 泛型读取方法(小端字节序)
/// </summary>
public T Read<T>() where T : struct
{
return Read<T>(Endianness.LittleEndian);
}
/// <summary>
/// 泛型读取方法
/// </summary>
public T Read<T>(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}");
}
/// <summary>
/// 泛型写入方法(小端字节序)
/// </summary>
public void Write<T>(T value) where T : struct
{
Write(value, Endianness.LittleEndian);
}
/// <summary>
/// 泛型写入方法
/// </summary>
public void Write<T>(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
/// <summary>
/// 将流内容转换为字节数组
/// </summary>
public byte[] ToByteArray()
{
byte[] result = new byte[_length];
Array.Copy(_buffer, result, _length);
return result;
}
/// <summary>
/// 辅助方法:判断是否需要反转字节顺序
/// </summary>
private bool NeedReverse(Endianness endianness)
{
return (endianness == Endianness.BigEndian && BitConverter.IsLittleEndian) ||
(endianness == Endianness.LittleEndian && !BitConverter.IsLittleEndian);
}
}
/// <summary>
/// 字节序枚举
/// </summary>
public enum Endianness
{
LittleEndian, // 小端字节序
BigEndian // 大端字节序
}
}