我目前正在使用shutil.copy2()
复制大量图像文件和文件夹(0.5到5 gigs之间)。 Shutil
工作正常,但速度很慢。我想知道是否有办法将此信息传递给Windows以制作副本并给我标准的传输对话框。你知道,这家伙......
很多时候,我的脚本需要大约两倍于标准Windows副本所花费的时间,并且让我感到紧张的是我的python解释器在运行副本时挂起。我多次运行复制过程,我希望减少时间。
答案 0 :(得分:4)
如果您的目标是花哨的复制对话框,SHFileOperation Windows API函数提供了这一点。 pywin32包有一个python绑定,ctypes也是一个选项(例如google“SHFileOperation ctypes”)。
这是使用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
如果您将上面的标记设置为shellcon.FOF_SILENT | shellcon.FOF_NOCONFIRMATION | shellcon.FOF_NOERRORUI | shellcon.FOF_NOCONFIRMMKDIR.
,请参阅SHFILEOPSTRUCT以获取详细信息,也可以在“静音模式”(无对话框,无确认,无错误弹出窗口)中执行相同的复制操作。
答案 1 :(得分:2)
更新:见
将它包装在库中会很高兴...借助上面的答案,我能够在Windows 7上运行它,如下所示。
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)
此处的参考资料也非常有用: http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html
答案 2 :(得分:1)
见IFileCopy。通过ctypes和shell32.dll可以使用IFileOperation ,我不确定。
答案 3 :(得分:0)
*碰撞* Windows 10!
在您的所有帮助下,Virgil Dupras' send2trash:
我只是使用ctypes
煮了一个香草 Python版本:
import ctypes
from ctypes import wintypes
class _SHFILEOPSTRUCTW(ctypes.Structure):
_fields_ = [("hwnd", wintypes.HWND),
("wFunc", wintypes.UINT),
("pFrom", wintypes.LPCWSTR),
("pTo", wintypes.LPCWSTR),
("fFlags", ctypes.c_uint),
("fAnyOperationsAborted", wintypes.BOOL),
("hNameMappings", c_uint),
("lpszProgressTitle", wintypes.LPCWSTR)]
def win_shell_copy(src, dst):
"""
:param str src: Source path to copy from. Must exist!
:param str dst: Destination path to copy to. Will be created on demand.
:return: Success of the operation. False means is was aborted!
:rtype: bool
"""
src_buffer = ctypes.create_unicode_buffer(src, len(src) + 2)
dst_buffer = ctypes.create_unicode_buffer(dst, len(dst) + 2)
fileop = _SHFILEOPSTRUCTW()
fileop.hwnd = 0
fileop.wFunc = 2 # FO_COPY
fileop.pFrom = wintypes.LPCWSTR(ctypes.addressof(src_buffer))
fileop.pTo = wintypes.LPCWSTR(ctypes.addressof(dst_buffer))
fileop.fFlags = 512 # FOF_NOCONFIRMMKDIR
fileop.fAnyOperationsAborted = 0
fileop.hNameMappings = 0
fileop.lpszProgressTitle = None
result = ctypes.windll.shell32.SHFileOperationW(ctypes.byref(fileop))
return not result
✔在src和dst路径较长的Python 3.7和2.7上进行了测试。
❌仍不检查src是否存在。