上传大文件问题! 进来看下!

时间:2022-08-28 20:02:18
        在本地测试上传80M的文件,4秒左右就传完了,   上传服务器,过了几十秒都上传不上去

          而且还出现该页无法显示了。


            是什么原因????

26 个解决方案

#1


你看下你的web.config有没有上传文件大小的限制。默认好像是10M。本地传你自己肯定快了啊。

#2


 Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


   上传的是视频格式的东西! flv,mp4,mov 等!

#3


关注
多测试下!

#4


。。。。。。
本地测试,你打开360的流量监控看看,几十M/s,当然几秒就上传了。

放在服务器,你看看,30KB/S,这能几秒就上传上去吗,至少半个小时。

出现无法显示,因为上传过期时间到了,你把过期时间再设置大一点。

#5


引用 2 楼 hou306010849 的回复:
Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


  上传的是视频格式的东西! flv,mp4,mov 等!


上传大小,你是设到最大了,也要把过期时间设置大一点啊。

没有办法能它上传快,受本地网张上传影响,如果你是1M网速的,速率也不过是 200KB/S,这还是全部网络由你占有的情况下,但一般,你只能占到70到80。

#6


引用 2 楼 hou306010849 的回复:
 Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


搞笑的,去把你的宽带换成1G的吧。

#7


 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!

#8


引用 7 楼 hou306010849 的回复:
 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!


你的图片有 17M ? 80M ?

#9


对于这样的上传,建议不要这么传统,最好将文件分块上传,设置webconfig这样的方式总是不能满足需求的

#10


引用 8 楼 karascanvas 的回复:
引用 7 楼 hou306010849 的回复:

我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



网速4M的 上传图片挺块的!


你的图片有 17M ? 80M ?


咱能不能看好了在说,我说的是flv 文件,  图片上传挺块的, 明白么?

#11


是这样的,没啥好说的,上传大文件就这样,慢慢的,基于网页上传,如是容易受到影响,比如你基于网页下载大文件(右健--另存为),一开始很快,后来就慢了,因为后来人家占了资源,你就慢了,人家放了,你还是慢,就这样,没办法。

因为图片小,上传时间短,所以受影响不大,视频大,上传时间长,所以受影响大。所以,你上传视频时,最好不要乱动。

#12


一般上传大文件我们这里都是直接通过FTP传,一是不会出现网页超时,二是稳定,三是可以续传

#13


 难道就没别的办法了? 就只有通过FTP 上传了????


      谁能给个办法啊! 

#14


引用 13 楼 hou306010849 的回复:
难道就没别的办法了? 就只有通过FTP 上传了????


  谁能给个办法啊!


局域网上传可以达到10M/秒,但外网的上传资源份额是有限的,我们这边的电信上行就控制得很严,只有几十K/s(光纤除外),LZ可以自己找一个工具来测试一下你那边的上行流量,你就明白为什么不能通过网页上传的原因了

#15


网上很多找下就好了。

#16


引用 12 楼 liuchaolin 的回复:
一般上传大文件我们这里都是直接通过FTP传,一是不会出现网页超时,二是稳定,三是可以续传


FTP要服务器支持才行的吧?

#17


引用 7 楼 hou306010849 的回复:
 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!


你的浏览器是什么版本的 IE的话 有一个什么筛选的东西要关闭

#18


关闭浏览器的smartscreen筛选试试

#19


 我顶!

#20


引用 2 楼 hou306010849 的回复:
Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?

本地测试,那就是本机对本机的Http,不会有什么网络瓶颈,网速你只能去找相关的维护方了
1. 服务器上一般默认上传最大2M,在网站的配置文件里改下
2. 网页默认执行超时是90秒,在CS中加Server.ScriptTimeOut = 3600; 单位秒

#21


答案己出,基于网页上传就是这样,尽量在web.conging把过期时间弄长一点,设置3到5小时也是可以的

#22


要使用多线程续传技术,http肯定会超时的。

#23


断点续传
上传
断点续传

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace CompleteClient
{
    /// <summary>
    /// 文件发送工作类
    /// </summary>
    class PostFile
    {
        /// <summary>
        /// 通过post发送指定文件的指定字段到指定的uri上
        /// </summary>
        /// <param name="uploadfile">上传文件路径</param>
        /// <param name="url">上传的到的URi位置</param>
        /// <param name="offset">当前偏移量</param>
        /// <param name="size">需要发送的块大小</param>
        /// <param name="fileFormName">服务器端"GET"取得的文件名</param>
        /// <param name="contenttype">文件类型(保留用)</param>
        /// <param name="querystring">GET数组(供服务器用GET取得一些信息)</param>
        /// <param name="cookies">本地cookies(保留用)</param>
        /// <returns>uri的response的内容以string的形式返回</returns>
        public string UploadFileEx(string uploadfile, string url, long offset, long size,
                                   string fileFormName, string contenttype,
                                   NameValueCollection querystring, CookieContainer cookies)
        {
            if ((fileFormName == null) ||
            (fileFormName.Length == 0))
            {
                fileFormName = "file";
            }

            if ((contenttype == null) ||
            (contenttype.Length == 0))
            {
                contenttype = "application/octet-stream";
            }

            string postdata;
            postdata = "?";
            if (querystring != null)
            {
                foreach (string key in querystring.Keys)
                {
                    postdata += key + "=" + querystring.Get(key) + "&";
                }
            }
            Uri uri = new Uri(url + postdata);

            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
            webrequest.CookieContainer = cookies;
            webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
            webrequest.Method = "POST";

            // 构造一个post请求的http头
            StringBuilder sb = new StringBuilder();
            sb.Append("--");
            sb.Append(boundary);
            sb.Append("\r\n");
            sb.Append("Content-Disposition: form-data; name=\"");
            sb.Append(fileFormName);
            sb.Append("\"; filename=\"");
            sb.Append(Path.GetFileName(uploadfile));
            sb.Append("\"");
            sb.Append("\r\n");
            sb.Append("Content-Type: ");
            sb.Append(contenttype);
            sb.Append("\r\n");
            sb.Append("\r\n");

            string postHeader = sb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

            // Build the trailing boundary string as a byte array
            // ensuring the boundary appears on a line by itself
            byte[] boundaryBytes =
            Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            FileStream fileStream = new FileStream(uploadfile,
                            FileMode.Open, FileAccess.Read);
            long length = postHeaderBytes.Length + (long)size +
                                       boundaryBytes.Length;
            webrequest.ContentLength = length;

            Stream requestStream = webrequest.GetRequestStream();
            // 写入post头
            requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

            // 写入文件内容
            byte[] buffer = new Byte[size];
            fileStream.Seek(offset, SeekOrigin.Current);
            fileStream.Read(buffer, 0, buffer.Length);

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

            // 写入post请求的尾
            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            //读取服务器的反馈消息
            WebResponse responce = webrequest.GetResponse();
            Stream s = responce.GetResponseStream();
            StreamReader sr = new StreamReader(s);

            return sr.ReadToEnd();
        }
    }
}

#24


引用楼主  的回复:
        在本地测试上传80M的文件,4秒左右就传完了,   上传服务器,过了几十秒都上传不上去

          而且还出现该页无法显示了。


            是什么原因????

传统的HTML方式已经难已满足超大文件的上传。别说是100MB,50MB对服务器来说都是非常大的,服务不仅要专门开一个socket连接接一直等待这个文件上传完毕,还要分配同等大小的内存来保存这个文件对服务器造成的压力相当的大,而且这个压力将会随着用户的增加而成几何式的增加。就算是用Flash也不行,因为目前的Flash不支持断点续传操作,也不支持文件分块操作,Flash和传统的HTML方式上传原理一样。用Flash上传100MB图片,服务器也要分配100MB的内存。10个用户同时上传100MB数据的话,就要吃掉服务器1G的内存。

有些朋友试过用Flash文件上传控件来上传超大文件,但是经常遇到上传超时,或上传出错的问题。这是因为现在的Flash文件上传控件使用的技术还是和传统的HTML方式上传一样。没有使用分段上传技术,这种传统的HTML上传方式需要服务器必须开着一个SOCKET连接一直等到Flash上传完毕。这在大并发的情况下对服务器可能会造成非常大的压力,因为网站的访问量一大,用户上传的文件一多,服务器不可能为一个用户等很长时间。都是希望能够在最短的时间内处理完用户的请求。

像QQ邮箱中的超大附件上传功能,115网盘中的超大附件上传控件,华为网盘(DBank),金山快盘他们都是使用控件来实现超大文件上传功能的。这样做主要是减轻服务器压力,节省服务器内存,同时提高用户体验。

当然从技术角度来讲,像这些互联网知名企业也是考虑了支撑海量用户的分布式文件存储构架设计。因为他们的文件存储服务器不可能是一台,而且会动态的随着用户数的增加而增加。

如果真如某些朋友所说的Flash控件就能解决超大文件上传的问题,那么腾迅也不会花那么大的力气专门为QQ邮箱开发一个控件了。

#25


引用楼主  的回复:
        在本地测试上传80M的文件,4秒左右就传完了,   上传服务器,过了几十秒都上传不上去

          而且还出现该页无法显示了。


            是什么原因????

在实际网络环境中一般100MB左右的文件都需要借助于控件来实现。一方面是因为国内的网络环境不太稳定,另一方面是从服务器的负载方面考虑。
我们的网站用户有的可能用的电信的网络,有的用的是联通的网络,有的是用的教育网,有的在南有的在北,这种复杂的网络环境导致他们访问网站的速度是不同的。有的用户网速快,比如电信的用户访问电信的机房肯定快,他上传大文件可能没有问题。但是联通的访问电信的机房可能就慢了,他上传大文件可能就出现上传超时,掉线等问题。

服务器负载的问题,现在普通的文件上传技术对服务端带来的压力还是非常大的。普通的HTML上传1G的文件,服务端需要先分配1G的内存,然后开个长连接一直等待客户上传完毕。在这个期间如果有其它的用户也要上传1G的文件,那么服务端就再分配1G的内存。可以想象如果用户多了,那服务器肯定扛不住挂扯。就算是用Flash也一样,比如swfupload还有其它的几个Flash控件,他们使用的技术还是和普通的HTML一样。

腾迅他们正是考虑了这个问题,所以使用控件来解决这个问题。他们通过控件将一个大文件,比如1G划分成许多的小块,每一小块大约是128KB,然后循环上传,直到上传完。这样做的优点就是减轻了服务端的压力,提高了服务端的负载能力,使得服务端能够处理的用户请求数多了。也节省了成本。

#26


该回复于2016-08-15 16:40:40被管理员删除

#1


你看下你的web.config有没有上传文件大小的限制。默认好像是10M。本地传你自己肯定快了啊。

#2


 Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


   上传的是视频格式的东西! flv,mp4,mov 等!

#3


关注
多测试下!

#4


。。。。。。
本地测试,你打开360的流量监控看看,几十M/s,当然几秒就上传了。

放在服务器,你看看,30KB/S,这能几秒就上传上去吗,至少半个小时。

出现无法显示,因为上传过期时间到了,你把过期时间再设置大一点。

#5


引用 2 楼 hou306010849 的回复:
Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


  上传的是视频格式的东西! flv,mp4,mov 等!


上传大小,你是设到最大了,也要把过期时间设置大一点啊。

没有办法能它上传快,受本地网张上传影响,如果你是1M网速的,速率也不过是 200KB/S,这还是全部网络由你占有的情况下,但一般,你只能占到70到80。

#6


引用 2 楼 hou306010849 的回复:
 Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?


搞笑的,去把你的宽带换成1G的吧。

#7


 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!

#8


引用 7 楼 hou306010849 的回复:
 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!


你的图片有 17M ? 80M ?

#9


对于这样的上传,建议不要这么传统,最好将文件分块上传,设置webconfig这样的方式总是不能满足需求的

#10


引用 8 楼 karascanvas 的回复:
引用 7 楼 hou306010849 的回复:

我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



网速4M的 上传图片挺块的!


你的图片有 17M ? 80M ?


咱能不能看好了在说,我说的是flv 文件,  图片上传挺块的, 明白么?

#11


是这样的,没啥好说的,上传大文件就这样,慢慢的,基于网页上传,如是容易受到影响,比如你基于网页下载大文件(右健--另存为),一开始很快,后来就慢了,因为后来人家占了资源,你就慢了,人家放了,你还是慢,就这样,没办法。

因为图片小,上传时间短,所以受影响不大,视频大,上传时间长,所以受影响大。所以,你上传视频时,最好不要乱动。

#12


一般上传大文件我们这里都是直接通过FTP传,一是不会出现网页超时,二是稳定,三是可以续传

#13


 难道就没别的办法了? 就只有通过FTP 上传了????


      谁能给个办法啊! 

#14


引用 13 楼 hou306010849 的回复:
难道就没别的办法了? 就只有通过FTP 上传了????


  谁能给个办法啊!


局域网上传可以达到10M/秒,但外网的上传资源份额是有限的,我们这边的电信上行就控制得很严,只有几十K/s(光纤除外),LZ可以自己找一个工具来测试一下你那边的上行流量,你就明白为什么不能通过网页上传的原因了

#15


网上很多找下就好了。

#16


引用 12 楼 liuchaolin 的回复:
一般上传大文件我们这里都是直接通过FTP传,一是不会出现网页超时,二是稳定,三是可以续传


FTP要服务器支持才行的吧?

#17


引用 7 楼 hou306010849 的回复:
 我上传一个flv 的文件 17M 上传了4分钟左右,怎么会这么慢啊!



    网速4M的 上传图片挺块的!


你的浏览器是什么版本的 IE的话 有一个什么筛选的东西要关闭

#18


关闭浏览器的smartscreen筛选试试

#19


 我顶!

#20


引用 2 楼 hou306010849 的回复:
Web.config 我已经设置到了最大,但还是很慢啊,有什么办法,能让上传块点?

本地测试,那就是本机对本机的Http,不会有什么网络瓶颈,网速你只能去找相关的维护方了
1. 服务器上一般默认上传最大2M,在网站的配置文件里改下
2. 网页默认执行超时是90秒,在CS中加Server.ScriptTimeOut = 3600; 单位秒

#21


答案己出,基于网页上传就是这样,尽量在web.conging把过期时间弄长一点,设置3到5小时也是可以的

#22


要使用多线程续传技术,http肯定会超时的。

#23


断点续传
上传
断点续传

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace CompleteClient
{
    /// <summary>
    /// 文件发送工作类
    /// </summary>
    class PostFile
    {
        /// <summary>
        /// 通过post发送指定文件的指定字段到指定的uri上
        /// </summary>
        /// <param name="uploadfile">上传文件路径</param>
        /// <param name="url">上传的到的URi位置</param>
        /// <param name="offset">当前偏移量</param>
        /// <param name="size">需要发送的块大小</param>
        /// <param name="fileFormName">服务器端"GET"取得的文件名</param>
        /// <param name="contenttype">文件类型(保留用)</param>
        /// <param name="querystring">GET数组(供服务器用GET取得一些信息)</param>
        /// <param name="cookies">本地cookies(保留用)</param>
        /// <returns>uri的response的内容以string的形式返回</returns>
        public string UploadFileEx(string uploadfile, string url, long offset, long size,
                                   string fileFormName, string contenttype,
                                   NameValueCollection querystring, CookieContainer cookies)
        {
            if ((fileFormName == null) ||
            (fileFormName.Length == 0))
            {
                fileFormName = "file";
            }

            if ((contenttype == null) ||
            (contenttype.Length == 0))
            {
                contenttype = "application/octet-stream";
            }

            string postdata;
            postdata = "?";
            if (querystring != null)
            {
                foreach (string key in querystring.Keys)
                {
                    postdata += key + "=" + querystring.Get(key) + "&";
                }
            }
            Uri uri = new Uri(url + postdata);

            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
            webrequest.CookieContainer = cookies;
            webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
            webrequest.Method = "POST";

            // 构造一个post请求的http头
            StringBuilder sb = new StringBuilder();
            sb.Append("--");
            sb.Append(boundary);
            sb.Append("\r\n");
            sb.Append("Content-Disposition: form-data; name=\"");
            sb.Append(fileFormName);
            sb.Append("\"; filename=\"");
            sb.Append(Path.GetFileName(uploadfile));
            sb.Append("\"");
            sb.Append("\r\n");
            sb.Append("Content-Type: ");
            sb.Append(contenttype);
            sb.Append("\r\n");
            sb.Append("\r\n");

            string postHeader = sb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

            // Build the trailing boundary string as a byte array
            // ensuring the boundary appears on a line by itself
            byte[] boundaryBytes =
            Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            FileStream fileStream = new FileStream(uploadfile,
                            FileMode.Open, FileAccess.Read);
            long length = postHeaderBytes.Length + (long)size +
                                       boundaryBytes.Length;
            webrequest.ContentLength = length;

            Stream requestStream = webrequest.GetRequestStream();
            // 写入post头
            requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

            // 写入文件内容
            byte[] buffer = new Byte[size];
            fileStream.Seek(offset, SeekOrigin.Current);
            fileStream.Read(buffer, 0, buffer.Length);

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

            // 写入post请求的尾
            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            //读取服务器的反馈消息
            WebResponse responce = webrequest.GetResponse();
            Stream s = responce.GetResponseStream();
            StreamReader sr = new StreamReader(s);

            return sr.ReadToEnd();
        }
    }
}

#24


引用楼主  的回复:
        在本地测试上传80M的文件,4秒左右就传完了,   上传服务器,过了几十秒都上传不上去

          而且还出现该页无法显示了。


            是什么原因????

传统的HTML方式已经难已满足超大文件的上传。别说是100MB,50MB对服务器来说都是非常大的,服务不仅要专门开一个socket连接接一直等待这个文件上传完毕,还要分配同等大小的内存来保存这个文件对服务器造成的压力相当的大,而且这个压力将会随着用户的增加而成几何式的增加。就算是用Flash也不行,因为目前的Flash不支持断点续传操作,也不支持文件分块操作,Flash和传统的HTML方式上传原理一样。用Flash上传100MB图片,服务器也要分配100MB的内存。10个用户同时上传100MB数据的话,就要吃掉服务器1G的内存。

有些朋友试过用Flash文件上传控件来上传超大文件,但是经常遇到上传超时,或上传出错的问题。这是因为现在的Flash文件上传控件使用的技术还是和传统的HTML方式上传一样。没有使用分段上传技术,这种传统的HTML上传方式需要服务器必须开着一个SOCKET连接一直等到Flash上传完毕。这在大并发的情况下对服务器可能会造成非常大的压力,因为网站的访问量一大,用户上传的文件一多,服务器不可能为一个用户等很长时间。都是希望能够在最短的时间内处理完用户的请求。

像QQ邮箱中的超大附件上传功能,115网盘中的超大附件上传控件,华为网盘(DBank),金山快盘他们都是使用控件来实现超大文件上传功能的。这样做主要是减轻服务器压力,节省服务器内存,同时提高用户体验。

当然从技术角度来讲,像这些互联网知名企业也是考虑了支撑海量用户的分布式文件存储构架设计。因为他们的文件存储服务器不可能是一台,而且会动态的随着用户数的增加而增加。

如果真如某些朋友所说的Flash控件就能解决超大文件上传的问题,那么腾迅也不会花那么大的力气专门为QQ邮箱开发一个控件了。

#25


引用楼主  的回复:
        在本地测试上传80M的文件,4秒左右就传完了,   上传服务器,过了几十秒都上传不上去

          而且还出现该页无法显示了。


            是什么原因????

在实际网络环境中一般100MB左右的文件都需要借助于控件来实现。一方面是因为国内的网络环境不太稳定,另一方面是从服务器的负载方面考虑。
我们的网站用户有的可能用的电信的网络,有的用的是联通的网络,有的是用的教育网,有的在南有的在北,这种复杂的网络环境导致他们访问网站的速度是不同的。有的用户网速快,比如电信的用户访问电信的机房肯定快,他上传大文件可能没有问题。但是联通的访问电信的机房可能就慢了,他上传大文件可能就出现上传超时,掉线等问题。

服务器负载的问题,现在普通的文件上传技术对服务端带来的压力还是非常大的。普通的HTML上传1G的文件,服务端需要先分配1G的内存,然后开个长连接一直等待客户上传完毕。在这个期间如果有其它的用户也要上传1G的文件,那么服务端就再分配1G的内存。可以想象如果用户多了,那服务器肯定扛不住挂扯。就算是用Flash也一样,比如swfupload还有其它的几个Flash控件,他们使用的技术还是和普通的HTML一样。

腾迅他们正是考虑了这个问题,所以使用控件来解决这个问题。他们通过控件将一个大文件,比如1G划分成许多的小块,每一小块大约是128KB,然后循环上传,直到上传完。这样做的优点就是减轻了服务端的压力,提高了服务端的负载能力,使得服务端能够处理的用户请求数多了。也节省了成本。

#26


该回复于2016-08-15 16:40:40被管理员删除