繁体   English   中英

如何在c#中导入和读取大二进制文件数据?

[英]How to import and read large binary file data in c#?

我有一个包含不同数据类型的大型二进制文件,我可以访问文件中的单个记录,但我不确定如何循环访问二进制值并将其逐字节加载到 memory stream 中

我一直在使用二进制阅读器

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

但这不起作用,因为我有一个具有不同数据类型的大文件,我需要将文件转换为逐字节读取,然后读取这些数据(如果它是字符串或其他数据)。

将不胜感激任何可以帮助的想法

这是一段简单的代码,显示了最基本的方法。

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

如果您只是在获取原始数据,那么实际上只需在stream上调用Read / ReadAsync即可。 然而,有各种“阅读器”提供了一种抽象,使使用某些格式更容易。

因此,如果您知道要读取整数、双精度和字符串,那么您可以使用BinaryReader及其 ReadIntxx/ReadDouble/ReadString 方法。

如果您正在读取结构,那么您可以按照上面@JonasH 的建议在循环中读取属性。 或者使用这个答案中的方法。

这在很大程度上取决于文件的格式。文件中的每个字节可能代表不同的东西,或者它可能只代表一个大数组中的值,或者两者的混合。

您需要知道格式是什么样子才能读取它,因为二进制文件不是自我描述的。 读一个简单的 object 可能看起来像

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();
    ...
}

然后,您通常会根据可在应用程序的 rest 中使用的数据创建一个或多个对象。 IE

new Bibliography(authorName, publishDate , books);

如果这是您无法控制的格式,我希望您有详细的规范。 否则,除了最复杂的解决方案之外,这对于任何事情都是一种失败的原因。

如果数据量超出 memory 的容量,则需要某种流式传输机制。 即读取一个项目,对该项目进行一些处理,保存结果,读取下一个项目等。

如果您确实控制了格式,我会建议更易于管理的替代方案。 我使用过protobuf.Net ,我发现它很容易使用,但还有其他选择。 使用这类库的常用方法是为数据创建 class,并为应存储的字段添加属性。 该库可以自动管理序列化/反序列化,通常可以轻松处理 inheritance 和格式更改等事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM