zoukankan      html  css  js  c++  java
  • silverlight漂亮的文件上传进度显示原理及示例

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

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

    概述:在网站根目录web.config里配置上传文件夹,注意:folder的value要写成windows资源管理器形式例如: uploadaudiochenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为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资源管理器形式例如:
    uploadaudiochenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为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(01) + "&");

                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
  • 相关阅读:
    PDIUSBD12指令
    (转)USB的VID和PID,以及分类(Class,SubClass,Protocol)
    静态测试
    一种循环buffer结构
    RL78 芯片复位指令
    XModem协议
    位反转的最佳算法
    CCP 协议
    AUTOSAR 架构
    HEX 文件格式
  • 原文地址:https://www.cnblogs.com/meimao5211/p/3396628.html
Copyright © 2011-2022 走看看