Как импортировать и читать данные большого двоичного файла в c#? - PullRequest
0 голосов
/ 29 мая 2020

У меня есть большой двоичный файл, который содержит разные типы данных, я могу получить доступ к отдельным записям в файле, но я не уверен, как l oop над двоичными значениями и загрузить их в поток памяти побайтно

Я использовал двоичный ридер

BinaryReader binReader = new BinaryReader(File.Open(fileName, FileMode.Open));
            Encoding ascii = Encoding.ASCII;
            string authorName = binReader.ReadString();
            Console.WriteLine(authorName);
            Console.ReadLine();

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

был бы признателен за любую мысль, которая может помочь

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

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

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

var authorName = binReader.ReadString();
var publishDate = DateTime.FromBinary(binReader.ReadInt64());
... 

Если у вас есть список элементов, обычно используется префикс длины. Что-то вроде

var numItems = binReader.ReadInt32();
for(int i = 0; i < numItems; i++){
    var title = binReader.ReadString();
    ...
}

Затем вы обычно создаете один или несколько объектов из данных, которые можно использовать в остальной части приложения. Т.е.

new Bibliography(authorName, publishDate , books);

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

Если данных больше, чем может поместиться в памяти, вам понадобится какой-то механизм потоковой передачи. Т.е. прочитать один элемент, выполнить некоторую обработку элемента, сохранить результат, прочитать следующий элемент и т. Д. c.

Если вы действительно контролируете формат, я бы предложил альтернативы, которыми проще управлять. Я использовал protobuf. * ​​1020 *, и я считаю его довольно простым в использовании, но есть и другие альтернативы. Обычный способ использования библиотек такого типа - создать класс для данных и добавить атрибуты для полей, которые следует сохранить. Библиотека может управлять сериализацией / десериализацией автоматически и обычно легко справляется с такими вещами, как наследование и изменение формата.

0 голосов
/ 29 мая 2020

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

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace binary_read
{
    class Program
    {
        private static readonly int bufferSize = 1024;

        static async Task Main(string[] args)
        {
            var bytesRead = 0;
            var totalBytes = 0;

            using (var stream = File.OpenRead(args.First()))
            {
                do
                {
                    var buffer = new byte[bufferSize];
                    bytesRead = await stream.ReadAsync(buffer, 0, bufferSize);
                    totalBytes += bytesRead;

                    // Process buffer

                } while (bytesRead > 0);

                Console.WriteLine($"Processed {totalBytes} bytes.");
            }
        }
    }
}

Основной бит, на который следует обратить внимание, находится в блоке using.

Во-первых, при работе с файлами / потоками / сокетами лучше использовать using, если возможно, чтобы детерминированно очистить после себя.

Тогда это действительно просто вопрос вызова Read / ReadAsync on stream, если вы сразу после необработанных данных. Однако существуют различные «читатели», которые предоставляют абстракцию, чтобы упростить работу с определенными форматами.

Итак, если вы знаете, что собираетесь читать целые числа, двойные числа и строки, тогда вы можете использовать BinaryReader и это методы ReadIntxx / ReadDouble / ReadString.

Если вы читаете структуру, вы можете прочитать свойства в al oop, как это было предложено @ Jona sH выше. Или используйте метод из этого ответа .

...