0
app = Flask(__name__)
@app.route("/")
def hello():
    address="someserver"
    global FTP
    ftp = FTP(address)
    ftp.login()
    return ftp.retrlines("LIST")

if __name__ == "__main__":
    app.run()

...这给了我以下输出:

226-Options: -l 226 1 matches total

问题是 - 为什么这不打印 retrlines 的输出,我该怎么做?

4

1 回答 1

2

该类的文档ftplib.FTP说,它retrlines需要一个可选的回调 - 如果没有提供回调“默认回调将行打印到sys.stdout.” 这意味着该方法retrlines实际上并不返回所提供的数据——它只是将接收到的每一行传递给可能传递给它的可调用对象。这为您提供了几个选择:

  1. 传入一个可存储多次调用结果的可调用对象:

    def fetchlines(line=None):
        if line is not None:
            # As long as we are called with a line
            # store the line in the array we added to this function
            fetchlines.lines.append(line)
        else:
            # When we are called without a line
            # we are retrieving the lines
            # Truncate the array after copying it
            # so we can re-use this function
            lines = fetchlines.lines[:]
            fetchlines.lines = []
            return lines
    
    fetchlines.lines = []
    
    @app.route("/")
    def hello():
        ftp = FTP("someaddress")
        ftp.login()
        ftp.dir(fetchlines)
        lines = fetchlines()
        return "<br>".join(lines)
    
  2. 替换sys.stdout为类似文件的对象(cStringIO例如),然后简单地读取文件:

    from cStringIO import StringIO
    from sys import stdout
    
    # Save a reference to stdout
    STANDARD_OUT = stdout
    
    @app.route("/")
    def hello():
        ftp = FTP("someaddress")
        ftp.login()
    
        # Change stdout to point to a file-like object rather than a terminal
        file_like = StringIO()
        stdout = file_like
    
        ftp.dir()
    
        # lines in this case will be a string, not a list
        lines = file_like.getvalue()
    
        stdout = STANDARD_OUT
        file_like.close()
    
        return lines
    

在大量负载下,甚至在任何真正的并发下,这些技术都不能很好地支撑。有办法解决这个问题,但我将把它留到另一天。

于 2012-12-15T03:10:27.337 回答