【问题标题】:tracking upload progress of multiple file uploads using multipart/body web request使用多部分/正文 Web 请求跟踪多个文件上传的上传进度
【发布时间】:2016-07-08 16:10:11
【问题描述】:

我正在使用 HttpWebRequest 将文件上传到服务器。该请求向服务器发送 2 个文件,一个视频文件和一个图像文件。我正在尝试跟踪整个进度的进度,但问题是,进度日志为每个文件上传单独运行。我希望两个上传的进度只显示一次,但我不知道该怎么做。这是我的客户端代码:

Dictionary<string, string> fields = new Dictionary<string, string>();
        fields.Add("username", username);

        HttpWebRequest hr = WebRequest.Create(url) as HttpWebRequest;
        hr.Timeout = 500000;
        string bound = "----------------------------" + DateTime.Now.Ticks.ToString("x");
        hr.ContentType = "multipart/form-data; boundary=" + bound;
        hr.Method = "POST";
        hr.KeepAlive = true;
        hr.Credentials = CredentialCache.DefaultCredentials;

        byte[] boundBytes = Encoding.ASCII.GetBytes("\r\n--" + bound + "\r\n");
        string formDataTemplate = "\r\n--" + bound + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

        Stream s = hr.GetRequestStreamWithTimeout(1000000);

        foreach (string key in fields.Keys)
        {
            byte[] formItemBytes = Encoding.UTF8.GetBytes(
                string.Format(formDataTemplate, key, fields[key]));
            s.Write(formItemBytes, 0, formItemBytes.Length);
        }

        s.Write(boundBytes, 0, boundBytes.Length);

        string headerTemplate =
            "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";

        List<string> files = new List<string> { fileUrl, thumbUrl };
        List<string> type = new List<string> { "video", "thumb" };

        int count = 0;
        foreach (string f in files)
        {
            var m = Path.GetFileName(f);
            var t = type[count];
            var j = string.Format(headerTemplate, t, m);
            byte[] headerBytes = Encoding.UTF8.GetBytes(
                string.Format(headerTemplate, type[count], Path.GetFileName(f)));

            s.Write(headerBytes, 0, headerBytes.Length);
            FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read);
            int bytesRead = 0;
            long bytesSoFar = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
            {
                bytesSoFar += bytesRead;
                s.Write(buffer, 0, buffer.Length);
                Console.WriteLine(string.Format("sending file data {0:0.000}%", (bytesSoFar * 100.0f) / fs.Length));

            }

            s.Write(boundBytes, 0, boundBytes.Length);
            fs.Close();

            count += 1;
        }

        s.Close();

        string respString = "";
        hr.BeginGetResponse((IAsyncResult res) =>
        {
            WebResponse resp = ((HttpWebRequest)res.AsyncState).EndGetResponse(res);

            StreamReader respReader = new StreamReader(resp.GetResponseStream());
            respString = respReader.ReadToEnd();
            resp.Close();
            resp = null;
        }, hr);

        while (!hr.HaveResponse)
        {
            Console.Write("hiya bob!");
            Thread.Sleep(150);
        }

        Console.Write(respString);
        hr = null;

如何将两个上传的进度日志合并到一个日志中?任何帮助表示赞赏。

【问题讨论】:

    标签: c# file-upload httpwebrequest


    【解决方案1】:

    一种选择是在进行任何工作之前计算您需要发送的总字节数:

    // Calculate the total size to upload before starting work
    long totalToUpload = 0;
    foreach (var f in files)
    {
        totalToUpload += (new FileInfo(f)).Length;
    }
    

    然后跟踪在任何文件中发送的总字节数,并将其用于计算进度:

    int count = 0;
    long bytesSoFar = 0;
    
    foreach (string f in files)
    {
        // ... Your existing work ...
    
        while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
        {
            bytesSoFar += bytesRead;
            // Make sure to only write the number of bytes read from the file
            s.Write(buffer, 0, bytesRead);
            // Console.WriteLine takes a string.Format() style string
            Console.WriteLine("sending file data {0:0.000}%", (bytesSoFar * 100.0f) / totalToUpload);
        }
    

    【讨论】:

    • 酷。这可以工作。我会给你的答案打分,如果我让它发挥作用,我会回来将其标记为已回答。谢谢! :)
    • 不应该 bytesSoFar 包含上一个文件上传的字节数吗?第一次上传文件的进度条从 0 到 96%,从 0 开始,第二次上传到 3.426%
    • 我想我需要在循环范围之外定义 bytesSoFar
    • 是的,应该。你会注意到我已经将bytesSoFar 移到foreach 循环之外,这样它就可以了。另外,重要的是要注意s.Write(...) 应该对bytesRead 中的数字进行操作,而不是buffer.Length。它们经常是相同的,但在最后一次读取文件时几乎总是不同的。
    猜你喜欢
    • 2016-06-27
    • 2014-11-15
    • 1970-01-01
    • 2021-05-18
    • 2018-09-26
    • 2018-10-25
    • 2023-03-31
    • 2017-02-11
    • 2017-04-23
    相关资源
    最近更新 更多