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

使用Office365 REST API上传大文件:如何直传内存数据避免临时文件?

解决Office365 REST API内存直传大文件的问题

你可以通过手动构建上传会话+内存流适配的方式,绕过临时文件直接上传内存中的内容,同时解决多线程下的磁盘IO同步问题。

核心问题分析

你之前尝试直接传入BytesIO失败,是因为create_upload_session默认的参数处理逻辑更偏向真实文件路径/句柄,会尝试调用真实文件特有的方法(比如fileno())。但通过拆分上传流程,先创建会话再处理内存流,就能避开这个限制。

优化方案代码示例

方案1:直接上传内存中的完整文件内容

import io
from zipfile import ZipFile
from office365.sharepoint.files.file import File

# ... 保留原有的下载和解压逻辑 ...

for z_file in zip_file.filelist:
    logger.warning(f"Extracting: {folder.name}_{ab_zip_file.name}_{z_file.filename}, Size: {z_file.file_size}")
    content = zip_file.read(z_file)
    upload_fname = z_file.filename

    if "/" in upload_fname:
        upload_fname = f'{folder.name}_{upload_fname.partition("/")[2]}'

    # 用内存流包装文件内容,无需写入临时文件
    content_stream = io.BytesIO(content)
    content_stream.seek(0)  # 重置流指针到起始位置

    # 创建上传会话(明确指定文件名)
    upload_session = ab_folder.files.create_upload_session(
        file_name=upload_fname,
        chunk_size=3072000
    ).execute_query()

    # 基于内存流执行分块上传
    uploader = File(content_stream)
    upload_session.upload(
        uploader,
        chunk_uploaded=print_upload_progress
    ).execute_query_retry()

方案2:流式读取Zip文件(更省内存)

如果解压后的单个文件达数百MB,推荐直接从Zip中流式读取,避免一次性加载整个文件到内存:

from zipfile import ZipFile
from office365.sharepoint.files.file import File

# ... 保留原有的下载和解压逻辑 ...

for z_file in zip_file.filelist:
    logger.warning(f"Extracting: {folder.name}_{ab_zip_file.name}_{z_file.filename}, Size: {z_file.file_size}")
    upload_fname = z_file.filename

    if "/" in upload_fname:
        upload_fname = f'{folder.name}_{upload_fname.partition("/")[2]}'

    # 直接从Zip中获取文件流,分块读取上传
    with zip_file.open(z_file) as z_stream:
        # 创建上传会话
        upload_session = ab_folder.files.create_upload_session(
            file_name=upload_fname,
            chunk_size=3072000
        ).execute_query()

        # 基于Zip流执行分块上传
        uploader = File(z_stream)
        upload_session.upload(
            uploader,
            chunk_uploaded=print_upload_progress
        ).execute_query_retry()

多线程问题解决

使用内存流后,所有操作都在内存中完成,没有磁盘IO的缓存同步延迟,因此可以完全删除flush()和time.sleep(2)代码,彻底解决多线程下的文件读取失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 19:10:34