Home > Mobile >  C# How to read a binary file into int[] without a BinaryReader loop?
C# How to read a binary file into int[] without a BinaryReader loop?

Time:01-18

As far as I know, the BinaryReader loop performance is poor. Another method I can think of is to first ReadAllBytes and then Buffer.BlockCopy into int[], but that would result in an additional copy. Is it possible to read a huge binary file directly into int[] efficiently?

CodePudding user response:

You can use MemoryMarshal.AsBytes to read all data:

using var stream = new FileStream(...);
var target = new int[stream.Length / 4];
stream.Read(MemoryMarshal.AsBytes(target.AsSpan()));

No BinaryReader is used in that case. Be aware of endianness of int representation. This code above might cause problems if the file doesn't match to your hardware.

CodePudding user response:

If you want to read the array as another type, you can use MemoryMarshal.Cast.

using System;
using System.Runtime.InteropServices;

class Program
{
    public static void Main(string[] args)
    {
        byte[] arrayByte = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
        Span<int> spanInt = MemoryMarshal.Cast<byte, int>(arrayByte);

        Console.WriteLine("0x{0:X8}", spanInt[0]); // For little endian it will be 0x44332211.
        Console.WriteLine("0x{0:X8}", spanInt[1]); // For little endian it will be 0x88776655.
    }
}

Another alternative is Unsafe.As. However, there are some problems, such as Length not reflecting the converted type value. I recommend using the MemoryMarshal class.

using System;
using System.Runtime.CompilerServices;

class Program
{
    public static void Main(string[] args)
    {
        byte[] arrayByte = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
        int[] arrayInt = Unsafe.As<byte[], int[]>(ref arrayByte);

        Console.WriteLine("Length={0}", arrayInt.Length); // 8!? omg...
        Console.WriteLine("0x{0:X8}", arrayInt[0]); // For little endian it will be 0x44332211.
        Console.WriteLine("0x{0:X8}", arrayInt[1]); // For little endian it will be 0x88776655.
    }
}
  • Related