Python pysftp.put 尽管文件已上传但引发 "No such file" 异常
Python pysftp.put raises "No such file" exception although file is uploaded
我正在使用 pysftp 连接到服务器并向其上传文件。
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
self.sftp = pysftp.Connection(host=self.serverConnectionAuth['host'], port=self.serverConnectionAuth['port'],
username=self.serverConnectionAuth['username'], password=self.serverConnectionAuth['password'],
cnopts=cnopts)
self.sftp.put(localpath=self.filepath+filename, remotepath=filename)
有时它没有错误,但有时它正确地放置了文件,但引发了以下异常。该文件由服务器上的另一个程序 运行 读取和处理,因此我可以看到该文件在那里并且没有损坏
File "E:\Anaconda\envs\py35\lib\site-packages\pysftp\__init__.py", line 364, in put
confirm=confirm)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 727, in put
return self.putfo(fl, remotepath, file_size, callback, confirm)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 689, in putfo
s = self.stat(remotepath)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 460, in stat
t, msg = self._request(CMD_STAT, path)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 780, in _request
return self._read_response(num)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 832, in _read_response
self._convert_status(msg)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 861, in _convert_status
raise IOError(errno.ENOENT, text)
FileNotFoundError: [Errno 2] No such file
如何防止异常?
从所描述的行为来看,我假设文件在被某些 server-side 进程上传后不久就被删除了。
默认情况下 pysftp.Connection.put
通过检查目标文件的大小来验证上传。如果 server-side 进程设法过快地删除文件,读取文件大小将失败。
您可以通过将 confirm
参数设置为 False
:
来禁用 post-upload 检查
self.sftp.put(localpath=self.filepath+filename, remotepath=filename, confirm=False)
我认为无论如何检查都是多余的,请参阅
How to perform checksums during a SFTP file transfer for data integrity?
有关 Paramiko(pysftp 内部使用)的类似问题,请参阅:
在 paramiko 可以对上传的文件执行 os.stat
并比较本地和上传的文件大小之前,文件也会自动移动。
@Martin_Prikryl 解决方案在使用 sftp.put
或 sftp.putfo
时传入 confirm=False
可以很好地消除错误
如果您希望此检查仍然 运行 验证文件是否已完全上传,您可以 运行 按照这些行进行操作。为此,您需要知道移动的文件位置并能够读取该文件。
import os
sftp.putfo(source_file_object, destination_file, confirm=False)
upload_size = sftp.stat(moved_path).st_size
local_size = os.stat(source_file_object).st_size
if upload_size != local_size:
raise IOError(
"size mismatch in put! {} != {}".format(upload_size, local_size)
)
两次检查都使用 os.stat
我正在使用 pysftp 连接到服务器并向其上传文件。
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
self.sftp = pysftp.Connection(host=self.serverConnectionAuth['host'], port=self.serverConnectionAuth['port'],
username=self.serverConnectionAuth['username'], password=self.serverConnectionAuth['password'],
cnopts=cnopts)
self.sftp.put(localpath=self.filepath+filename, remotepath=filename)
有时它没有错误,但有时它正确地放置了文件,但引发了以下异常。该文件由服务器上的另一个程序 运行 读取和处理,因此我可以看到该文件在那里并且没有损坏
File "E:\Anaconda\envs\py35\lib\site-packages\pysftp\__init__.py", line 364, in put
confirm=confirm)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 727, in put
return self.putfo(fl, remotepath, file_size, callback, confirm)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 689, in putfo
s = self.stat(remotepath)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 460, in stat
t, msg = self._request(CMD_STAT, path)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 780, in _request
return self._read_response(num)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 832, in _read_response
self._convert_status(msg)
File "E:\Anaconda\envs\py35\lib\site-packages\paramiko\sftp_client.py", line 861, in _convert_status
raise IOError(errno.ENOENT, text)
FileNotFoundError: [Errno 2] No such file
如何防止异常?
从所描述的行为来看,我假设文件在被某些 server-side 进程上传后不久就被删除了。
默认情况下 pysftp.Connection.put
通过检查目标文件的大小来验证上传。如果 server-side 进程设法过快地删除文件,读取文件大小将失败。
您可以通过将 confirm
参数设置为 False
:
self.sftp.put(localpath=self.filepath+filename, remotepath=filename, confirm=False)
我认为无论如何检查都是多余的,请参阅
How to perform checksums during a SFTP file transfer for data integrity?
有关 Paramiko(pysftp 内部使用)的类似问题,请参阅:
在 paramiko 可以对上传的文件执行 os.stat
并比较本地和上传的文件大小之前,文件也会自动移动。
@Martin_Prikryl 解决方案在使用 sftp.put
或 sftp.putfo
confirm=False
可以很好地消除错误
如果您希望此检查仍然 运行 验证文件是否已完全上传,您可以 运行 按照这些行进行操作。为此,您需要知道移动的文件位置并能够读取该文件。
import os
sftp.putfo(source_file_object, destination_file, confirm=False)
upload_size = sftp.stat(moved_path).st_size
local_size = os.stat(source_file_object).st_size
if upload_size != local_size:
raise IOError(
"size mismatch in put! {} != {}".format(upload_size, local_size)
)
两次检查都使用 os.stat