将字节数组拆分为偶数和奇数字节数组并存储在文件中

时间:2017-11-14 18:00:19

标签: c# arrays file split

我在字节数组中逐字节地读取.pst(File Structure)文件,现在我想将数据分成两部分,如偶数和奇数,并将其存储在另外两个文件中偶数和一个奇数。下面是我坚持的代码

        byte[] array = File.ReadAllBytes("PST_Sample.pst");
        for (int index = 0; index < even.Length; index++)
        {

            //Console.WriteLine(index + " : " + array[index]);
            if ((array[index] % 2) == 0)
            {
                even[index] = array[index];
            }
            else
            {
                odd[index] = array[index];
            }
        }

在FOR循环中我尝试过array.length,even.length没什么用。

5 个答案:

答案 0 :(得分:1)

arrayevenodd数组长两倍 请尝试使用以下代码:

for (int index = 0; index < even.Length; index++)
{
    even[index] = array[index * 2];
    odd[index] = array[index * 2 + 1];
}

答案 1 :(得分:1)

将源数组中的索引增加2,并将目标数组中的索引增加1。这允许您将一个字节分配给oddeven数组,而无需进行额外的偶数/奇数测试。

for (int src = 0, dst = 0; src < array.Length; src += 2, dst++)
{
    even[dst] = array[src];
    odd[dst] = array[src + 1];
}

如果数组长度为奇数,则odd[]必须短于even[]。此外,必须特别注意避免遇到超出范围异常的索引。

解决方案还使用奇数数组长度并避免在循环中进行额外测试:

byte[] array = { 0, 1, 2, 3, 4 };
bool isOdd = array.Length % 2 == 1;

byte[] even = new byte[(array.Length + 1) / 2];
byte[] odd = new byte[array.Length / 2];

int length = isOdd ? array.Length - 1 : array.Length;
for (int src = 0, dst = 0; src < length; src += 2, dst++) {
    even[dst] = array[src];
    odd[dst] = array[src + 1];
}

if (isOdd) { // If array length is odd, the last index is even (= length - 1).
    // Assign the last remaining entry.
    even[even.Length - 1] = array[array.Length - 1];
}

答案 2 :(得分:0)

你的测试是错误的。您正在测试数据中的字节,而不是索引。它应该是:

 for (int index = 0; index < array.Length; index++)
    {

        //Console.WriteLine(index + " : " + array[index]);
        if ((index % 2) == 0)
        {
            even[index/2] = array[index];
        }
        else
        {
            odd[(index - 1)/2] = array[index];
        }
    }

答案 3 :(得分:0)

如果您只是在寻找解决方案而不一定是如何修复代码,那么最简单的方法就是使用LINQ。

byte[] array = new byte[] 
{
    55, 56, 57, 58, 89, 90, 91, 92
};
var even = array.Where((b, i) => i % 2 == 0);
var odd = array.Except(even);

如果您需要evenoddbyte[],则只需在每行添加.ToArray()

如果你想将这些值交织在一起,那么这里有一个扩展方法(如果你只是想要一个普通的方法,请删除staticthis)。我借用并修改了this问题的接受答案,即使一个集合比另一个集合大,也可以交错。

public static IEnumerable<T> Interleave<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        var firstMoved = firstEnumerator.MoveNext();
        var secondMoved = secondEnumerator.MoveNext();

        while (firstMoved || secondMoved)
        {
            if (firstMoved)
                yield return firstEnumerator.Current;
            if (secondMoved)
                yield return secondEnumerator.Current;

            firstMoved = firstEnumerator.MoveNext();
            secondMoved = secondEnumerator.MoveNext();
        }
    }
}

答案 4 :(得分:0)

你的主阵列是结果两个的两倍。您的代码中可能存在2或3个设计错误,具体取决于您的数据

第一个缺陷是您同时为所有阵列使用相同的索引。因此,对于偶数阵列或奇数阵列,您在for的每次传递中都会跳过一个存储器单元,因为您的限制是偶数阵列的大小,所以只能在主阵列的中途进行。

第二个缺陷是,根据您的数据,您的偶数和奇数数组可能需要不同的大小,因为如果您有46个奇数和20个偶数,您仍然可以得到数组的大小每一个33

第3个缺陷,可能是最关键的:结合第一个和第二个缺陷,你肯定会得到一个超出范围的索引异常。如果您有25个偶数和67个奇数,因为您使用相同的索引,您的代码将一直有效,直到您到达index >= 25,您将获得一个超出索引的索引,因为偶数数组的最后一个索引为32

我还建议您使用列表而不是数组,因为它们旨在存储任意数量的数据。

在这里,您可以编写代码以避免这些缺陷:

byte[] array = File.ReadAllBytes("PST_Sample.pst");
List<byte> even = new List<byte>();
List<byte> odd = new List<byte>();

for (int index = 0; index < array.Length; index++)
{
    if ((array[index] % 2) == 0)
    {
        even.Add(array[index]);
    }
    else
    {
        odd.Add(array[index]);
    }
}

File.WriteAllBytes("even_file.pst", even.ToArray());
File.WriteAllBytes("odd_file.pst", odd.ToArray());