如何使用Python在SFTP服务器上检查文件是否包含字符串?

时间:2018-07-05 17:23:36

标签: python python-3.x sftp pysftp

我能够连接到服务器并查看给定目录中的所有文件,但是,当我尝试打开文件时,似乎总是遇到问题。

方案是:我想根据日期从SFTP服务器获取最新文件,然后我要检查该文件中是否包含特定字符串。如果是,则返回true,否则返回false。这是我下面的解决方案:

def does_file_exists_on_sftp_server_and_contains_given_value(value):
    latest_date = 0
    latest_file = None
    retry_attempt = 0
    value_is_present= False

    while retry_attempt < 50:
        # the line below does the sftp server login and that works successfully 
        conn = vm_sftp_login()
        files = conn.listdir_attr("directory")
        for file in files:
            if file.filename.endswith(".xml") and file.st_mtime > latest_date:
                latest_date = file.st_mtime
                latest_file = file.filename
                retry_attempt = 50
        retry_attempt += 1
    latest_file_obj = conn.get(latest_file)
    file_obj = open(latest_file_obj)
    for line in file_obj:
        if value in line:
            value_is_present = True
            break
    return value_is_present

代码似乎在此时中断:latest_file_obj = conn.get(latest_file)

跟踪

self = <paramiko.sftp_client.SFTPClient object at 0x000001EF8E156748>
msg = paramiko.Message(b'\x00\x00\x00\x05\x00\x00\x00\x02\x00\x00\x00\x0cNo such file\x00\x00\x00\x00')

    def _convert_status(self, msg):
        """
            Raises EOFError or IOError on error status; otherwise does nothing.
            """
        code = msg.get_int()
        text = msg.get_text()
        if code == SFTP_OK:
            return
        elif code == SFTP_EOF:
            raise EOFError(text)
        elif code == SFTP_NO_SUCH_FILE:
            # clever idea from john a. meinel: map the error codes to errno
>           raise IOError(errno.ENOENT, text)
E           FileNotFoundError: [Errno 2] No such file

2 个答案:

答案 0 :(得分:0)

我认为您的问题可能是特定的代码行试图访问文件latest.xml而不是directory/latest.xml。我个人并不熟悉该库,但是如果conn.listdir_attr()的工作方式与python的os.listdir()类似,则它会从返回的每个文件名中忽略该文件夹的名称。因此,如果要从该列表中打开文件,则必须重新添加目录名称。

所以,尝试

latest_file_obj = conn.get('directory/' + latest_file)

相反,看看它是否有效。

答案 1 :(得分:0)

  1. 您需要在Connection.get中指定文件的路径,@ a625993已经回答了该问题。

  2. Connection.get不返回任何内容。它将远程文件下载到localpath参数指定的本地路径。如果不指定参数,它将把文件下载到当前工作目录。

    如果您确实想将文件读取为变量(据我了解实际上不希望如此),则需要使用.getfo,例如:

    flo = BytesIO()
    sftp.getfo(remotepath, flo)
    

    或者,直接使用Paramiko库(不使用pysftp包装器)。
    参见Read a file from server with ssh using python