Общее чтение правильно сформированного двоичного файла

StackOverflow https://stackoverflow.com/questions/1420044

  •  07-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь прочитать содержимое файлов карты / модели игры в программу с целью написания небольшого средства просмотра моделей и тестирования некоторых функций DirectX. Форматы файлов модели / карты носят фрагментарный характер, и я знаю формат этих файлов. Я могу легко читать файлы, анализируя отдельные фрагменты, используя такой подход:

class FileType1 {
    private Chunk1 c1;
    private Chunk2 c2; // etc

    public void Read(BinaryReader reader) {
        c1 = new Chunk1(reader);
        c2 = new Chunk2(reader);
    }
}

Тем не менее, я пытаюсь придумать какой-нибудь способ общего чтения этих файлов, указав формат, которому придерживается файл (т. е. за Chunk1 следует Chunk2 и т. д. и т. д.), чтобы читатель мог убедиться, что файл имеет соответствующую структуру , Я могу использовать суперкласс Chunk и фабрику Chunk для общего чтения всех фрагментов в любом файле. По сути, я хотел бы дополнить это дополнительными функциональными возможностями валидатора структуры (или чего-то подобного), чтобы получить метод, подобный следующему:

public void Read(BinaryReader reader, ChunkFileFormat format) {
    while (!EOF) {
        char[] chunkID = reader.ReadChars(4);
        Chunk c = chunkFactory.Create(chunkID);
        if (c.GetType() != format.Next.GetType())
            throw new Exception("File format is invalid");
        format.SetCurrentRecord(c);
    }
}

Идея заключается в том, что класс ChunkFileFormat определяет структуру файла, указывая, какой тип чанка должен быть следующим чтением из двоичного потока. Это позволило бы подклассам ChunkFileFormat указывать макет этого конкретного формата, и единственный метод чтения мог бы использоваться для чтения всех различных форматов фрагментированных файлов, вместо того, чтобы писать длинный и повторяющийся метод для каждого.

Мой вопрос: кто-нибудь знает шаблоны проектирования или подходы, которые могут справиться с этой ситуацией? Проект, над которым я работаю, в настоящее время написан на C #, хотя меня могут заинтересовать решения на C ++ (или на любом другом языке).

Заранее спасибо!

Это было полезно?

Решение

Правила такого рода легко кодируются с помощью автомата с конечным состоянием .

Каждый чанк должен менять состояние, в котором вы находитесь. Каждое состояние ждет определенных чанков впоследствии. Если вы столкнулись с порцией, с которой вы не должны сталкиваться в текущем, это ошибка.

Другие советы

Вы можете создать формальное описание формата, используя DataScript / antlr и заставить его создавать для вас синтаксический анализ и код ввода / вывода (Java или C ++).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top