从字节数组C#中删除尾随零

时间:2014-08-22 17:11:27

标签: c#

我有一个使用Marshal.Copy将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]为零。

问题在于从内存中读取byte []。现有代码如下。

由于byte [] buffer = new byte [MAX_DATA_SIZE]被初始化为全零。现有代码正在尝试删除尾随。但是在那个进程中,它还在byte []中删除了零。

如何在byte []中保留零但删除尾随零?正如你在代码中看到的那样,在从内存中读取数据时,我不知道大小。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

this answer所述,你可以使用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,}