首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用'application/x-www-form-urlencoded‘上传文件

使用'application/x-www-form-urlencoded‘上传文件
EN

Stack Overflow用户
提问于 2011-09-12 10:33:19
回答 1查看 1.4K关注 0票数 1

我想使用应用程序和‘C# /x-www-form-urlencoded’方法上传一个文件。我看到的所有示例都首先将文件数据读取到字节数组中,但这对我不起作用,因为我发送的文件超过500MB。所以我正在寻找一种直接从磁盘传输文件的方法。

这个问题的一个好处是从指定的字节位置读取文件,例如,我可以从第500个字节开始,而不是从第一个字节到最后一个字节。

EN

回答 1

Stack Overflow用户

发布于 2011-09-12 12:30:01

您应该按块写入数据,因此上载的主要部分应如下所示

代码语言:javascript
复制
var buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fileData.Read(buffer, 0, buffer.Length)) != 0)
     requestStream.Write(buffer, 0, bytesRead);

全部上传代码。

代码语言:javascript
复制
public static class Upload
{
    private const string FileFieldNameDefault = "fileContent";

    public static WebResponse PostFile
        (Uri requestUri, NameValueCollection postData, Stream fileData, string fileName,
         string fileContentType, string fileFieldName, CookieContainer cookies,
         NameValueCollection headers)
    {
        ServicePointManager.Expect100Continue = false; 

        if (requestUri.Scheme == "https") 
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

            ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, err) => true;
        }

        var webRequest = (HttpWebRequest)WebRequest.Create(requestUri);

        webRequest.Method = "POST";

        string boundary = "----------" + DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture);

        webRequest.ContentType = "multipart/form-data; boundary=" + boundary;

        string ctype;

        if (string.IsNullOrEmpty(fileContentType))
            fileContentType = TryGetContentType(fileName, out ctype)
                                ? ctype
                                : "application/octet-stream";

        fileFieldName = string.IsNullOrEmpty(fileFieldName) ? FileFieldNameDefault : fileFieldName;

        if (headers != null)
            foreach (string key in headers.AllKeys)
            {
                var values = headers.GetValues(key);
                if (values != null)
                    foreach (var value in values)
                        webRequest.Headers.Add(key, value);
            }

        if (cookies != null)
            webRequest.CookieContainer = cookies;

        var sbHeader = new StringBuilder();

        if (fileData != null)
        {
            var fileNameValue = string.Empty;

            if (string.IsNullOrEmpty(fileName) == false)
                fileNameValue = string.Format(CultureInfo.InvariantCulture, "filename=\"{0}\"", Path.GetFileName(fileName));

            sbHeader
                .AppendFormat("--{0}", boundary)
                .AppendLine()
                .AppendFormat("Content-Disposition: form-data; name=\"{0}\"; {1}", fileFieldName, fileNameValue)
                .AppendLine()
                .AppendFormat("Content-Type: {0}", fileContentType)
                .AppendLine()
                .AppendLine();
        }

        var sbFooter = new StringBuilder();
        sbFooter.AppendLine();

        if (postData != null)
            foreach (var key in postData.AllKeys)
            {
                var values = postData.GetValues(key);
                if (values != null)
                    foreach (var value in values)
                        sbFooter
                            .AppendFormat("--{0}", boundary)
                            .AppendLine()
                            .AppendFormat("Content-Disposition: form-data; name=\"{0}\"", key)
                            .AppendLine()
                            .AppendLine()
                            .Append(value)
                            .AppendLine();
            }

        sbFooter.AppendFormat("--{0}--\r\n", boundary);

        byte[] header = Encoding.UTF8.GetBytes(sbHeader.ToString());
        byte[] footer = Encoding.UTF8.GetBytes(sbFooter.ToString());
        long contentLength = header.Length + (fileData != null ? fileData.Length : 0) + footer.Length;

        webRequest.ContentLength = contentLength;

        using (var requestStream = webRequest.GetRequestStream())
        {
            requestStream.Write(header, 0, header.Length);

            if (fileData != null)
            {
                var buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fileData.Read(buffer, 0, buffer.Length)) != 0)
                    requestStream.Write(buffer, 0, bytesRead);
            }

            requestStream.Write(footer, 0, footer.Length);

            return webRequest.GetResponse();
        }
    }

    public static WebResponse PostFile
        (Uri requestUri, NameValueCollection postData, string fileName,
         string fileContentType, string fileFieldName, CookieContainer cookies,
         NameValueCollection headers)
    {
        using (var fileData = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            return PostFile(requestUri, postData, fileData,
                            fileName, fileContentType, fileFieldName, cookies,
                            headers);
    }

    private static bool TryGetContentType(string fileName, out string contentType)
    {
        try
        {
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"MIME\Database\Content Type");

            if (key != null)
            {
                foreach (string keyName in from keyName in key.GetSubKeyNames()
                                           let subKey = key.OpenSubKey(keyName)
                                           where subKey != null
                                           let subKeyValue = (string)subKey.GetValue("Extension")
                                           where string.IsNullOrEmpty(subKeyValue) == false
                                           where string.Compare(Path.GetExtension(fileName), subKeyValue, StringComparison.OrdinalIgnoreCase) == 0
                                           select keyName)
                {
                    contentType = keyName;
                    return true;
                }
            }
        }
        catch
        {
            // fail silently
            // TODO: rethrow registry access denied errors
        }
        contentType = string.Empty;
        return false;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7382786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档