作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我一直在尝试跟踪文件上传的进度,但一直以死胡同告终(从 C# 应用程序而非网页上传)。
我试过这样使用 WebClient
:
class Program
{
static volatile bool busy = true;
static void Main(string[] args)
{
WebClient client = new WebClient();
// Add some custom header information
client.Credentials = new NetworkCredential("username", "password");
client.UploadProgressChanged += client_UploadProgressChanged;
client.UploadFileCompleted += client_UploadFileCompleted;
client.UploadFileAsync(new Uri("http://uploaduri/"), "filename");
while (busy)
{
Thread.Sleep(100);
}
Console.WriteLine("Done: press enter to exit");
Console.ReadLine();
}
static void client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
busy = false;
}
static void client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine("Completed {0} of {1} bytes", e.BytesSent, e.TotalBytesToSend);
}
}
文件确实上传并打印出进度,但进度比实际上传快很多,上传大文件时进度会在几秒内达到最大值,但实际上传需要几分钟(不是只是等待响应,所有数据还没有到达服务器)。
所以我尝试使用 HttpWebRequest
来流式传输数据(我知道这不完全等同于文件上传,因为它不会生成 multipart/form-data
内容,但它确实可以说明我的问题)。我设置了 AllowWriteStreamBuffering = false
并按照 this question/answer 的建议设置了 ContentLength
:
class Program
{
static void Main(string[] args)
{
FileInfo fileInfo = new FileInfo(args[0]);
HttpWebRequest client = (HttpWebRequest)WebRequest.Create(new Uri("http://uploadUri/"));
// Add some custom header info
client.Credentials = new NetworkCredential("username", "password");
client.AllowWriteStreamBuffering = false;
client.ContentLength = fileInfo.Length;
client.Method = "POST";
long fileSize = fileInfo.Length;
using (FileStream stream = fileInfo.OpenRead())
{
using (Stream uploadStream = client.GetRequestStream())
{
long totalWritten = 0;
byte[] buffer = new byte[3000];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
uploadStream.Write(buffer, 0, bytesRead);
uploadStream.Flush();
Console.WriteLine("{0} of {1} written", totalWritten += bytesRead, fileSize);
}
}
}
Console.WriteLine("Done: press enter to exit");
Console.ReadLine();
}
}
请求直到整个文件都被写入流并且在它开始时已经显示完整的进度后才会开始(我正在使用 fiddler 来验证这一点)。我还尝试将 SendChunked
设置为 true(同时设置和不设置 ContentLength
)。看起来数据在通过网络发送之前仍然被缓存。
这些方法是否有问题,或者是否有其他方法可以跟踪从 Windows 应用程序上传文件的进度?
最佳答案
更新:
此控制台应用程序按预期为我工作:
static ManualResetEvent done = new ManualResetEvent(false);
static void Main(string[] args)
{
WebClient client = new WebClient();
client.UploadProgressChanged += new UploadProgressChangedEventHandler(client_UploadProgressChanged);
client.UploadFileCompleted += new UploadFileCompletedEventHandler(client_UploadFileCompleted);
client.UploadFileAsync(new Uri("http://localhost/upload"), "C:\\test.zip");
done.WaitOne();
Console.WriteLine("Done");
}
static void client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
done.Set();
}
static void client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Console.Write("\rUploading: {0}% {1} of {2}", e.ProgressPercentage, e.BytesSent, e.TotalBytesToSend);
}
关于c# - 文件上传进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2681573/
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!