Копирование файлов с использованием фрагментированного потока приводит к разным размерам файлов из-за последнего чтения - PullRequest
0 голосов
/ 11 января 2019

Может ли кто-нибудь проявить любезность и объяснить, как я получаю файлы одинакового размера после их копирования с использованием фрагментированного потока? Я предполагаю, что это потому, что последний блок все еще имеет buffer размер 2048 , поэтому он ставит пустые байты в конце, но я не уверен, как бы я настроил последнее чтение?

Оригинальный размер: 15,1 МБ ( 15 835 745 байт) Новый размер: 15,1 МБ ( 15 837 184 байт)

        static FileStream incomingFile;

        static void Main(string[] args)
        {
            incomingFile = new FileStream(
             @"D:\temp\" + Guid.NewGuid().ToString() + ".png",
               FileMode.Create, 
               FileAccess.Write);

            FileCopy();
        }

        private static void FileCopy()
        {

            using (Stream source = File.OpenRead(@"D:\temp\test.png"))
            {

                byte[] buffer = new byte[2048];

                var chunkCount = source.Length;

                for (int i = 0; i < (chunkCount / 2048) + 1; i++)
                {
                    source.Position = i * 2048;
                    source.Read(buffer, 0, 2048);
                    WriteFile(buffer);
                }
                incomingFile.Close();
            }

        }
        private static void WriteFile(byte[] buffer)
        {

            incomingFile.Write(buffer, 0, buffer.Length);
        }

1 Ответ

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

Чтение last buffer не обязательно должно содержать ровно 2048 байтов (оно может быть неполным ). Представьте, у нас есть файл 5000 байтов; в этом случае будет читаться 3 чанков: 2 завершено и 1 не завершено

2048 
2048  
 904 the last incomplete buffer

Код:

        using (Stream source = File.OpenRead(@"D:\temp\test.png"))
        {

            byte[] buffer = new byte[2048];

            var chunkCount = source.Length;

            for (int i = 0; i < (chunkCount / 2048) + 1; i++)
            {
                source.Position = i * 2048;

                // size - number of actually bytes read 
                int size = source.Read(buffer, 0, 2048);

                // if we bytes to write, do it
                if (size > 0)
                    WriteFile(buffer, size);
            }
            incomingFile.Close();
        }

        ... 

        private static void WriteFile(byte[] buffer, int size = -1) 
        {
           incomingFile.Write(buffer, 0, size < 0 ? buffer.Length : size);
        }

В вашем случае вы пишете 15837184 == 7733 * 2048 байт (7733 завершено чанков), когда вы должны написать 15835745 == 7732 * 2048 + 609 байт - 7732 завершить чанков и последние неполный один из 609 байтов

...