简体   繁体   English

有没有最有效的方法来在C#中读取/写入最多10GB的二进制文件?

[英]Is there a most efficient way to read/write upto 10GB binary file in C#?

We have a project where we need to migrate up to 10GB of binary files. 我们有一个项目,需要迁移多达10GB的二进制文件。 The steps are 1) read file by message size 2) do some processing 3) either write the original message or processed message back to a new binary file. 步骤是1)按消息大小读取文件2)做一些处理3)将原始消息或已处理的消息写回到新的二进制文件中。

for a 10GB file, after processing it becomes 14GB. 对于10GB的文件,处理后将变为14GB。 Currently it takes nearly 2 hours. 目前大约需要2个小时。

I am wondering if I can do some IO trick to trim that time down. 我想知道我是否可以做一些IO技巧来减少时间。

using (FileStream fsInput =new FileStream(inputfilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (FileStream fsOutput = File.Create(outputfilename))
            {
                long total = fsInput.Length;
                long progress = 0;

                unsafe
                {
                    int hdrSize = sizeof(FullMessageHeader);
                    byte[] headerBuffer = new byte[hdrSize];

                    while (fsInput.Position < fsInput.Length)
                    {                         
                        progress += fsInput.Read(headerBuffer, 0, hdrSize);
                        int msgSize = 0;
                        fixed (byte* hdr = headerBuffer)
                        {
                            msgSize = *(int*)(hdr + MessageHeaderOffsets.Size);
                        }

                        byte[] msg = new byte[msgSize];
                        Buffer.BlockCopy(headerBuffer, 0, msg, 0, headerBuffer.Length);
                        fsInput.Position -= hdrSize;
                        progress += fsInput.Read(msg, 0, msgSize);

                        fixed (byte* ptr = msg)
                        {
                            byte[] ba = ProcessMessage(ptr);
                            if (ba.Length == 0)
                            {
                                fsOutput.Write(msg, 0, msg.Length);
                            }
                            else
                            {
                                fsOutput.Write(ba, 0, ba.Length);
                            }
                        }

                    }
                }
            }
        }

so finally as suggested by Georg, and some clean up of the above code, I was able to reduce the time from 2 hours to 10 minutes which is not the most optimum but acceptable. 因此,最后由Georg建议,并对上面的代码进行了一些整理,我能够将时间从2小时减少到10分钟,这不是最佳选择,但可以接受。

        Dictionary<int, byte[]> byteDictionary = new Dictionary<int, byte[]>();
        using (FileStream fsInput =new FileStream(inputfilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (FileStream fsOutput = File.Create(outputfilename))
            {
                long total = fsInput.Length;
                long progress = 0;

                unsafe
                {
                    int hdrSize = sizeof(FullMessageHeader);
                    byte[] headerBuffer = new byte[hdrSize];

                    while (fsInput.Position < fsInput.Length)
                    {                         
                        progress += fsInput.Read(headerBuffer, 0, hdrSize);
                        int msgSize = 0;
                        fixed (byte* hdr = headerBuffer)
                        {
                            msgSize = *(int*)(hdr + MessageHeaderOffsets.Size);
                        }

                        byte[] msg = byteDictionary.ContainsKey(msgSize)
                            ? byteDictionary[msgSize]
                            : new byte[msgSize];
                        if (!byteDictionary.ContainsKey(msgSize))
                        {
                            byteDictionary[msgSize] = msg;
                        }
                        //byte[] msg = new byte[msgSize];
                        //Buffer.BlockCopy(headerBuffer, 0, msg, 0, headerBuffer.Length);
                        fsInput.Position -= hdrSize;
                        progress += fsInput.Read(msg, 0, msgSize);

                        fixed (byte* ptr = msg)
                        {
                            //fsOutput.Write(msg,0,msg.Length);
                            byte[] ba = ProcessMessage(ptr);
                            if (ba.Length == 0)
                            {
                                fsOutput.Write(msg, 0, msg.Length);
                            }
                            else
                            {
                                fsOutput.Write(ba, 0, ba.Length);
                            }
                        }

                    }
                }
            }
        }

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

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