簡體   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