文件上传进度进度、文件上传

2023-09-07 03:28:20 作者:美图秀秀成就了多少网恋

我一直在试图跟踪文件上传进度,但保持在结束了在死角(从C#应用程序而不是网页上传)。

I've been trying to track the progress of a file upload but keep on ending up at dead ends (uploading from a C# application not a webpage).

我尝试使用 Web客户端这样:

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);
    }
}

的文件执行上载和进展被打印出来,但进展比实际上传快得多和上载大文件时的进展将在几秒钟内达到最大,但实际上载需要几分钟(它不是只是在等待一个响应,所有的数据尚未到达服务器)。

The file does upload and progress is printed out but the progress is much faster than the actual upload and when uploading a large file the progress will reach the maximum within a few seconds but the actual upload takes a few minutes (it is not just waiting on a response, all the data have not yet arrived at the server).

所以我试图用的HttpWebRequest 流的数据,而不是(我知道这是不是一个文件上传的完全等效,因为它不会产生的multipart / form-data的的内容,但它确实可以说明我的问题)。我设置 AllowWriteStreamBuffering = FALSE ,并设置 CONTENTLENGTH 所建议的this提问/回答:

So I tried using HttpWebRequest to stream the data instead (I know this is not the exact equivalent of a file upload as it does not produce multipart/form-data content but it does serve to illustrate my problem). I set AllowWriteStreamBuffering = false and set the ContentLength as suggested by this question/answer:

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();
    }
}

该请求不启动,直到整个文件已经被写入流,并已经具备了在它开始​​(我使用的小提琴手以验证这一点)。我也试着设置 SendChunked 为真(有和没有设置 CONTENTLENGTH 以及)。好像仍然得到被通过网络发送之前,缓存中的数据。

The request does not start until the entire file have been written to the stream and already shows full progress at the time it starts (I'm using fiddler to verify this). I also tried setting SendChunked to true (with and without setting the ContentLength as well). It seems like the data still gets cached before being sent over the network.

时有什么问题,这些方法中的一种或有可能是另一种方式,我可以从Windows应用程序跟踪文件上传进度?

Is there something wrong with one of these approaches or is there perhaps another way I can track the progress of file uploads from a windows application?

推荐答案

更新:

该控制台应用程序适用于我的预期:

This console app works for me as expected:

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);
    }