Разметка файла для параллельной загрузки - PullRequest
2 голосов
/ 27 января 2012

Я хочу сделать многопоточный загрузчик (на Python), и мне нужно указать каждому потоку, с чего начать и сколько байтов загрузить. Для этого я получаю удаленный размер файла и делю его, например, на 2. Теперь предположим, что размер удаленного файла равен 5: когда я делю число на 2, я получаю 2 в результате. Теперь я могу начать загрузку, но я потеряю байт (потому что 2*2=4, а не 5). Я не могу использовать числа с плавающей запятой, потому что я не могу загрузить половину байта. Как я могу разделить это число и получить список с [2, 3], например?

Ответы [ 3 ]

3 голосов
/ 27 января 2012

Использование divmod:

>>> divmod(5, 2)
(2, 1)
>>>

Это говорит о том, что 5, деленное на 2 - это 2, остаток 1, поэтому последний кусок будет 2 + 1 = 3.

>>> divmod(12345, 6)
(2057, 3)

Здесь у вас будет 5 блоков в 2057 году и последний кусок в 2057 + 3.

Этот алгоритм также будет работать для случаев, когда деление не имеет остатка:

>>> divmod(12345, 5)
(2469, 0)

Здесь у вас будет 4 фрагмента в 2469 плюс последний фрагмент в 2469 + 0.

Итак, размеры вашего чанка могут быть вычислены как:

def chunk_sizes(filesize, num_chunks):
    d, r = divmod(filesize, num_chunks)
    result = [d] * num_chunks
    result[-1] += r
    return result
1 голос
/ 27 января 2012

Если вы хотите получить размер каждого чанка, вы можете просто добавить остаток от деления до последнего элемента:

>>> file_size = 11
>>> no_of_chunks = 3
>>> chunks = [file_size / no_of_chunks] * no_of_chunks
>>> chunks[-1] += file_size % no_of_chunks
>>> chunks
[3, 3, 5]

Вы также можете изменить это, чтобы распределить остаток по всем чанкам, чтобы размер чанков отклонялся максимум на 1:

>>> for i in range(file_size % no_of_chunks):
>>>    chunks[i] += 1
>>> chunks
[4, 4, 3]
0 голосов
/ 27 января 2012

Особый случай последнего потока - назначьте его, чтобы получить сколько байтов осталось.

...