[英]Getting an error when uploading to Dropbox
I am attempting to upload a file to dropbox.我正在尝试将文件上传到 Dropbox。
Here is what I have said so far:这是我到目前为止所说的:
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();
}
When I try to send up a large file, I'm getting this message:当我尝试发送一个大文件时,我收到以下消息:
I'm accounting for small and large files.我正在考虑小文件和大文件。 If the file is bigger than the chunksize.
如果文件大于块大小。 I cannot get it to send up the file, I just get an error.
我无法让它发送文件,我只是收到一个错误。
It's happening at this line:它发生在这一行:
var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
Any suggestions?有什么建议?
For the first chunk idx==0
you have to call only UploadSessionStartAsync
and you also call UploadSessionAppendV2Async
.对于第一个块
idx==0
你只需要调用UploadSessionStartAsync
并且你还调用UploadSessionAppendV2Async
。 Try this:尝试这个:
...
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);
}
}
}
...
Didn't run it locally and didn't use Dropbox's client but I see the following...没有在本地运行它,也没有使用 Dropbox 的客户端,但我看到以下内容......
for
runs synchronously - all upload sessions start in parallel in a short period of time.for
同步运行 - 所有上传会话在短时间内并行启动。 At second, each of for
s has its own block-level scope
that has the using (...) {...}
syntax sugar in the sync context.for
s 都有自己的block-level scope
,在同步上下文中具有using (...) {...}
语法糖。 All var memStream
s are covering each other in the upper sync context.var memStream
都在上层同步上下文中相互覆盖。 Then, every thread does its work in its own async context.var response
.var response
。 It is a loop variable and it is not in use in your main SYNC context.using
closure.using
闭包中声明的。 So this line can be not awaitable in the sync context.using
will finish when the memStream
will be consumed but UploadSessionFinishAsync
will be working still.using
将在memStream
被消耗时完成,但UploadSessionFinishAsync
将继续工作。var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
var response = await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(path), memStream);
? await client.Files...
call but only client.Files.UploadSessionFinishAsync
tries to do something with the passed memStream
.await client.Files...
调用中的问题,但只有client.Files.UploadSessionFinishAsync
尝试对传递的memStream
做一些事情。 For example, close it as a final step.memStream
, abandoned the stream, do another work such as a request to Dropbox to get a final upload result.memStream
,放弃流,做其他的工作,比如请求 Dropbox 得到最终的上传结果。var response
above the for
scope.for
范围之上声明最终结果var response
。 Then just set the result at the last chunk processing.using
will have to wait for its result, only then it could dispose memStream
.using
将不得不等待它的结果,只有这样它才能处理memStream
。 Just like with sessionId = result.SessionId;
sessionId = result.SessionId;
. using
end.using
结束之前明确等待其结果。buffer
and sessionId
.buffer
和sessionId
。 They are for multiple uploading threads.UploadSessionFinishAsync
result from your loop.UploadSessionFinishAsync
结果。 Maybe, declare multiple memStream
s as different vars.memStream
声明为不同的变量。 Not sure about UploadSessionAppendV2Async
result.UploadSessionAppendV2Async
结果。 If it is void
then it is OK.void
那么就可以了。 Otherwise, such a result also should be awaited.//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();
}
}
...
}
Hope, this will help.希望,这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.