C# - чтение двоичных файлов в Big Endian?

Я пытаюсь улучшить свое понимание формата файла STFS, используя программу для чтения всех различных битов информации. Используя веб-сайт со ссылкой на то, какие смещения содержат какую информацию, я написал некоторый код, который заставляет двоичное устройство чтения проходить через файл и помещать значения в правильные переменные.

Проблема в том, что все данные ДОЛЖНЫ быть Big Endian, а все, что считывает двоичный файл, - Little Endian. Как лучше всего это исправить?

Могу ли я создать имитирующий класс Binary reader, который возвращает обратный массив байтов? Есть ли что-то, что я могу изменить в экземпляре класса, что заставит его читать в big endian, чтобы мне не пришлось все переписывать?

Любая помощь будет принята с благодарностью.

edit: Я попробовал добавить Encoding.BigEndianUnicode в качестве параметра, но он все равно читает в little endian.

27
задан mowwwalker 23 December 2011 в 21:49
поделиться

1 ответ

Главным образом полное (в моих целях) общедоступная замена для BinaryReader, который обрабатывает порядок байтов правильно, в отличие от большинства этих ответов. По умолчанию это работает точно как BinaryReader, но может быть создано для чтения в необходимом порядке байтов. Дополнительно эти Read<Primitive> методы перегружаются, чтобы позволить Вам определять порядок байтов для чтения конкретного значения в - полезный в (маловероятном) сценарии, что Вы имеете дело с потоком смешанных данных LE/.

public class EndiannessAwareBinaryReader : BinaryReader
{
    public enum Endianness
    {
        Little,
        Big,
    }

    private readonly Endianness _endianness = Endianness.Little;

    public EndiannessAwareBinaryReader(Stream input) : base(input)
    {
    }

    public EndiannessAwareBinaryReader(Stream input, Encoding encoding) : base(input, encoding)
    {
    }

    public EndiannessAwareBinaryReader(Stream input, Encoding encoding, bool leaveOpen) : base(input, encoding, leaveOpen)
    {
    }

    public EndiannessAwareBinaryReader(Stream input, Endianness endianness) : base(input)
    {
        _endianness = endianness;
    }

    public EndiannessAwareBinaryReader(Stream input, Encoding encoding, Endianness endianness) : base(input, encoding)
    {
        _endianness = endianness;
    }

    public EndiannessAwareBinaryReader(Stream input, Encoding encoding, bool leaveOpen, Endianness endianness) : base(input, encoding, leaveOpen)
    {
        _endianness = endianness;
    }

    public override short ReadInt16() => ReadInt16(_endianness);

    public override int ReadInt32() => ReadInt32(_endianness);

    public override long ReadInt64() => ReadInt64(_endianness);

    public override ushort ReadUInt16() => ReadUInt16(_endianness);

    public override uint ReadUInt32() => ReadUInt32(_endianness);

    public override ulong ReadUInt64() => ReadUInt64(_endianness);

    public short ReadInt16(Endianness endianness) => BitConverter.ToInt16(ReadForEndianness(sizeof(short), endianness));

    public int ReadInt32(Endianness endianness) => BitConverter.ToInt32(ReadForEndianness(sizeof(int), endianness));

    public long ReadInt64(Endianness endianness) => BitConverter.ToInt64(ReadForEndianness(sizeof(long), endianness));

    public ushort ReadUInt16(Endianness endianness) => BitConverter.ToUInt16(ReadForEndianness(sizeof(ushort), endianness));

    public uint ReadUInt32(Endianness endianness) => BitConverter.ToUInt32(ReadForEndianness(sizeof(uint), endianness));

    public ulong ReadUInt64(Endianness endianness) => BitConverter.ToUInt64(ReadForEndianness(sizeof(ulong), endianness));

    private byte[] ReadForEndianness(int bytesToRead, Endianness endianness)
    {
        var bytesRead = ReadBytes(bytesToRead);

        switch (endianness)
        {
            case Endianness.Little:
                if (!BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytesRead);
                }
                break;

            case Endianness.Big:
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(bytesRead);
                }
                break;
        }

        return bytesRead;
    }
}
1
ответ дан 28 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: