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

8 投票
2 回答
37910 浏览
提问于 2025-04-15 21:31

我的问题和这个很相似。

如何用变量从网络共享复制文件到本地磁盘?

唯一的不同是我的网络驱动器有用户名和密码的保护。

我需要用 Python 将文件复制到一个 Samba 共享,并且要验证这个过程。

如果我手动登录,那么代码就能正常工作,但如果不登录,shutil 命令就无法执行。

2 个回答

4

如果你安装了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

ActiveState Code上有一个更完整的例子

12

我会尝试通过调用 NET USE 命令,把共享文件映射到一个未使用的驱动器字母上,前提是你在使用Windows系统:

os.system(r"NET USE P: \\ComputerName\ShareName %s /USER:%s\%s" % (password, domain_name, user_name))

映射好共享文件到驱动器字母后,你可以用 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")

撰写回答