生成单文件
This commit is contained in:
928
电子展板/Utility/ByteArrayStream.cs
Normal file
928
电子展板/Utility/ByteArrayStream.cs
Normal file
@@ -0,0 +1,928 @@
|
||||
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表示false,1表示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 // 大端字节序
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user