#python #file-io #copy #progress-bar #pyqt4
#python #file-io #Копировать #индикатор выполнения #pyqt4
Вопрос:
Я видел задаваемые здесь ранее вопросы о Python и копировании файлов, но у меня есть другой сценарий, с которым нужно иметь дело.
Я почти закончил с установщиком дистрибутива Linux, над которым я работал, и теперь все, что ему нужно сделать, это скопировать файлы в раздел назначения. Поскольку у большинства установщиков дистрибутивов есть индикатор выполнения, я надеялся добавить его тоже.
Прямо сейчас я использую PyQt4, и мой код выглядит следующим образом:
self.status('Counting files...')
self.count = int(check_output(['-c', 'find /opt/linux/work/root-image/ -type f | wc -l'], stderr = PIPE, shell = True))
self.status('Copying files...')
i = 0
for root, dirs, files in os.walk('/opt/linux/work/root-image/'):
for file in files:
i = 1
f = os.path.join(root, file)
try:
os.system('mkdir -p /tmp/foo' os.path.split(f)[0])
except:
pass
os.system('cp ' f ' /tmp/foo' f)
if i % 100 == 0:
self.emit(SIGNAL('progress(int)'), int(100.0 * float(i) / float(self.count)))
self.status('Done...')
Это довольно неэффективно из-за индикатора выполнения. Изображение целиком 2.1GB
, и сценарию требуется действительно много времени, чтобы скопировать файлы. Намного длиннее простого cp -r
.
Есть ли какой-либо эффективный способ сделать это? Для панелей выполнения копирования одного файла все, что вы делаете, это читаете небольшие фрагменты за раз, но я понятия не имею, как это сделать для каталога с 91,489
файлами.
Любая помощь была бы полезна. Спасибо!
Ответ №1:
Вы могли бы попробовать использовать shutil.copy
для копирования файлов вместо вызова ОС с помощью os.system
(что создает отдельный процесс). Вы также можете использовать os.mkdir
для создания новых каталогов. Однако вы уверены, что это происходит медленно из-за индикатора выполнения, а не из-за чего-то еще?
Комментарии:
1. Излучение сигнала довольно сильно замедляет работу. Но я попробую эти изменения, возможно, на этот раз процессы действительно замедляют работу.
2. Если у вас 91489 файлов и вы запускаете сигнал после каждых 100 файлов, то это всего лишь 914 выбросов сигнала или около того — это не должно быть проблемой. Это намного быстрее, если вы закомментируете
self.emit
часть в цикле for и скопируете файлы один за другим, используяos.system
как указано выше?3. Сейчас я тестирую это. Кажется, застрял на неработающих символических ссылках (которые работают, если корневой каталог был исходным, но это не работает в хост-системе).
4. Очевидно, вам приходится обрабатывать такие угловые случаи самостоятельно, т. Е. заранее проверяя, является ли файл неработающей символической ссылкой (
os.path.exists
должен вернутьсяFalse
), а затем создавая символическую ссылку вручную с помощьюos.symlink
.5.Символические ссылки работают, если корневая папка
/
является папкой, из которой я копирую, поскольку папка, из которой я копирую, является FS Linux. Python не любит неработающие символические ссылки, поэтому, я думаю, мне придетсяcp
их вручную…