zoukankan      html  css  js  c++  java
  • 借助WebService实现多线程上传文件

    WebService的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。

     

    首先说说服务器端,只需要提供一个能允许多线程写文件的函数即可,具体代码如下。

    [WebMethod]

    public bool UploadFileData( string FileName, int StartPosition, byte[] bData )

    {

        string strFullName = Server.MapPath( "Uploads" ) + @""" + FileName;

        FileStream fs = null;

        try

        {

            fs = new FileStream( strFullName, FileMode.OpenOrCreate,

                FileAccess.Write, FileShare.Write );

        }

        catch( IOException err )

        {

            Session["ErrorMessage"] = err.Message;

            return false;

        }

        using( fs )

        {

            fs.Position = StartPosition;

            fs.Write( bData, 0, bData.Length );

        }

        return true;

    }

     

    其中“Uploads”是在服务程序所在目录下的一个子目录,需要设置ASPNET用户对此目录具有可写权限。

     

    相对于服务器端来说,客户端要稍微复杂一些,因为要牵扯到多线程的问题。为了更好的传递参数,我用一个线程类来完成。具体如下。

        public delegate void UploadFileData( string FileName, int StartPos, byte[] bData );

        ///<summary>

        /// FileThread: a class for sub-thread

        ///</summary>

        sealed class FileThread

        {

            private int nStartPos;

            private int nTotalBytes;

            private string strFileName;

            public static UploadFileData UploadHandle;

            ///<summary>

            /// Constructor

            ///</summary>

            ///<param name="StartPos"></param>

            ///<param name="TotalBytes"></param>

            ///<param name="FileName"></param>

            public FileThread( int StartPos, int TotalBytes, string FileName )

            {

                //Init thread variant

                nStartPos = StartPos;

                nTotalBytes = TotalBytes;

                strFileName = FileName;

                //Only for debug

                Debug.WriteLine( string.Format( "File name:{0} position: {1} total byte:{2}",

                    strFileName, nStartPos, nTotalBytes ) );

            }

            ///<summary>

            /// Sub-thread entry function

            ///</summary>

            ///<param name="stateinfo"></param>

            public void UploadFile( object stateinfo )

            {

                int nRealRead, nBufferSize;

                const int BUFFER_SIZE = 10240;

                using( FileStream fs = new FileStream( strFileName,

                           FileMode.Open, FileAccess.Read,

                           FileShare.Read ) )

                {

                    string sName = strFileName.Substring( strFileName.LastIndexOf( """" ) + 1 );

                    byte[] bBuffer = new byte[BUFFER_SIZE];//Init 10k buffer

                    fs.Position = nStartPos;

                    nRealRead = 0;

                    do

                    {

                        nBufferSize = BUFFER_SIZE;

                        if( nRealRead + BUFFER_SIZE > nTotalBytes )

                            nBufferSize = nTotalBytes - nRealRead;

                        nBufferSize = fs.Read( bBuffer, 0, nBufferSize );

                        if( nBufferSize == BUFFER_SIZE )

                            UploadHandle( sName,

                                nRealRead + nStartPos,

                                bBuffer );

                        else if( nBufferSize > 0 )

                        {

                            //Copy data

                            byte[] bytData = new byte[nBufferSize];

                            Array.Copy( bBuffer,0, bytData, 0, nBufferSize );

                            UploadHandle( sName,

                                nRealRead + nStartPos,

                                bytData );

                        }

                        nRealRead += nBufferSize;

                    }

                    while( nRealRead < nTotalBytes );

                }

                //Release signal

                ManualResetEvent mr = stateinfo as ManualResetEvent;

                if( mr != null )

                    mr.Set();

            }

        }

     

    那么在执行的时候,要创建线程类对象,并为每一个每个线程设置一个信号量,从而能在所有线程都结束的时候得到通知,大致的代码如下。

        FileInfo fi = new FileInfo( txtFileName.Text );

        if( fi.Exists )

        {

            btnUpload.Enabled = false;//Avoid upload twice

            //Init signals

            ManualResetEvent[] events = new ManualResetEvent[5];

            //Devide blocks

            int nTotalBytes = (int)( fi.Length / 5 );

            forint i = 0; i < 5; i++ )

            {

                events[i] = new ManualResetEvent( false );

                FileThread thdSub = new FileThread(

                    i * nTotalBytes,

                    ( fi.Length - i * nTotalBytes ) > nTotalBytes ? nTotalBytes:(int)( fi.Length - i * nTotalBytes ),

                    fi.FullName );

                ThreadPool.QueueUserWorkItem( new WaitCallback( thdSub.UploadFile ), events[i] );

            }

            //Wait for threads finished

            WaitHandle.WaitAll( events );

            //Reset button status

            btnUpload.Enabled = true;

        }

     

    总体来说,程序还是相对比较简单,而我也只是做了个简单例子而已,一些细节都没有进行处理。

     

    本来想打包提供给大家下载,没想到CSDNBlog对于这点做的太差,老是异常。

     

    如下是客户端的完整代码。

     

    //--------------------------- Multi-thread Upload Demo ---------------------------------------

     

    //--------------------------------------------------------------------------------------------

     

    //---File:          frmUpload

     

    //---Description:   The multi-thread upload form file to demenstrate howto use multi-thread to

     

    //                  upload files

     

    //---Author:        Knight

     

    //---Date:          Oct.12, 2006

     

    //--------------------------------------------------------------------------------------------

     

    //---------------------------{Multi-thread Upload Demo}---------------------------------------

     

    using System;

     

    using System.Drawing;

     

    using System.Collections;

     

    using System.ComponentModel;

     

    using System.Windows.Forms;

     

    using System.Data;

     

    namespace CSUpload

     

    {

     

        using System.IO;

     

        using System.Diagnostics;

     

        using System.Threading;

     

        using WSUploadFile;//Web-service reference namespace

     

        ///<summary>

     

        /// Summary description for Form1.

     

        ///</summary>

     

        public class frmUpload : System.Windows.Forms.Form

     

        {

     

            private System.Windows.Forms.TextBox txtFileName;

     

            private System.Windows.Forms.Button btnBrowse;

     

            private System.Windows.Forms.Button btnUpload;

     

            ///<summary>

     

            /// Required designer variable.

     

            ///</summary>

     

            private System.ComponentModel.Container components = null;

     

            public frmUpload()

     

            {

     

                //

     

                // Required for Windows Form Designer support

     

                //

     

                InitializeComponent();

     

                //

     

                // TODO: Add any constructor code after InitializeComponent call

     

                //

     

            }

     

            ///<summary>

     

            /// Clean up any resources being used.

     

            ///</summary>

     

            protected override void Dispose( bool disposing )

     

            {

     

                if( disposing )

     

                {

     

                    if (components != null)

     

                    {

     

                        components.Dispose();

     

                    }

     

                }

     

                base.Dispose( disposing );

     

            }

     

            #region Windows Form Designer generated code

     

            ///<summary>

     

            /// Required method for Designer support - do not modify

     

            /// the contents of this method with the code editor.

     

            ///</summary>

     

            private void InitializeComponent()

     

            {

     

                this.txtFileName = new System.Windows.Forms.TextBox();

     

                this.btnBrowse = new System.Windows.Forms.Button();

     

                this.btnUpload = new System.Windows.Forms.Button();

     

                this.SuspendLayout();

     

                //

     

                // txtFileName

     

                //

     

                this.txtFileName.Location = new System.Drawing.Point(16, 24);

     

                this.txtFileName.Name = "txtFileName";

     

                this.txtFileName.Size = new System.Drawing.Size(248, 20);

     

                this.txtFileName.TabIndex = 0;

     

                this.txtFileName.Text = "";

     

                //

     

                // btnBrowse

     

                //

     

                this.btnBrowse.Location = new System.Drawing.Point(272, 24);

     

                this.btnBrowse.Name = "btnBrowse";

     

                this.btnBrowse.TabIndex = 1;

     

                this.btnBrowse.Text = "&Browse...";

     

                this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);

     

                //

     

                // btnUpload

     

                //

     

                this.btnUpload.Location = new System.Drawing.Point(272, 56);

     

                this.btnUpload.Name = "btnUpload";

     

                this.btnUpload.TabIndex = 2;

     

                this.btnUpload.Text = "&Upload";

     

                this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click);

     

                //

     

                // frmUpload

     

                //

     

                this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

     

                this.ClientSize = new System.Drawing.Size(370, 111);

     

                this.Controls.Add(this.btnUpload);

     

                this.Controls.Add(this.btnBrowse);

     

                this.Controls.Add(this.txtFileName);

     

                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;

     

                this.MaximizeBox = false;

     

                this.Name = "frmUpload";

     

                this.Text = "Upload";

     

                this.Load += new System.EventHandler(this.frmUpload_Load);

     

                this.ResumeLayout(false);

     

            }

     

            #endregion

     

            ///<summary>

     

            /// The main entry point for the application.

     

            ///</summary>

     

            static void Main()

     

            {

     

                Application.Run(new frmUpload());

     

            }

     

            private FileUpload myUpload = new FileUpload();

     

            private void UploadData( string FileName, int StartPos, byte[] bData )

     

            {

     

                //Call web service upload

     

                myUpload.UploadFileData( FileName, StartPos, bData );

     

            }

     

            private void btnUpload_Click(object sender, System.EventArgs e)

     

            {

     

                FileInfo fi = new FileInfo( txtFileName.Text );

     

                if( fi.Exists )

     

                {

     

                    btnUpload.Enabled = false;//Avoid upload twice

     

                    //Init signals

     

                    ManualResetEvent[] events = new ManualResetEvent[5];

     

                    //Devide blocks

     

                    int nTotalBytes = (int)( fi.Length / 5 );

     

                    forint i = 0; i < 5; i++ )

     

                    {

     

                        events[i] = new ManualResetEvent( false );

     

                        FileThread thdSub = new FileThread(

     

                            i * nTotalBytes,

     

                            ( fi.Length - i * nTotalBytes ) > nTotalBytes ? nTotalBytes:(int)( fi.Length - i * nTotalBytes ),

     

                            fi.FullName );

     

                        ThreadPool.QueueUserWorkItem( new WaitCallback( thdSub.UploadFile ), events[i] );

     

                    }

     

                    //Wait for threads finished

     

                    WaitHandle.WaitAll( events );

     

                    //Reset button status

     

                    btnUpload.Enabled = true;

     

                }

     

           

     

            }

     

            private void frmUpload_Load(object sender, System.EventArgs e)

     

            {

     

                FileThread.UploadHandle = new UploadFileData( this.UploadData );

     

            }

     

            private void btnBrowse_Click(object sender, System.EventArgs e)

     

            {

     

                if( fileOpen.ShowDialog() == DialogResult.OK )

     

                    txtFileName.Text = fileOpen.FileName;

     

            }

     

            private OpenFileDialog fileOpen = new OpenFileDialog();

     

           

     

        }

     

        public delegate void UploadFileData( string FileName, int StartPos, byte[] bData );

     

        ///<summary>

     

        /// FileThread: a class for sub-thread

     

        ///</summary>

     

        sealed class FileThread

     

        {

     

            private int nStartPos;

     

            private int nTotalBytes;

     

            private string strFileName;

     

            public static UploadFileData UploadHandle;

     

            ///<summary>

     

            /// Constructor

     

            ///</summary>

     

            ///<param name="StartPos"></param>

     

            ///<param name="TotalBytes"></param>

     

            ///<param name="FileName"></param>

     

            public FileThread( int StartPos, int TotalBytes, string FileName )

     

            {

     

                //Init thread variant

     

                nStartPos = StartPos;

     

                nTotalBytes = TotalBytes;

     

                strFileName = FileName;

     

                //Only for debug

     

                Debug.WriteLine( string.Format( "File name:{0} position: {1} total byte:{2}",

     

                    strFileName, nStartPos, nTotalBytes ) );

     

            }

     

            ///<summary>

     

            /// Sub-thread entry function

     

            ///</summary>

     

            ///<param name="stateinfo"></param>

     

            public void UploadFile( object stateinfo )

     

            {

     

                int nRealRead, nBufferSize;

     

                const int BUFFER_SIZE = 10240;

     

                using( FileStream fs = new FileStream( strFileName,

     

                           FileMode.Open, FileAccess.Read,

     

                           FileShare.Read ) )

     

                {

     

                    string sName = strFileName.Substring( strFileName.LastIndexOf( """" ) + 1 );

     

                    byte[] bBuffer = new byte[BUFFER_SIZE];//Init 10k buffer

     

                    fs.Position = nStartPos;

     

                    nRealRead = 0;

     

                    do

     

                    {

     

                        nBufferSize = BUFFER_SIZE;

     

                        if( nRealRead + BUFFER_SIZE > nTotalBytes )

     

                            nBufferSize = nTotalBytes - nRealRead;

     

                        nBufferSize = fs.Read( bBuffer, 0, nBufferSize );

     

                        if( nBufferSize == BUFFER_SIZE )

     

                            UploadHandle( sName,

     

                                nRealRead + nStartPos,

     

                                bBuffer );

     

                        else if( nBufferSize > 0 )

     

                        {

     

                            //Copy data

     

                            byte[] bytData = new byte[nBufferSize];

     

                            Array.Copy( bBuffer,0, bytData, 0, nBufferSize );

     

                            UploadHandle( sName,

     

                                nRealRead + nStartPos,

     

                                bytData );

     

                        }

     

                        nRealRead += nBufferSize;

     

                    }

     

                    while( nRealRead < nTotalBytes );

     

                }

     

                //Release signal

     

                ManualResetEvent mr = stateinfo as ManualResetEvent;

     

                if( mr != null )

     

                    mr.Set();

     

            }

     

        }

     

    }

     

  • 相关阅读:
    PythonStudy——数据类型总结 Data type summary
    PythonStudy——可变与不可变 Variable and immutable
    PythonStudy——列表操作 List operatio
    PythonStudy——列表的常用操作 List of common operations
    PythonStudy——列表类型 List type
    PythonStudy——字符串扩展方法 String extension method
    PythonStudy——字符串重要方法 String important method
    AWT,Swing,RCP 开发
    JQuery插件机制
    最新知识网站
  • 原文地址:https://www.cnblogs.com/zhwl/p/2392064.html
Copyright © 2011-2022 走看看