C# 使用HttpWebRequest显示文件上载进度
我正在试图弄清楚如何执行多部分/表单数据put请求,并能够获得文件的上传进度。我遇到的问题是直到request.GetResponse()才发送请求;在发送前使我的写作进度达到100%。我尝试过谷歌搜索,发现有人使用request.SendChunked=true解决了这个问题;和request.AllowWriteStreamBuffering=false;但这似乎没有任何区别。我已经看到一些人发表了关于这一点的帖子,但还没有找到一个我能找到的解决方案。这是我的尝试。你知道我能做些什么来解决这个问题吗C# 使用HttpWebRequest显示文件上载进度,c#,.net,C#,.net,我正在试图弄清楚如何执行多部分/表单数据put请求,并能够获得文件的上传进度。我遇到的问题是直到request.GetResponse()才发送请求;在发送前使我的写作进度达到100%。我尝试过谷歌搜索,发现有人使用request.SendChunked=true解决了这个问题;和request.AllowWriteStreamBuffering=false;但这似乎没有任何区别。我已经看到一些人发表了关于这一点的帖子,但还没有找到一个我能找到的解决方案。这是我的尝试。你知道我能做些什么来解决这
class Program
{
private static float _progressBar;
static async Task Main(string[] args)
{
Console.WriteLine("hello");
// https://postman-echo.com/put
var response = ExecutePutCommand("C:/temp/zipfile.zip",
"https://postman-echo.com/put", "weef");
}
protected static string ExecutePutCommand(string filename, string uriStr, string stringToAdd)
{
try
{
const string authCookie = "";
byte[] fileBytes = File.ReadAllBytes(filename);
//
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uriStr);
request.SendChunked = true;
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = false;
request.KeepAlive = true;
request.ProtocolVersion = HttpVersion.Version11;
string boundary = System.Guid.NewGuid().ToString();
//
request.ContentType = string.Format("multipart/form-data;boundary={0}", boundary);
request.Method = "PUT";
//request.Headers["Cookie"] = authCookie;
// Build Contents for Post
string header = string.Format("--{0}", boundary);
string footer = header + "--";
// string builders are for the text above and below the file - file is kept in its original format.
StringBuilder contents = new StringBuilder();
StringBuilder contents2 = new StringBuilder();
// Zip File
contents.AppendLine(header);
contents.AppendLine(
string.Format("Content-Disposition:form-data; name=\"filefield\"; filename=\"{0}\"",
filename));
contents.AppendLine("Content-Type: application/x-zip-compressed");
contents.AppendLine();
// file goes here... then contents 2
contents2.AppendLine();
// Form Field 1
contents2.AppendLine(header);
contents2.AppendLine("Content-Disposition:form-data; name=\"stringToAdd\"");
contents2.AppendLine();
contents2.AppendLine(stringToAdd);
// Form Field 2
// Footer
contents2.AppendLine(footer);
// This is sent to the Put
byte[] bytes = Encoding.UTF8.GetBytes(contents.ToString());
byte[] bytes2 = Encoding.UTF8.GetBytes(contents2.ToString());
byte[] formData = bytes.Concat(fileBytes).Concat(bytes2).ToArray();
// calculate size of the stream
request.ContentLength = bytes.Length + fileBytes.Length + bytes2.Length;
byte[] buffer = new byte[4096];
int count = 0;
int length = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
//request.Proxy = null;
using (Stream requestStream = request.GetRequestStream())
{
using (Stream inputStream = new MemoryStream(formData))
{
while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, count);
length += count;
_progressBar = (float)length / request.ContentLength;
//Console.WriteLine(_progressBar);
}
}
}
sw.Stop();
WebResponse resp = request.GetResponse();
Stopwatch sw2 = new Stopwatch();
sw.Start();
using (Stream stream = resp.GetResponseStream())
{
StreamReader respReader = new StreamReader(stream);
sw2.Stop();
return respReader.ReadToEnd();
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
return String.Empty;
}
return null;
}
}
如果我从命令行执行curl,它将启动一个tickingpload进度文本,显示已上载的mb数和预计剩余时间,因此邮递员服务器似乎支持此功能:
C:\temp>curl-v-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah”>log.txt
%总接收百分比%x平均速度时间电流
数据加载上载总左速度
0 0 0 0 0 0 0--:-:-:-:-:-:---:---0*正在尝试107.23.124.180
- TCP_节点集
- 连接到postman-echo.com(107.23.124.180)端口443(#0)
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤1/3)
- schannel:正在检查服务器证书吊销
- 发送初始握手数据:发送181字节
- schannel:发送的初始握手数据:发送181字节
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
- schannel:无法接收握手,需要更多数据
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
- schannel:加密数据得到4096个
- schannel:加密数据缓冲区:偏移量4096长度4096
- schannel:加密数据长度:4030
- schannel:加密数据缓冲区:偏移量4030长度4096
- schannel:收到不完整的消息,需要更多数据
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
- 沙内尔:加密的数据有1024个
- schannel:加密数据缓冲区:偏移量5054长度5054
- schannel:加密数据长度:200
- schannel:加密数据缓冲区:偏移量200长度5054
- schannel:收到不完整的消息,需要更多数据
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
- 沙内尔:加密数据得到147
- schannel:加密数据缓冲区:偏移量347长度5054
- 发送下一次握手数据:发送126字节
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤2/3)
- 沙内尔:加密数据得到258
- schannel:加密数据缓冲区:偏移量258长度5054
- schannel:SSL/TLS握手完成
- schannel:postman-echo.com端口443的SSL/TLS连接(步骤3/3)
- schannel:会话缓存中存储的凭据句柄
- schannel:客户端想要读取102400字节
- schannel:encdata_缓冲区大小调整为103424
- schannel:加密数据缓冲区:偏移量0长度103424
- 沙内尔:加密数据得到54
- schannel:加密数据缓冲区:偏移量54长度103424
- schannel:解密的数据长度:25
- schannel:已添加解密数据:25
- schannel:缓存的解密数据:偏移量25长度102400
- schannel:加密数据缓冲区:偏移量0长度103424
- schannel:解密数据缓冲区:偏移量25长度102400
- schannel:schannel_recv清理
- schannel:已解密的数据返回25
- schannel:解密的数据缓冲区:偏移量0长度102400
3110.9M 0 0 31 3552k 0 208k 0:00:53 0:00:17 0:00:36 317kHttp具有流模式(1.0)和块模式(1.1)。当建立连接时,客户机和服务器之间会进行协商,以获得公共传输模式。仅当服务器支持区块模式时,区块模式才起作用。尝试向请求中添加以下内容:request.ProtocolVersion=HttpVersion.Version11;谢谢你的建议,但遗憾的是,这没什么区别。我更新了我的代码以显示我如何使用您的建议。如果我从命令行做一个curl,我可以得到一个进度表,所以看起来postmanecho服务器支持这个。C:\temp>curl-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah“>log.txt%总计%已接收%Xferd平均速度时间当前数据加载上载总计已用左速度810.9M 08944k 0236k 0:00:47 0:00:04 0:00:43 218k^CHttp具有流模式(1.0)块模式(1.1)。当建立连接时,客户机和服务器之间会进行协商,以获得公共传输模式。仅当服务器支持区块模式时,区块模式才起作用。尝试向请求中添加以下内容:request.ProtocolVersion=HttpVersion.Version11;谢谢你的建议,但遗憾的是,这没什么区别。我更新了我的代码以显示我如何使用您的建议。如果我从命令行做一个curl,我可以得到一个进度表,所以看起来postmanecho服务器支持这个。C:\temp>curl-X PUT-F“filefield=@C:\temp\zipfile.zip“-F”field2=blah”>log.txt%总计%已接收%Xferd平均速度时间当前数据加载上载总计已用左速度810.9M 08944k 0236k 0:00:47 0:00:04 0:00:43 218k^C