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

问题描述 投票:0回答:3

我的和这个问题类似。

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

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

我需要使用

Samba
将文件复制到
Python
共享并进行验证。

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

shutil
命令将不起作用。

python network-programming share drive
3个回答
12
投票

我会尝试使用

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

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")

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 代码的更完整示例


0
投票

我发现这个以及许多其他解决方案对我来说不起作用。我在非 Windows 计算机上运行 python。 我也尝试了一些AI建议的解决方案,但也不起作用。最后,我安装并使用了smbprotocol。 smbclient 是其中的一部分。这对我有用:

import smbclient
smbclient.ClientConfig(username='username', password='password')

source_file_path = "path/to/local/sourcefile"
destination_file_path = r"//your_server/your_share/your_file"

with smbclient.open_file(destination_file_path, mode="w") as fd:
    fd.write(open(source_file_path, "r").read())

smbclient.reset_connection_cache() # Reset the SMB client connection cache
© www.soinside.com 2019 - 2024. All rights reserved.