加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

借助WebService实现多线程上传文件

发布时间:2020-12-17 02:38:34 所属栏目:安全 来源:网络整理
导读:在 WebService 的帮助下,进行多线程上传文件是非常简单。因此我只做个简单的例子,那么如果想要实现此功能的朋友,可以在我的基础上进行扩展。 ? 首先说说服务器端,只需要提供一个能允许多线程写文件的函数即可,具体代码如下。 [WebMethod] public bool U

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,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,nBufferSize );

??????????????????? if( nBufferSize == BUFFER_SIZE )

??????????????????????? UploadHandle( sName,

??????????????????????????? nRealRead + nStartPos,

??????????????????????????? bBuffer );

??????????????????? else if( nBufferSize > 0 )

??????????????????? {

??????????????????????? //Copy data

??????????????????????? byte[] bytData = new byte[nBufferSize];

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

?

??????????????????????? UploadHandle( sName,

??????????????????????????? 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 );

??????? for( int 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,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 );

??????????????? for( int 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,

??????????????????????????? bytData );

??????????????????? }

?

??????????????????? nRealRead += nBufferSize;

??????????????? }

??????????????? while( nRealRead < nTotalBytes );

??????????? }

??????????? //Release signal

??????????? ManualResetEvent mr = stateinfo as ManualResetEvent;

??????????? if( mr != null )

??????????????? mr.Set();

??????? }

??? }

?

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读