Есть ли наиболее эффективный способ чтения / записи до 10 ГБ двоичного файла в C #? - PullRequest
0 голосов
/ 10 января 2019

У нас есть проект, в котором нам нужно перенести до 10 ГБ двоичных файлов. Шаги 1) читать файл по размеру сообщения 2) сделать некоторую обработку 3) либо записать исходное сообщение или обработанное сообщение обратно в новый двоичный файл.

для файла 10 ГБ, после обработки он становится 14 ГБ. В настоящее время это занимает почти 2 часа.

Мне интересно, смогу ли я сделать какой-нибудь трюк с вводом-выводом, чтобы сократить это время.

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

                    }
                }
            }
        }

1 Ответ

0 голосов
/ 11 января 2019

Итак, наконец, в соответствии с рекомендациями Георга и некоторой очистки приведенного выше кода, мне удалось сократить время с 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);
                            }
                        }

                    }
                }
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...