разбирать содержимое вне структуры в двоичном файле - PullRequest
5 голосов
/ 26 мая 2010

Используя C #, мне нужно прочитать упакованный двоичный файл, созданный с использованием FORTRAN.Файл хранится в формате «Неформатированный последовательный», как описано здесь (примерно на полпути вниз по странице в разделе «Неформатированные последовательные файлы»):

http://www.tacc.utexas.edu/services/userguides/intel8/fc/f_ug1/pggfmsp.htm

Как вы можетекак видно из URL, файл организован в «чанки» длиной 130 байт или меньше и включает 2 байта длины (вставленных компилятором FORTRAN), окружающих каждый чанк.

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

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

Мои первые мысли состоят в том, чтобы сжать весь файл в байтовый массив, используя File.ReadAllBytes.Затем просто перебирайте байты, пропуская форматирование и передавая фактические данные во второй байтовый массив.

В конце концов, этот второй байтовый массив должен содержать фактическое содержимое файла за вычетом всего форматирования, которое затем мне нужно будет вернуть, чтобы получить то, что мне нужно.

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

Кроме того, если это полезно, эти файлы могут быть довольно большими (скажем, 30 МБ), хотя большинство из них будет намногоменьше ...

Ответы [ 2 ]

1 голос
/ 26 мая 2010

Один из способов чтения файлов подобным образом - запись за записью (например, чтение байтов длины, а затем порция данных, создание списка записей, которые являются просто байтовыми массивами). Затем набор записей передается в последующие процедуры синтаксического анализа.

Однако, если вы используете 4.0, есть новый класс для сопоставления файлов, который был бы более эффективным, но работал бы так же, как ReadAllBytes.

Если вы используете ReadAllBytes или MemoryMappedFile, было бы неплохо встроить "индекс" в памяти в большой двоичный файл, предварительно проанализировав все длины записи. Это особенно полезно, если вам нужны только определенные записи.

0 голосов
/ 27 мая 2010

Вместо того, чтобы перебирать байты, взгляните на System.IO.BinaryReader. Откройте файл как FileStream, оберните его в BinaryReader, и вы сможете напрямую читать примитивные типы из него, указатель потока отслеживает ваше смещение в BLOB-объекте. Вам, возможно, придется учитывать порядок байтов и пользовательские типы самостоятельно, возможно, создавая свои собственные методы расширения для BinaryReader поверх его метода для чтения отдельных байтов.

Если вам нужны данные в байтовом массиве, вы все равно можете использовать BinaryReader, если сначала оберните массив в MemoryStream.

С такими большими файлами я бы держался подальше от File.ReadAllBytes. FileStream должен буферизироваться для вас, и предложение Стивена об использовании отображенных в память файлов звучит как более изощренная (возможно, более эффективная) альтернатива этому, особенно если вам нужно сделать второй проход для форматирования.

...