[英]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 的客戶端,但我看到以下內容......
for
同步運行 - 所有上傳會話在短時間內並行啟動。 其次,每個for
s 都有自己的block-level scope
,在同步上下文中具有using (...) {...}
語法糖。 所有var memStream
都在上層同步上下文中相互覆蓋。 然后,每個線程在它自己的異步上下文中完成它的工作。 看看var response
。 它是一個循環變量,不在您的主 SYNC 上下文中使用。 它不是從using
閉包中聲明的。 所以這一行在同步上下文中是不可等待的。 在這種情況下, using
將在memStream
被消耗時完成,但UploadSessionFinishAsync
將繼續工作。var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
? 想想,這可能是每個await client.Files...
調用中的問題,但只有client.Files.UploadSessionFinishAsync
嘗試對傳遞的memStream
做一些事情。 例如,將其作為最后一步關閉。 或者處理memStream
,放棄流,做其他的工作,比如請求 Dropbox 得到最終的上傳結果。for
范圍之上聲明最終結果var response
。 然后只需在最后一個塊處理時設置結果。 在這種情況下using
將不得不等待它的結果,只有這樣它才能處理memStream
。 就像sessionId = result.SessionId;
. 或者只是在using
結束之前明確等待其結果。buffer
和sessionId
。 它們用於多個上傳線程。 對於大文件 - 從循環中返回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.