C#上传文件 HttpWebRequest改为HttpClient

1、先声明HttpClient是.net 4.5及其以后的版本中引入的,要使用的话必须是4.5及之后的版本才行。

2、原因

  再说下我为什么要把原始的HttpWebRequest改为HttpClient的原因,内存问题,是的,用HttpWebRequest上传文件,就如果100M的文件,2,3次就能把内存干爆,不知道为啥HttpWebRequest方法上传100M的文件,内存会增加300M,相当于加载了3次(我调代码发现的),而且方法里我把所有改置空的,要释放的都加了,然后无非就是多了几次,依然能拉爆软件的内存(因为测试可不会管你什么限制啥的,一次上传十几个百M的文件很正常)。而且现在大多数程序都是32位的,为了兼容软件使用的外部插件嘛没办法,这就导致能用的内存上下在1G左右(我们的软件,其他的不清楚,但32位上限确实低的多)。

  然后用HttpClient你会发现,就简单的几行代码,几乎没有需要置空或释放的,内部自己给你处理了。改完发现随便折腾没毛病,真是气死个人,有时候降维打击最为致命,就像二战时德国的步坦结合的闪电战,把还在延用一战阵地战的号称最强陆军的法国,几个月就打穿了。

3、下面直接贴代码了,分两部分,上面是原始的HttpWebRequest,下面的改的HttpClient的,供大家借鉴

  HttpWebRequest:

  

public string PostContainFiles(string url, Dictionary<string, string> formFields, Dictionary<string, byte[]> attachments)
{
    string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.ContentType = "multipart/form-data; boundary=" +
                            boundary;
    request.Method = "POST";
    request.KeepAlive = true;

    using (Stream memStream = new System.IO.MemoryStream())
    {
        var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
                                                                boundary + "\r\n");
        var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
                                                                    boundary + "--");


        string formdataTemplate = "\r\n--" + boundary +
                                    "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";


        //如果formFields不为空时 此项拼接在首位使用该字符串
        string formdataTemplateFirst = "--" + boundary +
                           "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
        bool ret = true;
    //formFields是接口的入参
if (formFields != null) { foreach (string key in formFields.Keys) { string formitem = string.Empty; if (ret) { formitem = string.Format(formdataTemplateFirst, key, formFields[key]); ret = false; } else { formitem = string.Format(formdataTemplate, key, formFields[key]); } byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); memStream.Write(formitembytes, 0, formitembytes.Length); } } string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + "Content-Type: application/octet-stream\r\n\r\n"; if (attachments != null && attachments.Any()) { foreach (var item in attachments) { memStream.Write(boundarybytes, 0, boundarybytes.Length); var header = string.Format(headerTemplate, item.Key, item.Key); var headerbytes = System.Text.Encoding.UTF8.GetBytes(header); memStream.Write(headerbytes, 0, headerbytes.Length); memStream.Write(item.Value, 0, item.Value.Length); } attachments.Clear(); attachments = null; } memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length); endBoundaryBytes = null; request.ContentLength = memStream.Length; using (Stream requestStream = request.GetRequestStream()) { memStream.Position = 0; byte[] tempBuffer = new byte[memStream.Length]; memStream.Read(tempBuffer, 0, tempBuffer.Length); memStream.Close(); requestStream.Write(tempBuffer, 0, tempBuffer.Length); requestStream.Flush(); tempBuffer = null; } memStream.Flush(); } using (var response = request.GetResponse()) { using (Stream stream2 = response.GetResponseStream()) { using (StreamReader reader2 = new StreamReader(stream2)) { string str = reader2.ReadToEnd(); return str; } } } }

  HttpClient:

  

public void PostContainAttachment(string url, Dictionary<string, string> formFields, Dictionary<string, byte[]> attachments)
{
    using (var httpClient = new HttpClient())
    {
        if (attachments != null && attachments.Any())
        {
            foreach (var item in attachments)
            {
                using (var content = new MultipartFormDataContent())
                {
                    using (var fileContent = new ByteArrayContent(item.Value))
                    {
                        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                        {
                            Name = item.Key,
                            FileName = item.Key,
                            FileNameStar = null
                        };
                        content.Add(fileContent, "file");
              //formFields是接口的传参
                        if (formFields != null)
                        {
                            foreach (string key in formFields.Keys)
                            {
                                content.Add(new StringContent(formFields[key]), "\"" + key + "\"");
                            }
                        }

                        // 上传文件,获取返回的字符串内容
                        var result = httpClient.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
                    }
                }
            }

            attachments.Clear();
            attachments = null;
        }
    }
}

 

posted @ 2024-12-13 15:39  卡萨丁·周  阅读(2)  评论(0编辑  收藏  举报