1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
1 | |
Многопоточное сжатие файла27.07.2017, 17:01. Показов 11921. Ответов 58
Метки нет Все метки)
(
Здравствуйте. Есть задача: при помощи System.IO.Compression.GZipStream сжимать файлы. Программа должна эффективно распараллеливать и синхронизировать задачи в многопроцессорной среде.
основной вопрос: как правильно распараллелить все это? изначально я думал так: 1 поток - считывает файл поблочно в некий пул блоков 2 поток - записывает сжатые блоки в файл оставшиеся берут блоки из первого пула, сжимают их, и кладут в пул с которым работает второй поток. но при детальном рассмотрении было обнаружено, что GZipStream сжимает байты в stream. Т.е. по сути я могу сжимать сразу в fileStream выходного файла. однако, если несколько потоков буду одновременно сжимать, не факт, что блоки будут записаны по порядку. Если же сжимать в memoryStream, а потом писать через CopyTo в fileStream, то при разжатии получаю пустой файл. если сжимаю в memoryStream, который потом преобразую в byte[], который пишу в fileStream, при разжатии получаю ошибку "Неправильное магическое число в заголовке GZip" после всего этого не могу придумать ничего, кроме как один поток читает файл, другой сжимает. Но это не походит на "эффективное распараллеливание задач в многопроцессорной среде". Подскажите, пожалуйста, как быть
0
|
|
27.07.2017, 17:01 | |
Ответы с готовыми решениями:
58
Многопоточное чтение файла Многопоточное скачивание файла из интернета Многопоточное чтение строк из файла |
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
|
27.07.2017, 17:25 | 2 |
Вам нужно распараллелить именно сжатие байтов. Я сомневаюсь, что можно распараллелить операции с диском.
Схема примерно такая: 1. Прочитать файл 2. Разбить на блоки равной длины. 3. Параллельно сжать эти блоки, сохранив порядок. 4. Собрать блоки и записать в файл.
0
|
1452 / 845 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
|
|
27.07.2017, 17:37 | 3 |
IamRain, movorpovor,
0. Добавить оперативы в комп))))
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
27.07.2017, 17:43 [ТС] | 4 |
IamRain а что подразумевается под "собрать блоки"
0
|
263 / 224 / 108
Регистрация: 09.12.2015
Сообщений: 652
|
|
27.07.2017, 17:44 | 5 |
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
||||||
27.07.2017, 17:53 [ТС] | 6 | |||||
уточню вопрос кодом: как мне завести это? при разжатии созданного файла создается пустой файл
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
|
27.07.2017, 17:55 | 7 |
Расположить байты блоков в том же порядке, в каком они были в исходном файле.
Блок - это просто кусок данных. Минуту, сейчас покажу.
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
27.07.2017, 18:01 [ТС] | 8 |
вот тут GZipstream - каков принцип многопоточного сжатия/распаковки? чувак делает по сути то же, что и я кодом выше, но чет не могу врубить почему у него работает, а у меня нет
0
|
263 / 224 / 108
Регистрация: 09.12.2015
Сообщений: 652
|
|
27.07.2017, 18:01 | 9 |
Если бы блоки были одинакового размера - то можно просто рассчитывать смещение.
Но разные куски исходного файла пожмутся в куски разного размера. Смержим мы их в файле. А распаковывать как будем? Где границы? ![]()
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
||||||
27.07.2017, 18:21 | 10 | |||||
Посмотрите внимательно на свой код:
Вы создаете пустой MemoryStream, а затем на его основе создаете GZipStream, который соответственно, тоже будет пустой, и затем записываете данные этого сжатого пустого ![]() Не тестировал, получилось вот так:
По вышеприведенной ссылке отработает однозначно быстрее, так как читает поблочно и сразу же сжимает, в моем примере сразу все читает, так что будет очень накладно в случае файлов большого размера. Но это просто как пример распараллеливания. Добавлено через 4 минуты Их можно смотреть на основе DataToHandle.Data.Length объектов. Но ничего не тестировалось, это первое что пришло в голову. Так что, думаю, ТС-у проще разобрать пример из им же указанной ссылки.
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
27.07.2017, 18:27 [ТС] | 11 |
если, честно, я все равно не врубаю.
вот построчный разбор моего кода, как я его вижу на языке смертных. поправьте, пожалуйста, где путаю: 1) var memory = new MemoryStream(); - создаю пустой memoryStream 2) var compressing = new GZipStream(memory, CompressionMode.Compress); - создаю GZipStream и указываю, что сжатые данные нужно транслировать в ранее созданный memoryStream 3) compressing.Write(buffer, 0, part); - прошу сжать buffer (получается, что GZipStream сжимает и пишет в memoryStream) 4) var a = memory.ToArray(); - получаю байты из memoryStream 5) fileToWrite.Write(a, 0, a.Length); - записываю байты в fileStream где я не догоняю?
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
||||||
27.07.2017, 18:31 | 12 | |||||
Строки с 8 по 13 поправить на:
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
|
27.07.2017, 18:35 | 13 |
Смотрите внимательно: (пункт 2).
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
||||||
27.07.2017, 18:36 | 14 | |||||
А исходный поток у вас пустой.
Добавлено через 1 минуту Сравните с:
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
||||||
27.07.2017, 18:45 [ТС] | 15 | |||||
подскажите пожалуйста, что можно почитать по потокам (stream) потому как я не догоняю, зачем мне писать что-то в заполненный поток, и почему не в пустой
Добавлено через 5 минут в выше указанном мною коде человек пишет
скопировал ваш код, и выскочила ошибка "System.NotSupportedException: 'Поток не поддерживает чтение.'" на строчке stream.CopyTo(targetStream)
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
||||||
27.07.2017, 18:46 | 16 | |||||
Внимательного чтения документации из MSDN вполне хватит (Stream class). Хотя бы подсказки Intellisense внимательно читайте.
Комментарии на примере вашего кода:
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
27.07.2017, 19:09 [ТС] | 17 |
IamRain вот вам ссылка на мсдн, почитайте внимательно что мы передаём первым параметром https://msdn.microsoft.com/en-... .110).aspx
0
|
263 / 224 / 108
Регистрация: 09.12.2015
Сообщений: 652
|
||||||
27.07.2017, 19:10 | 18 | |||||
IamRain, а вы уверенны, что строчка
А, может, наоборот, а?! ![]()
0
|
3084 / 2226 / 641
Регистрация: 02.08.2011
Сообщений: 6,112
|
|
27.07.2017, 19:15 | 19 |
Здесь уже я ошибся, виноват. Stream.Write - записать в поток из буфера. В таком случае, проверяйте в отладке, есть ли данные в буфере.
Ну я же сказал, я не тестировал.
0
|
1 / 1 / 0
Регистрация: 24.05.2015
Сообщений: 45
|
|
27.07.2017, 19:19 [ТС] | 20 |
В любом случае спасибо вам. Если б не вы, я б не полез на мсдн и не увидел бы ремарки, что данные заносятся не сразу, и нужен Flush()
1
|
27.07.2017, 19:19 | |
Помогаю со студенческими работами здесь
20
Сжатие файла с текстом Сжатие текстового файла
Очередь на многопоточное чтение файла Сжатие файла сжатие бинарного файла Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |