我正在尝试将ActionScript 3中的功能转换为C#.NET。
我遇到的麻烦是如何在C#中正确使用ByteArrays。在As3中,有一个特定的类已经具有我所需的大多数功能,但是在C#中似乎没有这种类型的东西,我无法解决。
这是As3函数:
private function createBlock(type:uint, tag:uint,data:ByteArray):ByteArray
{
var ba:ByteArray = new ByteArray();
ba.endian = Endian.LITTLE_ENDIAN;
ba.writeUnsignedInt(data.length+16);
ba.writeUnsignedInt(0x00);
ba.writeUnsignedInt(type);
ba.writeUnsignedInt(tag);
data.position = 0;
ba.writeBytes(data);
ba.position = 0;
return ba;
}
但是据我所知,在C#中,我必须使用字节类型的普通Array,像这样
byte[] ba = new byte[length];
现在,我研究了Encoding类,BinaryWriter和BinaryFormatter类,并研究是否有人为ByteArrays创建了一个类,但是没有运气。
有人可以向正确的方向推我吗?
最佳答案
您应该可以使用MemoryStream
和BinaryWriter
的组合来执行此操作:
public static byte[] CreateBlock(uint type, uint tag, byte[] data)
{
using (var memory = new MemoryStream())
{
// We want 'BinaryWriter' to leave 'memory' open, so we need to specify false for the third
// constructor parameter. That means we need to also specify the second parameter, the encoding.
// The default encoding is UTF8, so we specify that here.
var defaultEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier:false, throwOnInvalidBytes:true);
using (var writer = new BinaryWriter(memory, defaultEncoding, leaveOpen:true))
{
// There is no Endian - things are always little-endian.
writer.Write((uint)data.Length+16);
writer.Write((uint)0x00);
writer.Write(type);
writer.Write(data);
}
// Note that we must close or flush 'writer' before accessing 'memory', otherwise the bytes written
// to it may not have been transferred to 'memory'.
return memory.ToArray();
}
}
但是,请注意,
BinaryWriter
始终使用小尾数格式。如果需要控制它,可以使用Jon Skeet's EndianBinaryWriter
代替。作为这种方法的替代方法,您可以传递流而不是字节数组(可能使用
MemoryStream
进行实现),但是随后您需要注意生命周期管理,即谁将在完成流后关闭/处置该流。与? (由于不使用任何非托管资源,您也许可以不必费心地关闭/处置内存流,但这并不是完全令人满意的IMO。)