当前位置: 首页 > 知识库问答 >
问题:

Paramiko无法下载大于1GB的大文件

家西岭
2023-03-14
def download():
if os.path.exists( dst_dir_path ) == False:
    logger.error( "Cannot access destination folder %s. Please check path and permissions. " % ( dst_dir_path ))
    return 1
elif os.path.isdir( dst_dir_path ) == False:
    logger.error( "%s is not a folder. Please check path. " % ( dst_dir_path ))
    return 1

file_list = None
#transport = paramiko.Transport(( hostname, port)) 
paramiko.util.log_to_file('paramiko.log')
ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
#transport
try:
    ssh.connect( hostname, username=username, password=password, timeout=5.0) 
    #transport.connect(username=username, password=password ) 
except Exception, err:
    logger.error( "Failed to connect to the remote server. Reason: %s" % ( str(err) ) )
    return 1

try:
    #sftp = paramiko.SFTPClient.from_transport(transport)
    sftp = ssh.open_sftp() 
except Exception, err:
    logger.error( "Failed to start SFTP session from connection to %s. Check that SFTP service is running and available. Reason: %s" % ( hostname, str(err) ))
    return 1

try:    
    sftp.chdir(src_dir_path)
    #file_list = sftp.listdir(path="%s" % ( src_dir_path ) )
    file_list = sftp.listdir()

except Exception, err:
    logger.error( "Failed to list files in folder %s. Please check path and permissions. Reason: %s" % ( src_dir_path, str(err) ))
    return 1
match_text = re.compile( file_mask )
download_count = 0
for file in file_list:         
    # Here is an item name... but is it a file or directory?         
    #logger.info( "Downloading file %s." % ( file ) )
    if not re.match( file_mask, file ):
        continue
    else:
        logger.info( "File \"%s\" name matched file mask \"%s\". matches %s.Processing file..." % ( file, file_mask, (match_text.match( file_mask ) ) ) )
    src_file_path = "./%s" % ( file )
    dst_file_path = "/".join( [ dst_dir_path, file]   )
    retry_count = 0
    while True:
        try:
            logger.info( "Downloading file %s to %s."  % ( file, dst_file_path ) )
            #sftp.get( file, dst_file_path, callback=printTotals ) #sftp.get( remote file, local file )
            sftp.get( file, dst_file_path) #sftp.get( remote file, local file )
            logger.info( "Successfully downloaded file %s to %s."  % ( file, dst_file_path ) )
            download_count += 1
            break
        except Exception, err:
            if retry_count == retry_threshold:
                logger.error( "Failed to download %s to %s. Reason: %s." % ( file, dst_file_path, str(err) ) )
                sftp.close() 
                #transport.close()
                return 1
            else:
                logger.error( "Failed to download %s to %s. Reason: %s." % ( file, dst_file_path, str(err) ) )
                retry_count +=1

sftp.close() 
transport.close() 
logger.info( "%d files downloaded." % ( download_count ) )
return 0

当我运行下面的函数时,它下载源文件大约3分钟,然后关闭会话,即使一个1-1.6GB的文件只下载了38-41MB(变化)。

从Paramiko日志文件中可以看出,SSh连接在SFTP会话关闭时保持打开状态:

DEB[20120913-10:05:00.894]Thr=1帕拉米科。运输:切换到新键...DEB[20120913-10:05:06.953]Thr=1 Paramiko。传输:重新密钥(命中401个数据包,1053444字节接收)DEB[20120913-10:05:07.391]Thr=1 Paramiko。传输:kex Algos:['Diffie-Hellman-Group1-SHA1','diffie-hellman-group-exchange-sha1']服务器密钥:['ssh-dss']客户端加密程序:['aes256-ctr','aes192-ctr'、'aes128-ctr'、'aes256-cbc'、'aes192-cbc'、'aes128-cbc'、'blowfish-cbc'、'3des-cbc'、'arcfour']服务器加密:['aes256-ctr'、'aes192-ctr'、'aes128-cbc'、'aes192-cbc'、'aes128-cbc'、'twofish-cbc'、'blowfish-cbc'、'3des-cbc'、'arcfour']客户端服务器密钥类型SSH-DSS;密码:本地aes128-ctr、远程aes128-ctr;MAC:本地hmac-sha1,远程hmac-sha1;压缩:本地无,远程无DEB[20120913-10:05:07.625]thr=1 Paramiko.Transport:切换到新密钥...INF[20120913-10:05:10.374]thr=2 Paramiko.Transport.sftp:[chan 1]sftp会话已关闭。DEB[20120913-10:05:10.388]Thr=2 Paramiko。运输:[chan 1]EOF发送(1)

在这一点之后,脚本以这个异常退出(从sftp.get()try/except块退出)

资源不足,无法完成请求

系统本身有GB的空闲磁盘空间,所以这不是问题。

想法?

附加信息:它在Windows XP SP3和Windows 2003 server上失败,完全相同的行为和错误消息。Sys.Version information Windows XP Workstation:“2.7.3(默认值,2012年4月10日,23:31:26)[MSC V.1500 32位(Intel)]”Windows 2003 Server:“2.7.3(默认值,2012年4月10日,23:31:26)[MSC V.1500 32位(Intel)]”我修补了packet.py文件以缩短密钥续订之间的时间。它对sftp.get()的行为没有影响。

共有1个答案

白昊乾
2023-03-14

我有一个非常相似的问题,在我的情况下,文件只有大约400 MB,但它会在下载大约35 MB后持续失败。它并不总是在下载完全相同的字节数时失败,但在大约35-40 MB的地方,文件将停止传输,大约一分钟后,我会得到“没有足够的资源来完成请求”的错误。

通过WinSCP或PSFTP下载文件工作良好。

我试过螺丝钉的方法,它确实奏效,但慢得令人痛苦。我的400 MB文件的速度大约需要4个小时下载,这是一个无法接受的时间框架,这个特殊的应用程序。

而且,有一段时间,当我们第一次设置时,一切都很好。但服务器管理员对SFTP服务器做了一些更改,这时就坏了。我不确定这些变化是什么,但由于使用WinSCP/其他SFTP方法仍然可以正常工作,所以我认为尝试从服务器端攻击它不会有效果。

我不想假装理解为什么,但我最终得到的结果是:

>

  • 我下载并安装了当前版本的Paramiko(此时为1.11.1)。最初,这没有任何区别,但我想我应该提到它,以防它是解决方案的一部分。

    File "C:\Python26\lib\site-packages\paramiko\sftp_client.py", line 676, in get
        size = self.getfo(remotepath, fl, callback)
    File "C:\Python26\lib\site-packages\paramiko\sftp_client.py", line 645, in getfo
        data = fr.read(32768)
    File "C:\Python26\lib\site-packages\paramiko\file.py", line 153, in read
        new_data = self._read(read_size)
    File "C:\Python26\lib\site-packages\paramiko\sftp_file.py", line 157, in _read
        data = self._read_prefetch(size)
    File "C:\Python26\lib\site-packages\paramiko\sftp_file.py", line 138, in _read_prefetch
        self._check_exception()
    File "C:\Python26\lib\site-packages\paramiko\sftp_file.py", line 483, in _check_exception
        raise x
    
    # Some sftp servers will choke if you send read/write requests larger than
    # this size.
    MAX_REQUEST_SIZE = 32768
    

    一时兴起,我试着将MAX_REQUEST_SIZE更改为1024,看哪,我可以下载整个文件!

    在我将MAX_REQUEST_SIZE更改为1024之后,我尝试了一组介于1024和32768之间的其他值,看看它是否会影响性能或其他什么。但当值明显大于1024(1025是可以的,但1048最终失败)时,我迟早会得到错误。

  •  类似资料:
    • 我正在尝试使用spring boot上载大于1Mb的文件

    • 我有一个文件表示为块的列表,目标是下载所有块,加入并保存为一个文件。 它应该适用于大文件 应该是跨浏览器解决方案 null null null null 但我仍然无法实现我的目标与涵盖的需求… 如果有人有经验,最好的解决方案,我恳请分享它在这里。谢谢

    • 我正在下载一个歌曲文件。下面的代码(好吧,原始代码,这只是我正在做的一个示例)在Asha 310设备上运行良好。然而,在较新的Asha 501设备上,下载的文件比实际文件大得多。如果我使用512缓冲区,一个2.455.870字节的文件最终会下载2.505.215字节,而且它也不会加载。使用4096缓冲区,文件大小最终为3.342.335字节!! 发生这种情况的原因是什么?它在另一部手机上运行良好,

    • 我正在尝试用PHP上传一个文件!我试过上传PNG、JPG、PDF、TXT文件,这些上传只在文件大小为20kb左右时有效。当我尝试上载大小约为150KB的文件时,它会打印,文件名为“1234.png”,其中tmp\u名称为空,图像本身也是空的!这是我的密码 我尝试了多种解决方案,例如更改和的值,而不是32M 以下是尝试上载4KB txt文件的结果: 上传PNG文件127KB的结果: 警告:file_

    • 问题内容: 有没有一种方法可以获取远程文件http://my_url/my_file.txt的大小而无需下载文件? 问题答案: 在这里找到有关此的一些信息: 这是(我发现)获取远程文件大小的最佳方法。请注意,HEAD请求不会获取请求的实际主体,它们只是检索标头。因此,对100MB的资源进行HEAD请求所花费的时间与对1KB的资源进行HEAD请求所花费的时间相同。 用法:

    • 我正在尝试通过OKHTTP3下载zip文件(大小为160 Mb)。几秒钟后,应用程序与堆栈崩溃: IllegalStateException:在scheduler.worker线程上引发的致命异常。在java.util.concurrent.executors$runnableadapter.call(executors.java:59)在java.util.concurrent.futureta