繁体   English   中英

上传到 Dropbox 时出错

[英]Getting an error when uploading to Dropbox

我正在尝试将文件上传到 Dropbox。

这是我到目前为止所说的:

    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;

      if (numChunks == 1)
      {
        using (var memStream = new MemoryStream(buffer, 0, chunkSize))
        {
          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;
            }

            var cursor = new UploadSessionCursor(sessionId, (ulong) (chunkSize * idx));

            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);
            }
          }
        }
      }

      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();
      //Console.ReadKey();
    }

当我尝试发送一个大文件时,我收到以下消息:

在此处输入图片说明

我正在考虑小文件和大文件。 如果文件大于块大小。 我无法让它发送文件,我只是收到一个错误。

它发生在这一行:

var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);

有什么建议?

对于第一个块idx==0你只需要调用UploadSessionStartAsync并且你还调用UploadSessionAppendV2Async 尝试这个:

...
using (var memStream = new MemoryStream(buffer, 0, byteRead))
{
    if (idx == 0)
    {
        var result = await client.Files.UploadSessionStartAsync(body: memStream);
          sessionId = result.SessionId;
    }
    else
    {
        var cursor = new UploadSessionCursor(sessionId, (ulong) (chunkSize * idx));

        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);
        }
    }
}
...

没有在本地运行它,也没有使用 Dropbox 的客户端,但我看到以下内容......

  1. 可能,虽然手动调试缓慢,但您可能会错过这个问题。
  2. 期望,错误消息有点误导。 一般来说,这是正确的。 但是当您的原始 Stream 被更改时,应该有一个额外的检查来捕捉情况。
  3. 让我添加更多关于“这里到底发生了什么?!.”的同步/异步混沌数据。 首先,您的for同步运行 - 所有上传会话在短时间内并行启动。 其次,每个for s 都有自己的block-level scope ,在同步上下文中具有using (...) {...}语法糖。 所有var memStream都在上层同步上下文中相互覆盖。 然后,每个线程在它自己的异步上下文中完成它的工作。 看看var response 它是一个循环变量,不在您的主 SYNC 上下文中使用。 它不是从using闭包中声明的。 所以这一行在同步上下文中是不可等待的。 在这种情况下, using将在memStream被消耗时完成,但UploadSessionFinishAsync将继续工作。
  4. 为什么它只发生在var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream); ? 想想,这可能是每个await client.Files...调用中的问题,但只有client.Files.UploadSessionFinishAsync尝试对传递的memStream做一些事情。 例如,将其作为最后一步关闭。 或者处理memStream ,放弃流,做其他的工作,比如请求 Dropbox 得到最终的上传结果。
  5. 关于修复的想法。 我认为您需要在for范围之上声明最终结果var response 然后只需在最后一个块处理时设置结果。 在这种情况下using将不得不等待它的结果,只有这样它才能处理memStream 就像sessionId = result.SessionId; . 或者只是在using结束之前明确等待其结果。
  6. 代码优化。 对于短文件,您不需要buffersessionId 它们用于多个上传线程。 对于大文件 - 从循环中返回UploadSessionFinishAsync结果。 也许,将多个memStream声明为不同的变量。 不确定UploadSessionAppendV2Async结果。 如果它是void那么就可以了。 否则,也应该等待这样的结果。 它可能是这样的:
//outer vars
SomeDropboxFileUploadResultOrElse uploadResult;
string sessionId = null;

//original full file read
using (var stream = new MemoryStream(File.ReadAllBytes(fileName)))
{
   var numChunks = (int) Math.Ceiling((double) stream.Length / chunkSize);
   if (numChunks == 1)
   {
       Console.WriteLine($"Sending file: {path}");
       uploadResult = await client.Files.UploadAsync(path, WriteMode.Overwrite.Instance, body: stream);
   }
   else
   {
       var buffer = new byte[chunkSize];
       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;
               }
               //prevent 2+ parts processing on idx == 0 iteration, start thread in the sync scope but wait for sessionId value in the async thread
               else
               {
                   var cursor = new UploadSessionCursor(sessionId, (ulong)(chunkSize * idx));
                   if (idx == numChunks - 1)
                   {
                       Console.WriteLine($"Finalizing file: {path}");
                       //explicitly pass result to outer scope, then the execution could be continued, memStream could be closed below
                       uploadResult = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
                   }
                   else
                   {
                       await client.Files.UploadSessionAppendV2Async(cursor, body: memStream);
                   }
               }
           } //memStream?.Dispose(); 
       }
   }
...
}

希望,这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM