Python实现FTP上传文件

15

我正在尝试将文件从Windows服务器上传到Unix服务器(基本上是在尝试FTP)。 我使用了下面的代码

#!/usr/bin/python
import ftplib
import os
filename = "MyFile.py"
ftp = ftplib.FTP("xx.xx.xx.xx")
ftp.login("UID", "PSW")
ftp.cwd("/Unix/Folder/where/I/want/to/put/file")
os.chdir(r"\\windows\folder\which\has\file")
ftp.storbinary('RETR %s' % filename, open(filename, 'w').write)

我遇到了以下错误:

Traceback (most recent call last):
  File "Windows\folder\which\has\file\MyFile.py", line 11, in <module>
    ftp.storbinary('RETR %s' % filename, open(filename, 'w').write)
  File "windows\folder\Python\lib\ftplib.py", line 466, in storbinary
    buf = fp.read(blocksize)
AttributeError: 'builtin_function_or_method' object has no attribute 'read'

同时,MyFile.py 的所有内容都被删除了。

有人能给予建议吗?我已经读到了使用 ftp.storbinary 进行 FTP 文件上传的相关说明。

4个回答

17
如果您正在尝试存储一个非二进制文件(如文本文件),请尝试将其设置为读模式而不是写模式。
ftp.storlines("STOR " + filename, open(filename, 'rb'))

对于二进制文件(无法在文本编辑器中打开的任何文件),请以读取二进制模式打开您的文件。

ftp.storbinary("STOR " + filename, open(filename, 'rb'))

如果你打算使用ftp库,最好先通过一些教程学习,我推荐从effbot的这篇文章开始。


MyFile.py的内容不会被删除。但我仍然收到错误提示。 - misguided
2
使用 storlines 假定 myfile 是一个文本文件。对于其他文件(图像、电影、存档,基本上任何你不能在文本编辑器中打开并阅读的文件),你应该使用 storbinary 并用 'rb' 而不是仅仅的 'r' 打开文件。 - jilles de wit
你好 @john,如果我想移动 wav 文件而不是二进制和文本文件,我该怎么办?请问如何将 wav 文件移动到 FTP 服务器? - Susan
@Susan 我相信wav文件是二进制文件。 - John
谢谢@John。是的,我可以使用二进制格式将wav文件移动到FTP服务器。 - Susan

9

综合两个建议,最终答案是

#!/usr/bin/python
import ftplib
import os
filename = "MyFile.py"
ftp = ftplib.FTP("xx.xx.xx.xx")
ftp.login("UID", "PSW")
ftp.cwd("/Unix/Folder/where/I/want/to/put/file")
os.chdir(r"\\windows\folder\which\has\file")
myfile = open(filename, 'r')
ftp.storlines('STOR ' + filename, myfile)
myfile.close()

5
使用 storlines 函数需要 myfile 是一个文本文件。对于其他类型的文件(如图片、电影、压缩文件等,不能在文本编辑器中打开并读取的文件),应该使用 storbinary 函数,并将文件以'rb'方式打开,而不是仅用'r'方式打开。 - jilles de wit
至少在当前版本中,您需要以二进制模式('rb')打开文件才能发送它,否则会出现错误。编辑:没有意识到已经有人说过这个了^ - Eliezer Miron

3

尝试将文件制作为对象,这样你就可以在操作结束时关闭它。

myfile = open(filename, 'w')
ftp.storbinary('RETR %s' % filename, myfile.write)

在转移过程结束时

 myfile.close()

这可能不直接解决问题,但可以帮助解决问题。


0

ftplib支持使用上下文管理器,因此您可以将其简化为以下内容

    with ftplib.FTP('ftp_address', 'user', 'pwd') as ftp, open(file_path, 'rb') as file:
        ftp.storbinary(f'STOR {file_path.name}', file)
        ...

这种方式不仅可以避免在代码中插入 try/except/finally块,还可以防范文件和ftp问题。而且,它符合Python语言的风格。

PS: 由于使用了f字符串,所以只能在Python版本>=3.6以上才能使用,但是很容易修改成旧的.format()语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接