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

上传大文件到Dropbox时UploadSessionFinishAsync报错如何解决?

问题原因分析
  • 分块上传逻辑重复提交首块数据:idx=0时,你已经通过UploadSessionStartAsync上传了第一块内容,但是后续未跳过该块的append逻辑,会重复上传第一块,导致会话累计的上传字节数和cursor声明的偏移量不匹配,最终Finish时校验失败。
  • 偏移量计算错误:当前cursor偏移量用chunkSize * idx硬编码计算,没有使用实际读取的字节数累加,若实际读取的字节数不等于chunkSize(比如最后一块,或者文件流读取时的异常情况),会导致偏移量和实际上传量不符。
  • 小文件上传逻辑存在隐式BUG:单块上传的分支中,你没有将文件流内容读取到buffer中,直接使用空的buffer构造流上传,会导致小文件上传后为空。
修复方案

首先调整分块逻辑、偏移量计算方式,修复后的完整代码如下:

using (var stream = new MemoryStream(File.ReadAllBytes(fileName)))
{
    var numChunks = (int)Math.Ceiling((double)stream.Length / chunkSize);
    var buffer = new byte[chunkSize];
    string sessionId = null;
    ulong uploadedBytes = 0; // 用变量累计实际上传的字节数作为偏移量

    if (numChunks == 1)
    {
        // 修复:先读文件内容到buffer
        var byteRead = stream.Read(buffer, 0, chunkSize);
        using (var memStream = new MemoryStream(buffer, 0, byteRead))
        {
            Console.WriteLine($"Sending file: {path}");
            var tst = await client.Files.UploadAsync(path, WriteMode.Overwrite.Instance, body: memStream);
        }
    }
    else
    {
        for (var idx = 0; idx < numChunks; idx++)
        {
            Console.WriteLine($"Uploading chunk {idx + 1} / {numChunks}.");
            var byteRead = stream.Read(buffer, 0, chunkSize);

            using (var memStream = new MemoryStream(buffer, 0, byteRead))
            {
                if (idx == 0)
                {
                    var result = await client.Files.UploadSessionStartAsync(body: memStream);
                    sessionId = result.SessionId;
                    uploadedBytes += (ulong)byteRead;
                    // 首块已经通过Start上传,跳过后续append逻辑
                    continue;
                }

                var cursor = new UploadSessionCursor(sessionId, uploadedBytes);

                if (idx == numChunks - 1)
                {
                    Console.WriteLine($"Finalizing file: {path}");
                    var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
                }
                else
                {
                    await client.Files.UploadSessionAppendV2Async(cursor, body: memStream);
                    uploadedBytes += (ulong)byteRead;
                }
            }
        }
    }

    var url = string.Empty;
    var link = await client.Sharing.ListSharedLinksAsync(path);

    if (link.Links.Count == 0)
    {
        var result = await client.Sharing.CreateSharedLinkWithSettingsAsync(path);
        url = result.Url;
    }
    else
    {
        url = link.Links[0].Url;
    }

    Console.WriteLine();
    Console.WriteLine("Dropbox Download Link:");
    Console.WriteLine(url);
    Console.WriteLine();
}
额外排查建议

如果修改后仍然报错,可以按以下步骤定位:

  • 打印每个块的byteRead、uploadedBytes数值,确认和实际文件大小匹配
  • 捕获UploadSessionFinishAsync抛出的异常详情,查看Dropbox返回的错误码,常见的invalid_cursor错误就对应偏移量不匹配的问题
  • 确认chunkSize取值符合Dropbox要求,分块上传的块大小最小为1MB,最大为150MB,推荐使用8MB作为默认分块大小

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:54:02