silverlight漂亮的文件上传进度显示原理及示例

作者:chenxumi 出处:博客园  2009/11/27 13:37:11 阅读 1219  次

概述:在网站根目录web.config里配置上传文件夹,注意:folder的value要写成windows资源管理器形式例如: upload\audio\chenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为4MB。

为了节省大家时间,先看怎么使用,最后再贴代码:
截图如下:

我把这个功能做成了一个控件,大家直接在要用的页面调用就行KeyTime的value就可以,具体怎么做,给大家推荐一个视频,
本来要贴视频地址的,但是silverlight.net网站打开的慢如蜗牛,大家有机会上去看看,有个动态改变keyframe的
value的一个动画

<%@ Register Src="~/SLUpload/SLUpload.ascx" TagName="Upload"  TagPrefix="u"%>
<u:Upload runat=server ></u:Upload>

在网站根目录web.config里配置上传文件夹,注意:folder的value要写成windows资源管理器形式例如:
upload\audio\chenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为4MB。所以maxRequestLength设为4100kb,至于为什么不是4096kb是因为上传时还附带了很多其他信息,例如当前文件的文件名、文件是否为第一次上传、文件是否是最后一块上传、文件此时的偏移量等信息,显然这种最大上传限制很有弹性,比起传统的一次性上传大小设置更有活性。

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="SLUpload" type="System.Configuration.NameValueSectionHandler"/>
    </configSections>
    <SLUpload>
        <add key="folder" value="upload"/>
    </SLUpload>
    <system.web>
        <httpRuntime maxRequestLength="4050"/>
        <compilation debug="true"/></system.web>
</configuration>

大家测试时有可能会出现文件无法上传的现象,这是在服务器后面又加别名导致FileReceive.ashx的路径错误。

从IIS里打开就可以解决这个问题。
文件下载地址:
http://files.cnblogs.com/chenxumi/sl.rar

这个程序的界面设计用的是Blend,只需改变

程序设计方面其实很简单,大家知道原理就行,把文件分成4mb大小的块,在发送一次文件时除发送文件的
本身数据流外,还得发送其他附加信息,例如文件名、文件此时的偏移量、是否是最后还是第一次到达,然后后台
接受文件的程序再根据这些信息先生成一个临时文件,如果此时文件存在则会删除文件,如果此时发送的文件是
最后一块时就将临时文件转移到目标文件夹中也就是web.config里配置的文件夹里。
这里还有个小问题大家注意,因为从服务器返回的响应和主程序是异步的,所以当返回后是不能调用主线程的,即不能
修改文件上传的界面,所以这里用到了线程的队列服务这个类 Dispatcher 具体代码请见如下:

 public Dispatcher UIDispatcher;
while (--)
            {
                requestStream.Write(buffer, 0, bytesRead);
                requestStream.Flush();                 send += bytesRead;
                tempTotal += bytesRead;
                this.UIDispatcher.BeginInvoke(delegate()
                {
                    OnProgressChanged();
                });
            }

文件选定、文件发送、以及服务器回调函数、以及进度变化都是些很简单的方法,大家看看就行了

private void btnUpLoad_Click(object sender, System.Windows.RoutedEventArgs e)
        {             OpenFileDialog dialog = new OpenFileDialog()
            {
                Filter = "all files|*.*",
                Multiselect = false
            };
            if ((bool)dialog.ShowDialog())
            {
                send = 0;
                data = dialog.File.OpenRead();
                filename = dialog.File.Name;
                UIDispatcher = this.Dispatcher;
                this.UIDispatcher.BeginInvoke(delegate()
                {
                    if (keyframe_rect.Value.Equals(270))
                    {
                        keyframe_rect.Value = -270;
                        txbPrecent.Text = "0%";
                        keyframe_rect.KeyTime = System.Windows.Media.Animation.KeyTime.FromTimeSpan(TimeSpan.Zero);
                        Storyboard1.Begin();
                    }
                });
                StartUpload();
            }
        }
        private void StartUpload()
        {
            double dataToSend = data.Length - send;
            bool isLastChunk = dataToSend <= ChunkSize;
            bool isFirstChunk = send == 0;             UriBuilder httpHandlerUrlBuilder = new UriBuilder(new Uri(this.url, UriKind.Absolute));
            httpHandlerUrlBuilder.Query = string.Format("{5}file={0}&offset={1}&last={2}&first={3}&param={4}", filename, send, isLastChunk, isFirstChunk, "", string.IsNullOrEmpty(httpHandlerUrlBuilder.Query) ? "" : httpHandlerUrlBuilder.Query.Remove(0, 1) + "&");             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(httpHandlerUrlBuilder.Uri);
            webRequest.Method = "POST";
            webRequest.BeginGetRequestStream(new AsyncCallback(WriteToStreamCallback), webRequest);         }         private void WriteToStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
            Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);             byte[] buffer = new Byte[4096];
            int bytesRead = 0;
            int tempTotal = 0;             while (tempTotal + bytesRead < ChunkSize && (bytesRead = data.Read(buffer, 0, buffer.Length)) != 0
            )
            {
                requestStream.Write(buffer, 0, bytesRead);
                requestStream.Flush();                 send += bytesRead;
                tempTotal += bytesRead;
                this.UIDispatcher.BeginInvoke(delegate()
                {
                    OnProgressChanged();
                });
            }             requestStream.Close();
            webRequest.BeginGetResponse(new AsyncCallback(ReadHttpResponseCallback), webRequest);         }         private void ReadHttpResponseCallback(IAsyncResult asynchronousResult)
        {             HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
            StreamReader reader = new StreamReader(webResponse.GetResponseStream());             string responsestring = reader.ReadToEnd();
            reader.Close();             if (send < data.Length)
            {
                StartUpload();
            }
            else
            {
                data.Close();
                data.Dispose();
            }
        }         private void OnProgressChanged()
        {
            double progress = send / (double)(data.Length);
            keyframe_rect.Value = (double)progress * 270;
            txbPrecent.Text = (send / 1024 / 1024).ToString("0.0").Replace(".0", "") + "MB " + (progress * 100).ToString("0.0").Replace(".0", "") + "%";
            Storyboard1.Begin();
        }
 
本站文章除注明转载外,均为本站原创或翻译
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:慧都控件网 [http://www.evget.com/]
本文地址:http://www.evget.com/zh-CN/info/catalog/13498.html

silverlight漂亮的文件上传进度显示原理及示例的更多相关文章

  1. servlet上传文件+上传进度显示

    效果图 功能描述 1.使用jquery.form.js实现异步上传功能,并显示上传进度 2.servlet中保存上传的文件到指定文件夹 3.查看已经上传的文件 4.不同文件类型用不同图标显示 下载 h ...

  2. 阿里云 oss 小文件上传进度显示

    对阿里云OSS上传小文件时的进度,想过两个方法:一是.通过多线程监測Inputstream剩余的字节数来计算,可是由于Inputstream在两个线程中共用,假设上传线程将Inputstream关闭, ...

  3. Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现)(转)

    Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现) 相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦 ...

  4. 【原创】用JAVA实现大文件上传及显示进度信息

    用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 (本文提供全部源码下载,请访问 https://github.com/grayprince/UploadBigFil ...

  5. 使用element UI el-upload组件实现视频文件上传及上传进度显示方法总结

    实现效果: 上传中: 上传完成: 代码: <el-form-item label="视频上传" prop="Video"> <!-- acti ...

  6. HTML5矢量实现文件上传进度条

    在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传.上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5文件 ...

  7. 基于HT for Web矢量实现HTML5文件上传进度条

    在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传.上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5文件 ...

  8. PHP中使用Session配合Javascript实现文件上传进度条功能

    Web应用中常需要提供文件上传的功能.典型的场景包括用户头像上传.相册图片上传等.当需要上传的文件比较大的时候,提供一个显示上传进度的进度条就很有必要了. 在PHP .4以前,实现这样的进度条并不容易 ...

  9. Web---文件上传-用apache的工具处理、打散目录、简单文件上传进度

    我们需要先准备好2个apache的类: 上一个博客文章只讲了最简单的入门,现在来开始慢慢加深. 先过渡一下:只上传一个file项 index.jsp: <h2>用apache的工具处理文件 ...

随机推荐

  1. HA架构

    HA架构是个什么东西? 阅读文章:浅谈web应用的负载均衡.集群.高可用(HA)解决方案

  2. java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案

    Service层的接口中有一些比较常用方法,一次又一次的在新的Service层中被书写,所以懒惰的程序员又烦了,他们决定写个通用接口来解决这个问题. 有些项目中,实体类即承担接收表单数据的任务,又承担 ...

  3. POJ3150:Cellular Automaton

    题意看不懂加题目想不通,很菜. n<=500个数围城环,每次操作对每个数Ai把与i在环上相距不超过d<n/2(包括Ai)的数加起来取模m<=1e6,求K<=1e7次操作后的环. ...

  4. Java操作XML牛逼利器JDOM&DOM4J

    JDOM  JDOM 是一种使用 XML(标准通用标记语言下的一个子集) 的独特 Java 工具包,用于快速开发 XML 应用 程序. JDOM 官方网站:http://www.jdom.org/ 利 ...

  5. poj 3041——Asteroids

    poj       3041——Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22604   Accep ...

  6. 寒武纪camp Day3

    补题进度:9/10 A(多项式) 题意: 在一个长度为n=262144的环上,一个人站在0点上,每一秒钟有$\frac{1}{2}$的概率待在原地不动,有$\frac{1}{4}$的概率向前走一步,有 ...

  7. Eclipse中Maven运行项目时在Console中无日志出现的问题解决

    这是由于工作空间损坏造成的,比如重装JDK后,或者重装Maven后这些问题.解决方法如下: 1.删除现有工作空间,重新选择一个新的. 2.重置Workspece. 3.可能是Maven版本太新导致的, ...

  8. Java泛型的主要用途

    1.泛型的主要用途就是代替各种类型,作为一个笼统的整体类型代替,也就是代替参数,不论是传入参数还是返回参数.都可以用泛型来代替. 如dao操作类的增删改查操作,因为传入参数的类型不同,但基本都是相同接 ...

  9. java比较两个日期大小

    方法一 /** * 比较两个日期之间的大小 * * @param d1 * @param d2 * @return 前者大于后者返回true 反之false */ public boolean com ...

  10. 学习swift从青铜到王者之Swift控制语句04

    1 if语句基本用法 if boolean_expression { /* 如果布尔表达式为真将执行的语句 */ } 如果布尔表达式为 true,则 if 语句内的代码块将被执行.如果布尔表达式为 f ...