2013-05-31 9 views
8

Tôi hiện đang sử dụng shutil.copy2() để sao chép một số lượng lớn tệp và thư mục hình ảnh (bất kỳ nơi nào giữa 0,5 và 5 biểu diễn). Shutil hoạt động tốt, nhưng quá chậm. Tôi đang tự hỏi nếu có một cách để vượt qua thông tin này qua Windows để làm cho bản sao và đưa cho tôi hộp thoại chuyển giao tiêu chuẩn của nó. Bạn biết đấy, anh chàng này ...Sao chép bằng hộp thoại sao chép Windows

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

Nhiều lần, kịch bản của tôi sẽ mất khoảng gấp đôi so với thời gian các cửa sổ tiêu chuẩn sao chép mất, và nó làm cho tôi lo lắng rằng thông dịch viên python của tôi bị treo trong khi đang chạy các bản sao. Tôi chạy quá trình sao chép nhiều lần và tôi đang tìm cách cắt giảm thời gian.

+1

bạn đã thực sự đúng lúc chuyển file của cùng một tập tin sử dụng cả Python và Windows Explorer? Tôi có một thời gian rất khó tin rằng Python thực sự chậm hơn. –

+0

Có, tôi đã làm một bài kiểm tra bên cạnh. Đó là trên một mạng, vì vậy có lẽ tốc độ mạng đã can thiệp, nhưng làm thế nào để tôi tìm thấy tốc độ truyền của tôi với shutil? – tylerART

+0

Bạn có thể sử dụng 'time.clock()' trong Python để có được thời gian truyền, nhưng bạn phải sử dụng đồng hồ bấm giờ cho thời gian Explorer. Giả định của tôi là cả Python và Explorer thực hiện cùng một thư viện gọi để thực hiện bản sao, nhưng Explorer cảm thấy nhanh hơn vì thanh tiến trình và có thể do một số ước tính thời gian không chính xác mà nó cung cấp cho bạn. Nếu bạn chạy cả hai cùng một lúc và thấy sự khác biệt lớn, đó là khá thú vị! –

Trả lời

1

Xem IFileCopy. IFileOperation có thể có sẵn thông qua ctypes và shell32.dll, tôi không chắc chắn.

4

Nếu mục tiêu của bạn là hộp thoại sao chép ưa thích, SHFileOperation Chức năng API Windows cung cấp điều đó. gói pywin32 có một ràng buộc python cho nó, ctypes cũng là một tùy chọn (google "SHFileOperation ctypes" cho ví dụ).

Dưới đây là của tôi (thử nghiệm rất nhẹ) ví dụ sử dụng 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 

Bạn cũng có thể thực hiện các hoạt động sao chép tương tự trong "chế độ im lặng" (không có hộp thoại, không confirmationsm, không có popup lỗi) nếu bạn thiết lập các cờ ở trên để shellcon.FOF_SILENT | shellcon.FOF_NOCONFIRMATION | shellcon.FOF_NOERRORUI | shellcon.FOF_NOCONFIRMMKDIR. Xem SHFILEOPSTRUCT để biết chi tiết.

+0

Tôi đã hỏi ở đây về giá trị trả về của 'shell.SHFileOperation' cho một _delete_: http://stackoverflow.com/questions/29053189/python-win32com-shell-shfileoperation-any-way-to-get-the- files-that-was-actua.Dường như không tìm thấy bất kỳ tài liệu nào –

+0

Và ở đây tôi lại tự hỏi nếu 'src = os.path.abspath (src)' nên là 'src = os.path.abspath (src) + '\ 0'' (giống với tham gia dưới đây) –

1

Cập nhật: Xem

Sẽ được tốt đẹp để có nó được bọc trong một thư viện ... Với sự giúp đỡ của các câu trả lời ở trên, tôi đã có thể để có được nó hoạt động trên các cửa sổ 7 như sau.

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) 

Các tài liệu tham khảo ở đây cũng rất hữu ích: http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html

+0

Xin lỗi để trả lời quá muộn, nhưng điều này có vẻ rất hứa hẹn. Tôi nhận được một lỗi chạy điều này nói rằng mô-đun trình bao không có một thuộc tính CLSID_FileOperation. – tylerART

+0

CLSID_FileOperation không có trong phiên bản pip của pywin32. Bạn có phiên bản pywin32 218.4+ không? Xem https://github.com/frmdstryr/pywinutils – frmdstryr

+0

CLSID_FileOperation nằm trong pywin 220 –