如何使用Python将文件复制到网络路径或驱动器

如何使用Python将文件复制到网络路径或驱动器,python,network-programming,share,drive,Python,Network Programming,Share,Drive,我的问题与这个问题类似 唯一的区别是我的网络驱动器有一个用户名和密码保护 我需要使用Python将文件复制到Samba共享,并对其进行验证 如果我手动登录,则代码可以工作,但不登录shutil命令不工作。我会尝试使用os.system调用NET USE命令,将共享映射到未使用的驱动器号(假设您在Windows上): 将共享映射到驱动器号后,可以使用shutil.copyfile将文件复制到给定驱动器。最后,您应该卸载共享: os.system(r"NET USE P: /DELETE") 当

我的问题与这个问题类似

唯一的区别是我的网络驱动器有一个用户名和密码保护

我需要使用
Python
将文件复制到
Samba
共享,并对其进行验证


如果我手动登录,则代码可以工作,但不登录
shutil
命令不工作。

我会尝试使用
os.system
调用
NET USE
命令,将共享映射到未使用的驱动器号(假设您在Windows上):

将共享映射到驱动器号后,可以使用
shutil.copyfile
将文件复制到给定驱动器。最后,您应该卸载共享:

os.system(r"NET USE P: /DELETE")
当然,这只适用于Windows,您必须确保驱动器号p可用。您可以检查
NET USE
命令的返回代码,查看装载是否成功;如果没有,您可以尝试其他驱动器号,直到成功

由于两个
NET USE
命令成对出现,并且在执行第一个命令时应始终执行第二个命令(即使在这两个命令之间引发了异常),因此如果您使用的是Python 2.5或更高版本,则可以在上下文管理器中包装这两个调用:

from contextlib import contextmanager

@contextmanager
def network_share_auth(share, username=None, password=None, drive_letter='P'):
    """Context manager that mounts the given share using the given
    username and password to the given drive letter when entering
    the context and unmounts it when exiting."""
    cmd_parts = ["NET USE %s: %s" % (drive_letter, share)]
    if password:
        cmd_parts.append(password)
    if username:
        cmd_parts.append("/USER:%s" % username)
    os.system(" ".join(cmd_parts))
    try:
        yield
    finally:
        os.system("NET USE %s: /DELETE" % drive_letter)

with network_share_auth(r"\\ComputerName\ShareName", username, password):
     shutil.copyfile("foo.txt", r"P:\foo.txt")

如果您有pywin32库(例如,它是ActiveState Python发行版的一部分),那么您只需几行就可以完成,而无需映射驱动器:

import win32wnet
win32wnet.WNetAddConnection2(0, None, '\\\\'+host, None, username, password)
shutil.copy(source_file, '\\\\'+host+dest_share_path+'\\')
win32wnet.WNetCancelConnection2('\\\\'+host, 0, 0) # optional disconnect

Hi域名参数是什么?当正在验证的用户位于不同的身份验证域下时,可以使用doomain name参数。我没有将它包含在contextlib版本中,因为它可以简单地成为用户名的一部分。如果正在验证的用户与当前用户位于同一域中,则可以省略该域。谢谢。。。它起作用了。。。只有当我第二次运行它时,我才会收到一个错误,说本地设备正在使用中。谢谢。。。使用子流程导致了很多问题,但您的os.system方法工作得很好!5年后。。。这对我有帮助。干杯
import win32wnet
win32wnet.WNetAddConnection2(0, None, '\\\\'+host, None, username, password)
shutil.copy(source_file, '\\\\'+host+dest_share_path+'\\')
win32wnet.WNetCancelConnection2('\\\\'+host, 0, 0) # optional disconnect