2013-05-31 11 views
8

Attualmente sto utilizzando shutil.copy2() per copiare un gran numero di file di immagine e cartelle (ovunque tra 0,5 e 5 concerti). Shutil funziona bene, ma è così lento. Mi chiedo se c'è un modo per passare queste informazioni a Windows per creare la copia e darmi la sua finestra di dialogo di trasferimento standard. Sai, questo ragazzo ...Copia utilizzando la finestra di dialogo di copia di Windows

http://www.top-windows-tutorials.com/images/file-copy.jpg

Molte volte, il mio script prenderà circa il doppio del tempo gli standard di Windows copiare prende, e mi rende nervoso che il mio interprete Python si blocca durante l'esecuzione della copia. Eseguo il processo di copia più volte e sto cercando di ridurre il tempo.

+1

Avete in realtà cronometrato i trasferimenti di file dello stesso file utilizzando sia Python e Windows Explorer? Ho difficoltà a credere che Python sia effettivamente più lento. –

+0

Sì, ho fatto un test fianco a fianco. È attraverso una rete, quindi forse la velocità della rete stava interferendo, ma come faccio a trovare le velocità di trasferimento con shutil? – tylerART

+0

Si potrebbe usare 'time.clock()' in Python per ottenere il tempo di trasferimento, ma si dovrebbe usare un cronometro per il tempo Explorer. La mia supposizione sarebbe che sia Python che Explorer eseguono la stessa chiamata di libreria per eseguire la copia, ma Explorer si sente più veloce a causa della barra di avanzamento e forse a causa di alcune stime di tempo errate fornite. Se hai eseguito entrambi nello stesso momento e hai riscontrato enormi differenze, è piuttosto interessante! –

risposta

1

Vedere IFileCopy. IFileOperation può essere disponibile tramite ctypes e shell32.dll, non sono sicuro.

4

Se il tuo obiettivo è una finestra di dialogo copia fantasia, la funzione API di Windows SHFileOperation lo fornisce. Il pacchetto pywin32 ha un collegamento Python per esso, anche i ctypes sono un'opzione (per esempio "SHFileOperation SHFile" per gli esempi).

Qui è la mia (molto leggermente testato) Esempio con pywin32:

import os.path 
from win32com.shell import shell, shellcon 


def win32_shellcopy(src, dest): 
    """ 
    Copy files and directories using Windows shell. 

    :param src: Path or a list of paths to copy. Filename portion of a path 
       (but not directory portion) can contain wildcards ``*`` and 
       ``?``. 
    :param dst: destination directory. 
    :returns: ``True`` if the operation completed successfully, 
       ``False`` if it was aborted by user (completed partially). 
    :raises: ``WindowsError`` if anything went wrong. Typically, when source 
      file was not found. 

    .. seealso: 
     `SHFileperation on MSDN <http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx>` 
    """ 
    if isinstance(src, basestring): # in Py3 replace basestring with str 
     src = os.path.abspath(src) 
    else: # iterable 
     src = '\0'.join(os.path.abspath(path) for path in src) 

    result, aborted = shell.SHFileOperation((
     0, 
     shellcon.FO_COPY, 
     src, 
     os.path.abspath(dest), 
     shellcon.FOF_NOCONFIRMMKDIR, # flags 
     None, 
     None)) 

    if not aborted and result != 0: 
     # Note: raising a WindowsError with correct error code is quite 
     # difficult due to SHFileOperation historical idiosyncrasies. 
     # Therefore we simply pass a message. 
     raise WindowsError('SHFileOperation failed: 0x%08x' % result) 

    return not aborted 

È inoltre possibile eseguire la stessa operazione di copia in "modalità silenziosa" (senza dialogo, senza confirmationsm, nessun pop-up di errore) se si imposta le bandiere sopra a shellcon.FOF_SILENT | shellcon.FOF_NOCONFIRMATION | shellcon.FOF_NOERRORUI | shellcon.FOF_NOCONFIRMMKDIR. Vedere SHFILEOPSTRUCT per i dettagli.

+0

Ho chiesto qui i valori di ritorno di 'shell.SHFileOperation' per un _delete_: http://stackoverflow.com/questions/29053189/python-win32com-shell-shfileoperation-any-way-to-get-the- file-che-erano-Actua.Non riesco a trovare alcun documento –

+0

E qui mi sto chiedendo di nuovo se 'src = os.path.abspath (src)' dovrebbe essere 'src = os.path.abspath (src) + '\ 0'' (lo stesso con il join sotto) –

1

Update: Vedi

sarebbe bello avere avvolto in una libreria ... Con l'aiuto delle risposte di cui sopra, sono stato in grado di ottenere funziona su Windows 7 come segue.

import pythoncom 
from win32com.shell import shell,shellcon 

def win_copy_files(src_files,dst_folder):   
     # @see IFileOperation 
     pfo = pythoncom.CoCreateInstance(shell.CLSID_FileOperation,None,pythoncom.CLSCTX_ALL,shell.IID_IFileOperation) 

     # Respond with Yes to All for any dialog 
     # @see http://msdn.microsoft.com/en-us/library/bb775799(v=vs.85).aspx 
     pfo.SetOperationFlags(shellcon.FOF_NOCONFIRMATION) 

     # Set the destionation folder 
     dst = shell.SHCreateItemFromParsingName(dst_folder,None,shell.IID_IShellItem) 

     for f in src_files: 
       src = shell.SHCreateItemFromParsingName(f,None,shell.IID_IShellItem) 
       pfo.CopyItem(src,dst) # Schedule an operation to be performed 


     # @see http://msdn.microsoft.com/en-us/library/bb775780(v=vs.85).aspx 
     success = pfo.PerformOperations() 

     # @see sdn.microsoft.com/en-us/library/bb775769(v=vs.85).aspx 
     aborted = pfo.GetAnyOperationsAborted() 
     return success and not aborted 


files_to_copy = [r'C:\Users\jrm\Documents\test1.txt',r'C:\Users\jrm\Documents\test2.txt'] 
dest_folder = r'C:\Users\jrm\Documents\dst' 
win_copy_files(files_to_copy,dest_folder) 

I riferimenti qui erano anche molto disponibile: http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html

+0

Siamo spiacenti di rispondere così tardi, ma questo sembra molto promettente. Sto ricevendo un errore in esecuzione dicendo che il modulo shell non ha un attributo CLSID_FileOperation. – tylerART

+0

CLSID_FileOperation non era nella versione pip di pywin32. Hai la versione pywin32 218.4+? Vedi https://github.com/frmdstryr/pywinutils – frmdstryr

+0

CLSID_FileOperation è in pywin 220 –

Problemi correlati