我从输入文件(ASCII 文本文件)中获得了一个 byte[] 数组,并且我正在尝试删除预设十六进制值的所有字节,而不将数组转换为 string 且不使用 lists .
这是我到目前为止想出的代码:
byte[] byteLine = File.ReadAllBytes(filePath);
byte lineBreak = (byte)0x0d;
int breakIndex = Array.IndexOf(byteLine, lineBreak);
这些是我认为需要的变量才能发挥作用。 Here我发现了一种方法,它的功能与我尝试执行的操作类似,因此我将代码(按原样)添加到项目中并尝试在循环中使用它。首先是一个 for 循环:
for(int i = 0; i < byteLine.Length; i++) {
byte v = byteLine[i];
if (v == lineBreak) {
RemoveRange(byteLine, breakIndex, 2);
}
}
我试图遍历数组中的每个字节,直到出现相当于换行符字节的字节,然后我尝试调用从换行符索引开始的方法 (breakIndex var) 删除 2 个字节(因为 ASCII 中的换行符使用 2 个字节 0d0a)。它应该循环遍历所有数组并对所有换行符重复此操作(lineBreak var)。这就是我认为如果我使用
for(;;)
循环它会做的事情,但它没有,我一定是做了错误。第二次尝试使用 foreach:
int t = breakIndex;
foreach (byte b in byteLine) {
if (b == lineBreak) {
while (t != 0)
{
RemoveRange(byteLine, breakIndex, 2);
t--;
}
}
}
在第二个循环中,我添加了一个变量 (t) 用作“计数器”,其起始值等于换行符索引值 (breakIndex var)。我知道输入文件是一个方形 ASCII 图像,因此它的行数与换行符符号的数量相同(减去一个换行符,因为最后一行的最后一个字符不是换行符),因此循环应该循环等于换行次数的次数,或者直到 t 达到值 0,因为每次循环后它都会减少 1。此循环中存在同样的问题,该方法未触发。这是我尝试的第三件事,也是最后一件事:
int t = 0;
foreach (byte b in byteLine) {
if (b == lineBreak) { do
{
RemoveRange(byteLine, breakIndex, 2);
t++;
}
while (t < breakIndex); }
}
}
与另一个 foreach 循环类似,但它是上升而不是下降,它应该继续循环,直到 t 变量达到换行符总数的值。我什至不知道我是否正确使用了 do 和 while,这是我第一次尝试使用 do。这就是说,我在循环外测试了方法,它工作得很好,它只是删除了第一个换行符,因为它本身并不意味着循环。经过一番搜索,我找到了这个答案。
通过阅读该答案,我了解到应该有一种方法可以直接编辑 byte[] 数组中的项目,而无需很多解决方法,问题是我不知道如何将该解决方案应用于我的问题,因为我不熟悉使用那些 C# 函数。
这是就地处理数组的实现。
const byte CR = 0x0d, LF = 0x0a;
byte[] byteLine = [1, 2, 3, 4, CR, LF, 5, 6, 7, CR, LF, CR, LF, 8, 9];
int firstCR = Array.IndexOf(byteLine, CR);
if (firstCR >= 0) {
// Jump to first CR
int destination = firstCR, source = firstCR + 2;
while (source < byteLine.Length) {
if (byteLine[source] == CR) {
source += 2;
} else {
byteLine[destination++] = byteLine[source++];
}
}
// Fill remaining bytes with 0
for (int i = destination; i < byteLine.Length; i++) {
byteLine[i] = 0;
}
}
但请注意,它远非单行代码,而且比像
byteLine.Where(b => b != lineBreak).ToArray()
这样的单行代码更可能包含错误。
此外,在不进行基准测试的情况下进行这样的优化是没有意义的。您认为可能很慢的解决方案有时比预期的要快。 Microsoft 在加速循环和 LINQ 查询方面投入了大量精力。
另请参阅:BenchmarkDotNet