Подтвердить что ты не робот

Python копирует более крупный файл слишком медленно

Я пытаюсь скопировать большой файл ( > 1 ГБ) с жесткого диска на USB-накопитель с помощью shutil.copy. Простой script, изображающий то, что я пытаюсь сделать, это: -

import shutil
src_file = "source\to\large\file"
dest = "destination\directory"
shutil.copy(src_file, dest)

Для linux требуется всего 2-3 минуты. Но одна и та же копия файла в том же файле занимает более 10-15 минут под Windows. Может ли кто-нибудь объяснить, почему и дать какое-то решение, предпочтительно используя код python?

Обновление 1

Сохраненный файл в формате файла test.pySource составляет 1 ГБ. Каталог Destination находится в USB-накопителе. Вычисленное время копирования файла с помощью ptime. Результат здесь: -

ptime.exe test.py

ptime 1.0 for Win32, Freeware - http://www.
Copyright(C) 2002, Jem Berkes <[email protected]

===  test.py ===

Execution time: 542.479 s

542,479 с = 9 мин. Я не думаю, что shutil.copy займет 9 минут для копирования 1 ГБ файла.

Обновление 2

Здоровье USB хорошо, так же как и script работает под Linux. Вычисленное время с тем же файлом под окнами native xcopy. Вот результат.

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <[email protected]>

===  xcopy F:\test.iso L:\usb\test.iso
1 File(s) copied

Execution time: 128.144 s

128,144 с == 2,13 мин. У меня есть свободное место на 1.7 ГБ даже после копирования тестового файла.

4b9b3361

Ответ 1

Ваша проблема не имеет ничего общего с Python. Фактически, процесс копирования Windows действительно неудовлетворительный по сравнению с системой Linux.

Вы можете улучшить это, используя xcopy или robocopy в соответствии с этим сообщением: Является ли (Ubuntu) алгоритмом копирования файлов Linux лучше, чем Windows 7?. Но в этом случае вы должны делать разные вызовы для Linux и Windows...

import os
import shutil
import sys

source = "source\to\large\file"
target = "destination\directory"

if sys.platform == 'win32':
    os.system('xcopy "%s" "%s"' % (source, target))
else:
    shutil.copy(source, target)

См. также:

Ответ 2

Просто добавьте интересную информацию: WIndows не любит крошечный буфер, используемый во внутренних реализациях shutil.

Я быстро попробовал следующее:

  • Скопировал исходный файл shutil.py в папку script и переименовал его в myshutil.py
  • Изменена первая строка до import myshutil
  • Отредактировал файл myshutil.py и изменил copyfileobj с

def copyfileobj (fsrc, fdst, length = 16 * 1024):

к

def copyfileobj (fsrc, fdst, length = 16 * 1024 * 1024):

Использование 16-мегабайтного буфера вместо 16 КБ привело к значительному повышению производительности.

Возможно, Python нуждается в некоторой настройке, ориентированной на характеристики внутренней файловой системы Windows?

Edit:

Пришло к лучшему решению здесь. В начале вашего файла добавьте следующее:

import shutil

def _copyfileobj_patched(fsrc, fdst, length=16*1024*1024):
    """Patches shutil method to hugely improve copy speed"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)
shutil.copyfileobj = _copyfileobj_patched

Это простой патч для текущей реализации и безупречно работает здесь.