我有一个使用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 []中保留零但删除尾随零?正如你在代码中看到的那样,在从内存中读取数据时,我不知道大小。
答案 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,}