You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用pyCurl复用连接串行上传多文件至WebDAV服务器

问题描述

目前使用pyCurl将base64字符串格式的单个文件上传至WebDAV服务器,现有代码如下:

def fileupload(url, filename, filedata, upload_user, upload_pw):
    filedata = base64.b64decode(filedata).decode('ascii', 'ignore')

    # Initialize pycurl
    c = pycurl.Curl()
    url = url + filename
    c.setopt(pycurl.URL, url)
    c.setopt(pycurl.UPLOAD, 1)
    c.setopt(pycurl.READFUNCTION, StringIO(filedata).read)
    c.setopt(pycurl.CONNECTTIMEOUT, 5)
    c.setopt(pycurl.TIMEOUT, 20)
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.SSL_VERIFYHOST, 2)
    c.setopt(pycurl.CAINFO, "ca.pem")
    c.setopt(pycurl.USERPWD, upload_user + ":" + upload_pw)

    # Set size of file to be uploaded.
    filesize = len(filedata)
    c.setopt(pycurl.INFILESIZE, filesize)

    # Start transfer
    logPes.debug('Uploading file %s to url %s' % (filename, url))
    try:
        c.perform()

        # Check result of transfer
        if c.getinfo(pycurl.HTTP_CODE) == 201:
            c.close()
            logPes.info('Fileupload successful')
            return True
        else:
            logPes.error('Fileupload NOT successful. Error code {0}.'.format(c.getinfo(pycurl.HTTP_CODE)))
            c.close()
            return False
    
    except pycurl.error as error:
        logPes.error('Fileupload: {0}'.format(error.args[1]))
        return False

多次调用该函数上传多文件时,会反复建立并关闭连接。想了解:

  • 是否可通过pyCurl复用同一连接串行上传多文件?
  • pycurl.CurlMulti是否适用?它是否复用连接,是串行还是异步执行?服务器性能较弱,希望以此减少负载。
解答

一、复用单个Curl连接串行上传多文件

完全可以复用同一个pycurl.Curl实例来串行上传多个文件,这是减少连接建立开销、降低弱服务器负载的最优方案。

修改思路

  • 仅初始化一次Curl实例,设置通用选项(超时、SSL验证、用户密码等),避免重复创建销毁连接。
  • 每次上传单个文件时,仅更新需要变更的选项:目标URL、文件读取函数、文件大小。
  • 所有文件上传完成后,再统一关闭Curl实例。

示例代码

import pycurl
from io import StringIO
import base64
import logging

logPes = logging.getLogger(__name__)

def init_curl_handle(base_url, upload_user, upload_pw):
    # 初始化一次Curl实例,配置通用参数
    curl = pycurl.Curl()
    curl.setopt(pycurl.CONNECTTIMEOUT, 5)
    curl.setopt(pycurl.TIMEOUT, 20)
    curl.setopt(pycurl.SSL_VERIFYPEER, 1)
    curl.setopt(pycurl.SSL_VERIFYHOST, 2)
    curl.setopt(pycurl.CAINFO, "ca.pem")
    curl.setopt(pycurl.USERPWD, f"{upload_user}:{upload_pw}")
    curl.setopt(pycurl.UPLOAD, 1)  # 固定开启上传模式
    return curl

def upload_single_file(curl_handle, base_url, filename, filedata):
    # 解码base64文件数据
    filedata = base64.b64decode(filedata).decode('ascii', 'ignore')
    target_url = base_url + filename

    # 更新本次上传的专属参数
    curl_handle.setopt(pycurl.URL, target_url)
    curl_handle.setopt(pycurl.READFUNCTION, StringIO(filedata).read)
    curl_handle.setopt(pycurl.INFILESIZE, len(filedata))

    logPes.debug('Uploading file %s to url %s' % (filename, target_url))
    try:
        curl_handle.perform()
        http_code = curl_handle.getinfo(pycurl.HTTP_CODE)
        if http_code == 201:
            logPes.info('Fileupload successful: %s' % filename)
            return True
        else:
            logPes.error('Fileupload failed for %s. Error code: %d' % (filename, http_code))
            return False
    except pycurl.error as error:
        logPes.error('Fileupload error for %s: %s' % (filename, error.args[1]))
        return False

# 使用示例
if __name__ == "__main__":
    base_webdav_url = "https://your-webdav-server.com/"
    user = "your-username"
    password = "your-password"

    # 初始化一次连接
    curl = init_curl_handle(base_webdav_url, user, password)

    # 待上传文件列表(文件名+base64数据)
    upload_tasks = [
        ("doc1.txt", "base64-encoded-data-1"),
        ("image1.jpg", "base64-encoded-data-2"),
        # 更多文件...
    ]

    # 串行上传所有文件
    for filename, filedata in upload_tasks:
        upload_single_file(curl, base_webdav_url, filename, filedata)

    # 所有上传完成后关闭连接
    curl.close()

关键说明

  • pycurl默认支持HTTP/1.1的持久连接(Keep-Alive),同一个Curl实例多次调用perform()时,会自动复用已建立的连接,无需额外配置。
  • 若某次上传出现连接中断等严重错误,可考虑重新初始化Curl实例,但大部分场景下无需额外处理。

二、关于pycurl.CurlMulti的适用场景

CurlMulti并不适合你的弱服务器场景,具体说明如下:

  • 执行方式:CurlMulti是异步并发执行多个请求,会同时发起多个上传任务,反而会增加服务器的负载,与你降低服务器压力的需求相悖。
  • 连接复用:CurlMulti内部维护连接池,支持连接复用,但前提是并发执行,对性能较弱的服务器不友好。
  • 适用场景:仅当服务器性能充足、需要提升上传效率时,CurlMulti才是合适的选择;你的场景更适合用单个Curl实例串行上传。

内容的提问来源于stack exchange,提问作者nico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:27:47