【问题标题】:how to write to a file on a remote server using ftplib如何使用 ftplib 写入远程服务器上的文件
【发布时间】:2019-08-21 00:04:29
【问题描述】:

我需要在远程服务器上以写入模式打开一个文件。

我正在使用以下代码来写入/读取文件:

python
import tempfile
import io



class OpenRead(object):

    def _open_tempfile(self):
        self.tfile = tempfile.NamedTemporaryFile()
        # Write data on tempfile.
        self.ftp.retrbinary(
            'RETR %s' % self.filename, self.tfile.write)
        # Get back to start of file, so it would be possible to
        # read it.
        self.tfile.seek(0)
        return open(self.tfile.name, 'r')

    def __init__(self, ftp, filename):
        self.ftp = ftp
        self.filename = filename
        self.tfile = None

    def __enter__(self):
        return self._open_tempfile()

    def __exit__(self, exception_type, exception_value, traceback):
        # Remove temporary file.
        self.tfile.close()

class OpenWrite(object):
    def __init__(self, ftp, filename):
        self.ftp = ftp
        self.filename = filename
        self.data = ''

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        bio = io.BytesIO()
        if isinstance(self.data, six.string_types):
            self.data = self.data.encode()
        bio.write(self.data)
        bio.seek(0)
        res = self.ftp.storbinary('STOR %s' % self.filename, bio)
        bio.close()
        return res

    def write(self, data):
        self.data += data

def open(ftp, filename, mode='r'):
    """Open a file on FTP server."""
    if mode == 'r':
        return OpenRead(ftp, filename)
    if mode == 'w':
        return OpenWrite(ftp, filename)

但是

python
with open(ftplib.FTP('domain.com', 'username', 'password'), 'file.txt', 'w') as file:
    file.write('hello')

抛出

OpenWrite object has no atribute 'write'", 

尽管上下文管理器应该调用__enter__,它调用返回打开对象的_open_tempfile,但事实并非如此。

我该如何解决这个错误,或者有没有更好的方法来完成这一切? 谢谢!

【问题讨论】:

  • 您知道FTP 的意思是文件传输协议,对吧?它用于在服务器和客户端之间传输整个文件。
  • 我知道。我想保存一个临时文件并在本地编辑它,然后用我编辑的临时文件替换服务器上的文件。我不想使用 ftp 的原因是我需要写入的服务器只允许这种数据传输方法。无论如何感谢您的快速响应。
  • 所以先下载文件,然后打开临时副本,进行编辑,保存文件,然后上传。它们是单独的操作。你不能把它们当作一个单独的,因为 FTP 不能这样工作,文件 I/O 也不能。
  • 知道了!谢谢。我会试试的。
  • 使用您已经拥有的BytesIO 实例而不是添加另一个层不是更容易吗?

标签: python-3.x ftp ftplib


【解决方案1】:

我现在想通了。我正在使用 FTP 下载并重新上传文件,在本地将其编辑为临时文件,然后重新上传带有更改的文件。我的代码肯定不是最有效的,但它对我有用。

import tempfile
import io

class WriteModeFtp:
        def __init__(self, ftp, filename, mode="a"):
                self.ftp = ftp
                self.filename = filename
                self.mode = mode
                self.load()
        def load(self):

                self.tempfile = tempfile.NamedTemporaryFile()

                with open(self.tempfile.name, "wb+") as tmp:
                        self.ftp.retrbinary('RETR ' + self.filename, tmp.write)
        def getThis(self):
                return open(self.tempfile.name, self.mode)
        def flush(self):
                self.ftp.storbinary('STOR %s' % self.filename, open(self.tempfile.name, "rb"))
class MultiFtpStream:
        def __init__(self, ftp, mode="r"):
                self.ftp = ftp
                self.mode = mode
        def loadFile(self, filename):
                return WriteModeFtp(self.ftp, filename, self.mode)

【讨论】:

    猜你喜欢
    • 2014-11-29
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    相关资源
    最近更新 更多