Сжатие большого файла (~ 30 ГБ) параллельно? - PullRequest
0 голосов
/ 11 мая 2018

Итак, прежде всего, я читаю файл частями по 32 МБ:

var inputFileReader = new Thread(() =>
        {
            var buffer = new byte[_32_MB];
            using (var fileStream = File.Open(fileURL, FileMode.Open, FileAccess.Read))
            using (var bufferedStream = new BufferedStream(fileStream))
            {
                while (bufferedStream.Read(buffer, 0, _32_MB) != 0)
                {
                    // queue might be oversized:
                    // .Wait() suppose to guarantee it won't happen
                    _queue.Wait();
                    _queue.Push(buffer);
                }

                Console.WriteLine("File reading done.");
                _applicationIsRunning = false;
            }
        });

Тогда другие потоки (которые еще не реализованы) предполагают взять эти необработанные чанки байтов и сжать их, используя MemoryStream. Я ожидаю, что что-то вроде этого будет работать только с исправлением, которое я хотел бы повторно использовать некоторое количество потоков, а не создавать новый каждый раз:

public static byte[] GZip(byte[] bytes)
    {
        byte[] res = { };

        var compressor = new Thread(() =>
        {
            using (var memoryStream = new MemoryStream())
            using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, false))
            {
                gZipStream.Write(bytes, 0, bytes.Length);
                res = memoryStream.ToArray();
            }
        });
        compressor.Start();

        return res;
    }

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

Есть предложения?

...