#python #windows
#python #Windows
Вопрос:
Я пытаюсь создать скрипт, который перемещает файл в папку назначения при его добавлении в исходную папку, но я получаю сообщение об ошибке, в котором говорится, что файл, который я пытаюсь переместить, используется чем-то другим. Однако странно то, что иногда это работает просто отлично, а иногда выдает следующую ошибку:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:/Users/username/Desktop/Python/download_manager/test/20200728_184438000_iOS.MOV' -> 'C:/Users/username/Desktop/Python/download_manager/test2/20200728_184438000_iOS.MOV'
и
PermissionError: [Errno 13] Permission denied: 'C:/Users/username/Desktop/Python/download_manager/test/20200728_184438000_iOS.MOV'
Вот мой код:
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import os
import json
import time
import shutil
class Handler(FileSystemEventHandler):
def on_modified(self, event):
for filename in os.listdir(folder_to_track):
src = folder_to_track "/" filename
new_destination = folder_destination "/" filename
print ('moving {} to {}'.format(src,new_destination))
shutil.move(src, new_destination)
folder_to_track = "C:/Users/olivi/Desktop/Python/download_manager/test"
folder_destination = "C:/Users/olivi/Desktop/Python/download_manager/test2"
event_handler = Handler()
observer = Observer()
observer.schedule(event_handler, folder_to_track, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
Редактировать:
Я внес следующие изменения, и, похоже, теперь он работает более надежно (хотя иногда он все еще выводит из себя …):
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import os
import json
import time
import shutil
import logging
logging.basicConfig(filename="logs.txt", filemode='w', level=logging.INFO, format='%(asctime)-15s %(message)s', datefmt='%Y/%d/%m %H:%M:%S')
class Handler(FileSystemEventHandler):
def on_modified(self, event):
for filename in os.listdir(folder_to_track):
while True:
src = folder_to_track "/" filename
new_destination = folder_destination "/" filename
try:
shutil.move(src, new_destination)
logging.info('moved {} to {}'.format(src, new_destination))
except PermissionError:
continue
break
folder_to_track = "C:/Users/olivi/Downloads"
folder_destination = "C:/Users/olivi/Desktop/Python/download_manager/test"
event_handler = Handler()
observer = Observer()
observer.schedule(event_handler, folder_to_track, recursive=True)
observer.start()
logging.info('--Service Started--')
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
logging.warning(KeyboardInterrupt)
observer.join()
Комментарии:
1. Угадайте:
observer
папка заблокирована, поэтому любая попытка изменить содержимое завершается неудачей. Попробуйте остановитьobserver
перед перемещением, затем перезапустите его.2. Если это не сработает, возможно,
os.listdir
файл заблокирован. Попробуйте сначала прочитать имена файлов в списке.3. Единственное, чего я не понимаю, это почему иногда это работает отлично, а иногда нет…
4. Если
folder_to_track
иfolder_destination
находятся в одной файловой системе, тоshutil.move
можно использоватьos.rename
. Для этого требуется открытьsrc
файл с доступом к удалению (переименованию), который, по-видимому, не используется совместно с открытыми в данный момент ссылками на файл, что приводит кERROR_SHARING_VIOLATION
(32).shutil.move
выполняется возврат к копированию и удалению файла. Для копирования требуется открытие с доступом для чтения, что также, вероятно, приводит к сбою из-за нарушения общего доступа, ноopen
, в отличиеos.rename
, вызывает исключение только для genericEACCES
(13), теряя конкретный код ошибки Windows (32).5. Вероятно, это состояние гонки, для которого простейшим решением является повторная попытка несколько раз в цикле с увеличивающимся временем ожидания.