从BinaryWriter写入字节[]

本文关键字:字节 BinaryWriter | 更新日期: 2023-09-27 18:07:50

快速提问。我试图通过二进制写入器将整数转换为7BitEncodedInt。目前看来,我必须这样做的最好方式是:

Stream memoryStream = new MemoryStream();
InternalBinaryWriter ibw = new InternalBinaryWriter(memoryStream);
ibw.Write7BitEncodedInt((int)length);
memoryStream.Position = 0;
memoryStream.Read(object.ByteArray, 0, (int)memoryStream.Length);

有没有更简单的方法来做到这一点,而不需要流?我有点不愿意重新实现它们的Write7BitEncodedInt函数,只是把它直接输出到字节数组,但如果有必要,我就会这样做

编辑:

我最后做的是:

the byteArray is resized accordingly, just didn't include that line in the source.

我最后做的是:

    byte[] Write7BitEncodedIntToByteArray(int length) {
        List<byte> byteList = new List<byte>();
        while (length > 0x80) {
            byteList.Add((byte)(length | 0x80));
            length >>= 7;
        }
        byteList.Add((byte)length);
        return byteList.ToArray();
    }

从BinaryWriter写入字节[]

如果您想写入byte[]数组,使用MemoryStream是最简单的方法。事实上,其中一个MemoryStream构造函数接受一个字节数组,并将其用作写入的缓冲区。因此,在您的情况下,这样做可能更有用:

using( var memoryStream = new MemoryStream( @object.ByteArray ) )
using( var writer = new InternalBinaryWriter( memoryStream ) )
{
    writer.Write7BitEncodedInt( (int) length );
}

请记住,这将导致内存流无法扩展其大小。根据您提供的代码,我认为这将是好的(您所显示的可能实际上抛出一个异常在运行时,如果@object.ByteArray小于流数组)。

编辑:由于我们正在查看明显的性能关键代码,我测试了三种不同的方法:

列表
static byte[] MethodA( int length )
{
    List<byte> byteList = new List<byte>();
    while (length > 0x80) {
        byteList.Add((byte)(length | 0x80));
        length >>= 7;
    }
    byteList.Add((byte)length);
    return byteList.ToArray();
}

MemoryStream

static byte[] MethodB( int length )
{
    using( var stream = new MemoryStream( 5 ) )
    {
        while( length > 0x80 )
        {
            stream.WriteByte( (byte) ( length | 0x80 ) );
            length >>= 7;
        }
        stream.WriteByte( (byte) length );
        return stream.ToArray();
    }
}

直接数组
static byte[] MethodC( int length )
{
    int tmp = length;
    int l = 1;
    while( ( tmp >>= 7 ) > 0 ) ++l;
    var result = new byte[l];
    for( int i = 0; i < l; ++i )
    {
        result[i] = (byte) ( 0x80 | length );
        length >>= 7;
    }
    result[l - 1] &= 0x7f;
    return result;
}

在很大程度上,第三种方法是最快的(比前两种快4-5倍)。当涉及到性能关键代码时,创建一个List只是为了把它变成一个数组几乎总是一种气味,这就是我在这里引起注意的地方。

根据使用该方法的方式,也有可能在其他地方占用另一大块时间(例如,如果每次都将这个小数组复制到一个更大的数组中,则可以完全删除数组分配并直接写入更大的数组)。