从bytearray c#中删除末尾的零

本文关键字:删除 bytearray | 更新日期: 2023-09-27 18:19:05

我有一个使用Marshal将byte[]写入文件的代码。复制如下所示。从我在调试时观察到的情况来看,有些值可能在字节数组中包含零。

的例子:

[0] 113
[1] 70
[2] 57
[3] 172
[4] 70
[5] 0
[6] 165
[7] 0
[8] 224
[9] 48
[10] 136

可以看到byte[5]和byte[7]都是0。

问题发生在从内存中读取byte[]时。现有代码如下:

因为byte[] buffer = new byte[MAX_DATA_SIZE]被初始化为全0。现有代码正在尝试删除尾随。但在这个过程中,如果它也删除字节[]中的零。

如何保留字节[]中的零,但删除后面的零?正如您在代码中看到的,当从内存中读取数据时,我不知道大小。

从bytearray c#中删除末尾的零

正如这个答案所指出的,您可以使用Linq(它是一个可爱的孩子)。或者你可以用更简单(也更明显)的方法来做,我敢打赌,这种方法会比Linq版本更好。

你可以通过调整它的大小来执行一个适当的"修剪":

public static void TrimTrailingBytes( ref byte[] buffer , byte trimValue )
{
  int i = buffer.Length ;
  while ( i > 0 && buffer[--i] == trimValue )
  {
    ; // no-op by design
  }
  Array.Resize( ref buffer , i+1 ) ;
  return ;
}

使用方便:

byte[] foo = {0,1,0,2,0,3,0,0,0,0,} ;
TrimTrailingBytes( ref foo , 0 ) ;

产生预期的

{0,1,0,2,0,3,}

或者您可以返回源数组的副本,修剪为长度:

static byte[] TrimTrailingBytes( byte[] buffer , byte trimValue )
{
  int i = buffer.Length ;
  while ( i > 0 && buffer[--i] == trimValue )
  {
    ; // no-op by design
  }
  byte[] resized = new byte[i+1] ;
  Array.Copy( buffer , resized , resized.Length ) ;
  return resized ;
}

用法同样简单:

byte[] foo = {0,1,0,2,0,3,0,0,0,0,} ;
byte[] bar = TrimTrailingBytes( foo , 0 ) ;

再次生成预期的

{0,1,0,2,0,3,}

不像LINQ解决方案那么漂亮,但它应该更快(我没有bench,也取决于数组的大小),而无需将数组反转两次。

byte[] withZeroes = new byte[]{ 1,0,1,10,1,1,0,1,5,0,0,0,0,0 }; // Dummy
int indexOfLastNonZero = withZeroes.Length;
while(indexOfLastNonZero != 0 && withZeroes[indexOfLastNonZero-1] == 0)
    indexOfLastNonZero--;
byte[] withoutZeroes = new byte[indexOfLastNonZero];
Array.Copy(withZeroes, withoutZeroes, indexOfLastNonZero); 
// withoutZeroes: 1, 0, 1, 10, 1, 1, 0, 1, 5