我发现我的HTTPWebRequest上传在上传结束时失败了......如 this video @Screenr
所示我的代码如下所示
using (var reqStream = req.GetRequestStream())
{
BinaryWriter reqWriter = new BinaryWriter(reqStream);
byte[] buffer = new byte[25600]; // 20KB Buffer
int read = 0, bytesRead = 0;
while ((read = memStream.Read(buffer, 0, buffer.Length)) > 0) {
reqWriter.Write(buffer); // at the very last loop, this line causes the error
bytesRead += read;
Debug.WriteLine("Percent Done: " + ((double)bytesRead / memStream.Length * 100) + "% " + DateTime.Now);
}
我不知道您是否需要更多代码,我只是不想在此处使用垃圾邮件代码。
以下例外System.Net.WebException was caught
Message=The request was aborted: The request was canceled.
Source=System
StackTrace:
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)
at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeState)
at System.Net.ConnectStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at QuickImageUpload.ViewModels.ShellViewModel.UploadImage(String filename, String contentType, Byte[] image) in D:\Projects\QuickImageUpload\QuickImageUpload\ViewModels\ShellViewModel.cs:line 190
InnerException: System.IO.IOException
Message=Cannot close stream until all bytes are written.
Source=System
StackTrace:
at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)
InnerException:
注意内部异常“在写入所有字节之前无法关闭流”。但是我没有在这个循环中关闭任何流吗?
答案 0 :(得分:15)
好吧,你是通过将它放在using
语句中来关闭流 - 但你应该关闭它,所以这不太可能是问题。
开头几点:
BinaryWriter
。它不会给你买任何东西。直接写入流。如果memStream
是MemoryStream
,您可以使用WriteTo
:
using (var reqStream = req.GetRequestStream())
{
memStream.WriteTo(reqStream);
}
这意味着您无法获得诊断,但它确实使代码更简单:)
现在,至于发生了什么...我的猜测是你在Write
的调用中得到一个异常,但是异常被异常有效地取代了通过关闭流来抛出。
我知道为什么会抛出异常......
您是否在任何地方设置内容长度?因为你可能会重复它。看看这一行:
reqWriter.Write(buffer);
这是在循环的每次迭代中写出整个缓冲区,而忽略了你刚读取的数据量。您已经将已读入的字节数分配给变量read
,但之后您永远不会使用该值。您可以通过将其更改为
reqWriter.Write(buffer, 0, read);
......但我个人不会。我要么只是使用MemoryStream.WriteTo
或直接写入请求流......正如我之前所说,BinaryWriter
实际上并不是给你买任何东西。
无论如何,在每个请求的当前代码中,无论内容长度如何,都要尝试写入25600字节的倍数。如果请求流注意到并抛出异常,我不会感到惊讶。让我们假装我们有30000字节的数据。我怀疑序列是这样的:
IOException
finally
语句的隐式using
块然后处理关闭它的流这种事情让图书馆从Dispose
抛出异常是一个坏主意......但假设我是对的,它确实给出了你同时试图写的有趣问题很多和太少的数据:)
答案 1 :(得分:4)
你不能写“缓冲区”,因为到最后“缓冲区”不包含20k的数据。
因此,当您执行memStream.Read时,它返回实际读取的字节数。你需要在写作时使用这些知识/信息。
reqWriter.Write(buffer, 0, read);