`

WCF大文件传输

    博客分类:
  • WCF
WCF 
阅读更多

WCF传输文件的时候可以设置每次文件的传输大小,如果是小文件的时候,可以很方便的将文件传递到服务端,但是如果文件比较大的话,就不可取了

遇到大文件的话可以采取分段传输的方式进行文件传输

思路:

1、客户端循环传递

2、将文件分割成指定大小的字节块

3、每次传输一小块后,客户端将当前文件的读取指针移动到指定位置

4、服务端每次依照传递过来的字节文件追加

问题:假设文件有好几个G大小,按照上述方式进行文件传输,当文件传递到99%的时候突然由于客观原因而造成文件传输失败,直接会造成服务器已经上传的文件不可用,必须重新上传

解决方案:

可以采取断点续传的模式

1、当服务器第一次传输文件的时候,可以先通过服务检查服务器上是否已经存在当前文件,如果存在则返回服务器上文件的最大指针位置,如果不存在则默认为0

2、判断服务器指针最大位置是否大于等于当前文件指针位置;如果大于等于,则文件已经存在

  a)大于等于:由于每次上传的文件字节数是固定的,假设传递到最后一块,本地文件小于要求的传递数量,服务端还是按照规定大小的字节数进行写文件

2、客户端拿到服务器上返回的文件指针位置后,循环发送文件开始,将读取文件指针直接移动到服务器返回的文件指针位置

 

文件传输案例:

1、可以断点续传

2、同时传输多台服务器

3、显示计算当前文件的上传速度

4、传递完成后文件自动解压

一:客户端服务连接

复制代码
 //同时存在多台服务器
                                    string[] SynServiceAddress = ConfigurationSettings.AppSettings["IpAddress"].ToString().Split('|');
                                    SynFilesContract.Course.SynCustomServerFileInfo cusSelectPath = new SynFilesContract.Course.SynCustomServerFileInfo(new FileInfo(ServicePath));
                                    ChannelFactory<SynFilesContract.SynIFileServicesInterface> duplexChannelFactory = null;
                                    string ServiceFileName = "\\" + fileName;
                                    for (int i = 0; i < SynServiceAddress.Length; i++)
                                    {
                                        string ServiceIP = SynServiceAddress[i];
                                        if (ServiceIP != "")
                                        {
                                            ServiceIP = ServiceIP + "/Design_Time_Addresses/SynFilesContract/Service1/";
                                            EndpointAddress address = new EndpointAddress(ServiceIP);

                                            //设置传输类型协议
                                            WSHttpBinding binding = new WSHttpBinding();
                                            //设置协议属性
                                            binding.Security.Mode = System.ServiceModel.SecurityMode.None;
                                            binding.MaxReceivedMessageSize = 2147483647;
                                            binding.ReaderQuotas = new XmlDictionaryReaderQuotas() { MaxStringContentLength = 2147483647 };
                                            binding.SendTimeout = TimeSpan.Parse("00:10:00");
                                            binding.CloseTimeout = TimeSpan.Parse("12:00:00");
                                            binding.ReceiveTimeout = TimeSpan.Parse("23:10:00");
                                            binding.OpenTimeout = TimeSpan.Parse("00:01:00");
                                            binding.ReliableSession.Enabled = false;
                                            binding.ReliableSession.InactivityTimeout = TimeSpan.Parse("23:10:00");
                                            binding.MessageEncoding = WSMessageEncoding.Mtom;
                                            duplexChannelFactory = new ChannelFactory<SynFilesContract.SynIFileServicesInterface>(binding, address);

                                            binding.MessageEncoding = WSMessageEncoding.Mtom;
                                            ServiceThrottlingBehavior Behavior = new ServiceThrottlingBehavior();
                                            //限流与PerCall     MaxConcurrentCalls与MaxConcurrentInstances控制每个服务的吞吐量
                                            int CallsNum = 1000;
                                            int InstancesNum = 1000;
                                            int SessionNum = 1000;
                                            try { CallsNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentCalls"].ToString()); }
                                            catch { }
                                            try { InstancesNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentInstances"].ToString()); }
                                            catch { }
                                            try { SessionNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentSessions"].ToString()); }
                                            catch { }
                                            //最大并发调用  
                                            Behavior.MaxConcurrentCalls = CallsNum;
                                            //最大并发实例
                                            Behavior.MaxConcurrentInstances = InstancesNum;
                                            //最大并发会话
                                            Behavior.MaxConcurrentSessions = SessionNum;

                                            FileUpload fileUpload = new FileUpload(cusSelectPath, duplexChannelFactory, ServiceFileName, UserId, CourseType, ServiceIP, CoursePathNow);
                                            //针对传递不同的服务器启用多线程传输
                                            Thread thread = new Thread(fileUpload.Start);
                                            thread.Start();
                                            //添加文件服务器上传路径
                                            /// <summary>
                                            /// 文件服务器同步记录
                                            /// </summary>
                                            /// <param name="fileName">文件名称</param>
                                            /// <param name="ServicePath">文件在服务器的IP地址</param>
                                            /// <param name="FileType">处理文件类型,1  文件上传完成、删除Xml文件记录,2,文件正在上传</param>
                                            /// <param name="inThread">发送给其他文件服务器启用的线程</param>
                                            /// <param name="userId">用户ID(解压压缩文件同步时用到)</param>
                                            /// <param name="courseType">上传的文件类型</param>
                                            /// <param name="CoursePathNow">上传到文件服务器的地址</param>
                                            fileUpload.AddFilePercent(fileName, cusSelectPath.FullName, CourseType, ServiceIP, thread, CoursePathNow);
复制代码

构造函数:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Xml.Linq;
using ICSharpCode.SharpZipLib.Zip;

namespace FileServicesBLLContract.Common
{

    public delegate void OnDownPosChanage(int pos, long speed);
    public delegate void OnDownOver();
    public enum MakeFileType
    {
        Down,
        Upload
    }
    public class FileUpload
    {
        /// <summary>
        /// 线程的集合
        /// </summary>
        public List<Thread> list = new List<Thread>();
        /// <summary>
        /// 计数器
        /// </summary>
        public static List<int> listCertificateContract = listCertificate();
        /// <summary>
        /// 初始化计数器
        /// 1、2、3、4分别代表不同的处理服务器
        /// </summary>
        /// <returns></returns>
        private static List<int> listCertificate()
        {
            List<int> listCertificate = new List<int>();
            listCertificate.Add(1);
            listCertificate.Add(2);
            listCertificate.Add(3);
            listCertificate.Add(4);
            return listCertificate;
        }

        public event OnDownPosChanage OnChange = null;
        public event OnDownOver OnDownOver = null;
        public int DowPrcet = 0;
        public struct DownInfo
        {
            public MakeFileType MakeFileType;
            public SynFilesContract.SynIFileServicesInterface Contract;
            public SynFilesContract.Course.SynCustomServerFileInfo CurrentFileInfo;
            public long offset;
        }
        public DownInfo CurrentDownInfo = new DownInfo();
        //文件名称
        public string LocalFileName = string.Empty;
        //文件全路径名
        public string LocalFileFullName = string.Empty;
        //一秒前文件上传速度大小
        public long UpdateFileSpeedFirst = 0;
        //一秒后文件上传大小
        public long UpdateFileSpeedEnd = 0;
        //当前时间
        public DateTime dt = DateTime.Now;
        //一秒后时间
        public string EndUploadFileSpeed = "";

        //文件服务器文件所在的地址(续传时需要读取改地址)
        public string ServicePath = "";

        //上传到的具体地址
        public string CoursePathNow = "";

        //上传文件的大小
        public long FileLength = 0;
        public Thread th = null;
        /// <summary>
        /// 用户ID
        /// </summary>
        string UserId = "";
        /// <summary>
        /// 上传的类型
        /// </summary>
        string CourseType = "";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="CurretFileInfo"></param>
        /// <param name="Channel"></param>
        /// <param name="LocalFileName"></param>
        /// <param name="userId"></param>
        /// <param name="courseType"></param>
        /// <param name="servicePath">文件服务器文件所在的地址,续传有值,上传时传入""</param>
        public FileUpload(SynFilesContract.Course.SynCustomServerFileInfo CurretFileInfo, ChannelFactory<SynFilesContract.SynIFileServicesInterface> Channel, string LocalFileName, string userId, string courseType, string servicePath, string coursePathNow)
        {
            CoursePathNow = coursePathNow;
            ServicePath = servicePath;
            UserId = userId;
            CourseType = courseType;
            SynFilesContract.SynIFileServicesInterface Contract = Channel.CreateChannel();
            CurrentDownInfo.CurrentFileInfo = CurretFileInfo;
            CurrentDownInfo.Contract = Contract;
            this.LocalFileName = LocalFileName;
            this.LocalFileFullName = CurretFileInfo.FullName;
        }

        public void Start()
        {
            string UrlAddress = ConfigurationManager.AppSettings["UrlAddress"].ToString();
            //for (int i = 0; i < UrlAddress.Split('|').Length; i++)
            //{
            Thread thread = new Thread(UploadFile);
            thread.Start();
            //}
        }
        /// <summary>
        ///  上传方法
        /// </summary>
        public void UploadFile()
        {
            int UploadF = 0;
            int UploadXml = 0;
            string path = "";
            string UrlAddress = ConfigurationManager.AppSettings["UrlAddress"].ToString();
            path = UrlAddress + CoursePathNow + "\\";
            //表示需要续传
            //if (ServicePath != "")
            //{
            //    path = ServicePath;
            //}
            //else
            //{
            //    int Url = listCertificateContract[0];
            //    listCertificateContract.Add(listCertificateContract[0]);
            //    listCertificateContract.RemoveAt(0);
            //    if (Url == 1)
            //    {
            //        path = UrlAddress.Split('|')[0].ToString();
            //    }
            //    else if (Url == 2)
            //    {
            //        path = UrlAddress.Split('|')[1].ToString();
            //    }
            //    else if (Url == 3)
            //    {
            //        path = UrlAddress.Split('|')[2].ToString();
            //    }
            //    else
            //    {
            //        path = UrlAddress.Split('|')[3].ToString();
            //    }
            //}
            //lock (this)
            //{
            EndUploadFileSpeed = dt.AddSeconds(2).ToLongTimeString();
            FileStream fs = new FileStream(this.CurrentDownInfo.CurrentFileInfo.FullName, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[102400];
            bool result = true;
            NewFile(path);
            //初始化查询服务器上面当前文件的字节位置大小
            long dataInfo = CurrentDownInfo.Contract.GetFilesLength(this.LocalFileName, path);
            AutoResetEvent ar = new AutoResetEvent(false);
            //定位当前文件的续传位置
            fs.Position = dataInfo;
            //用全局变量获取文件的大小,不用每次都读取
            //FileLength = fs.Read(buffer, 0, buffer.Length);
            try
            {
                while ((dataInfo = fs.Read(buffer, 0, buffer.Length)) > 0)
                {

                    ar.Reset();
                    //开始传输
                    CurrentDownInfo.Contract.BeginUploadFile(this.LocalFileName, fs.Position - dataInfo, buffer, this.LocalFileFullName, path, fs.Length,
                          new AsyncCallback(delegate(IAsyncResult ra)
                          {
                              try
                              {
                                  result = CurrentDownInfo.Contract.EndUploadFile(ra);
                              }
                              catch 
                              {
                                  result = false;
                              }
                              ar.Set();
                          }), null);
                    ar.WaitOne();
                    if (!result)
                    {
                        if (UploadF >= 3)
                        {
                            break;
                        }
                        else
                        {
                            //如果传输完成,则更新文件的传输记录
                            UploadFile();
                        }
                        UploadF++;
                    }
                    if (dt.ToLongTimeString() == EndUploadFileSpeed)
                    {
                        EndUploadFileSpeed = dt.AddSeconds(2).ToLongTimeString();
                        dt = DateTime.Now;
                        //后秒前文件上传速度大小  即当前传输文件的速度
                        UpdateFileSpeedEnd = ((UpdateFileSpeedFirst - (fs.Length - fs.Position)) / 1024) / 2;
                        //前秒前文件上传速度大小
                        UpdateFileSpeedFirst = 0;
                    }
                    else
                    {
                        dt = DateTime.Now;
                        if (UpdateFileSpeedFirst == 0)
                        {
                            UpdateFileSpeedFirst = fs.Length - fs.Position;
                        }
                    }
                    CurrentDownInfo.offset = fs.Position;
                    int pos = Convert.ToInt32(CurrentDownInfo.offset * 100 / fs.Length);
                    if (DowPrcet != pos)
                    {
                        DowPrcet = pos;
                        if (OnChange != null)
                        {
                            OnChange(DowPrcet, UpdateFileSpeedEnd);
                        }
                    }
                    if (fs.Position >= fs.Length)
                    {

                        if (UploadXml >= 3)
                        {
                            //文件已经上传完成
                            //RemoveFilePercent(this.LocalFileName, this.CurrentDownInfo.CurrentFileInfo.FullName, "1", path);
                            break;
                        }
                        else
                        {
                            //fs.Close();
                            //fs.Dispose();
                            Thread.Sleep(1000);
                            RemoveFilePercent(this.LocalFileName, this.CurrentDownInfo.CurrentFileInfo.FullName, "1", ServicePath, fs, CoursePathNow);
                        }
                        UploadXml++;
                    }
                }
            }
            catch

            { }

            fs.Close();
            fs.Dispose();
            if (result)
            {
                if (OnDownOver != null)
                {
                    OnDownOver();
                }
            }
            //}
            //sw.Stop();
            //MessageBox.Show(sw.ElapsedMilliseconds.ToString());
        }
        /// <summary>
        /// 文件服务器同步记录
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="ServicePath">文件在服务器的IP地址</param>
        /// <param name="FileType">处理文件类型,1  文件上传完成、删除Xml文件记录,2,文件正在上传</param>
        /// <param name="inThread">发送给其他文件服务器启用的线程</param>
        /// <param name="userId">用户ID(解压压缩文件同步时用到)</param>
        /// <param name="courseType">上传的文件类型</param>
        /// <param name="CoursePathNow">上传到文件服务器的地址</param>
        public void AddFilePercent(string fileName, string FilePath, string FileType, string ServicePath, Thread inThread, string CoursePathNow)
        {

            if (th == null)
            {
                th = inThread;
            }
            lock (this)
            {
                fileName = fileName.Replace("/", "").Replace("\\", "");

                //添加XML
                string userXmlPath = "SynFileXml/SysFile.xml";
                if (!Directory.Exists("SynFileXml"))
                {
                    Directory.CreateDirectory("SynFileXml");
                }

                if (FileType == "2")
                {
                    XDocument doc = null;
                    //string UrlAddress = ConfigurationManager.AppSettings["IpAddress"].ToString();
                    if (File.Exists(userXmlPath))
                    {
                        doc = XDocument.Load(userXmlPath);

                        //为Xml之追加节点,
                        doc.Element("Data").Add(
                            new XElement("Files",
                                new XElement("FileName", fileName),
                                 new XElement("UserId", UserId),
                                new XElement("CourseType", CourseType),
                                new XElement("FilePath", FilePath),
                                new XElement("CoursePathNow", CoursePathNow),
                                new XElement("ServicePath", ServicePath)));
                    }
                    else
                    {

                        //已上传
                        doc = new XDocument(new XElement("Data",
                      new XElement("Files",
                          new XElement("FileName", fileName),
                           new XElement("UserId", UserId),
                           new XElement("CourseType", CourseType),
                          new XElement("FilePath", FilePath),
                          new XElement("CoursePathNow", CoursePathNow),
                          new XElement("ServicePath", ServicePath))));

                    }
                    doc.Save(userXmlPath);
                }
                else
                {
                    //如果文件存在
                    //之前已经上传过,应该往现有文件里面添加新的节点数据
                    if (File.Exists(userXmlPath))
                    {
                        XDocument doc = XDocument.Load(userXmlPath);
                        var s1 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName && s.Element("ServicePath").Value == ServicePath select s;
                        //如果当前文件上传信息存在
                        if (s1.Count() > 0)
                        {
                            if (FileType == "1")
                            {
                                //如果文件已经上传完成
                                s1.Remove();
                                doc.Save(userXmlPath);
                            }

                        }
                        else
                        {
                            //如果当前文件上传信息不存在,则是新上传的文件,需要添加新的文件节点信息
                            //为Xml之追加节点,
                            doc.Element("Data").Add(
                                new XElement("Files",
                                    new XElement("FileName", fileName),
                                    new XElement("UserId", UserId),
                                    new XElement("CourseType", CourseType),
                                    new XElement("FilePath", FilePath),
                                    new XElement("CoursePathNow", CoursePathNow),
                                    new XElement("ServicePath", ServicePath)));
                            doc.Save(userXmlPath);
                        }
                    }
                    else
                    {
                        //已上传
                        XDocument doc = new XDocument(new XElement("Data",
                       new XElement("Files",
                           new XElement("FileName", fileName),
                           new XElement("UserId", UserId),
                           new XElement("CourseType", CourseType),
                           new XElement("FilePath", FilePath),
                           new XElement("CoursePathNow", CoursePathNow),
                           new XElement("ServicePath", ServicePath))));
                        doc.Save(userXmlPath);

                    }
                }
            }
        }



        /// <summary>
        /// 文件服务器同步记录
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="ServicePath">文件服务器的ip地址</param>
        /// <param name="FileType">处理文件类型,1  文件上传完成、删除Xml文件记录,2,文件正在上传</param>
        public void RemoveFilePercent(string fileName, string FilePath, string FileType, string ServicePath, FileStream fs, string CoursePathNow)
        {

            lock (this)
            {
                fileName = fileName.Replace("/", "").Replace("\\", "");

                //添加XML
                string userXmlPath = "SynFileXml/SysFile.xml";
                if (!Directory.Exists("SynFileXml"))
                {
                    Directory.CreateDirectory("SynFileXml");
                }


                //如果文件存在
                //之前已经上传过,应该往现有文件里面添加新的节点数据
                if (File.Exists(userXmlPath))
                {
                    XDocument doc = XDocument.Load(userXmlPath);
                    var s1 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName && s.Element("ServicePath").Value == ServicePath && s.Element("CoursePathNow").Value == CoursePathNow select s;
                    //如果当前文件上传信息存在
                    if (s1.Count() > 0)
                    {
                        if (FileType == "1")
                        {

                            //如果文件已经上传完成
                            s1.Remove();
                            doc.Save(userXmlPath);
                            //上传完成
                            var s2 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName select s;
                            if (s2.Count() == 0 || s2 == null)
                            {
                                Thread.Sleep(1000);
                                try
                                {
                                    fs.Close();
                                    fs.Dispose();
                                    if (th != null)
                                    {
                                        th.Abort();
                                        th.Join();
                                    }
                                    //解压 2012-09-25 ning 
                                    if (fileName.Split('.')[1].ToString() == "rar" || fileName.Split('.')[1].ToString() == "zip")
                                    {
                                        UnZip.UnZipFile(FilePath, FilePath.Substring(0, FilePath.LastIndexOf("\\") + 1) + fileName.Split('.')[0].ToString() + "/");
                                    }
                                    Thread.Sleep(1000);
                                    //删除文件上传的压缩文件
                                    File.Delete(FilePath);
                                    //调用同步文件写入数据库的方法
                                    Thread.Sleep(3000);
                                    RescSyn.RescSyn.SynSource(UserId, CourseType);

                                }
                                catch
                                {

                                }
                            }
                        }

                    }
                    else
                    {
                        //如果当前文件上传信息不存在,则是新上传的文件,需要添加新的文件节点信息
                        //为Xml之追加节点,
                        doc.Element("Data").Add(
                            new XElement("Files",
                                new XElement("FileName", fileName),
                                new XElement("FilePath", FilePath),
                                new XElement("ServicePath", ServicePath)));
                        doc.Save(userXmlPath);
                    }
                }
                else
                {
                    //已上传
                    XDocument doc = new XDocument(new XElement("Data",
                   new XElement("Files",
                       new XElement("FileName", fileName),
                       new XElement("FilePath", FilePath),
                       new XElement("ServicePath", ServicePath))));
                    doc.Save(userXmlPath);

                }

            }
        }
        #region 考试管理服务1


        //传入文件地址,如果不存在则创建
        /// <summary>
        /// 文件地址
        /// </summary>
        /// <param name="filePath"></param>
        public void NewFile(string filePath)
        {
            string[] arrS = filePath.Replace("/", "\\").Split('\\');
            string path = arrS[0].ToString();
            for (int i = 1; i < arrS.Length; i++)
            {
                if (arrS[i].ToString() != "")
                {
                    path += "\\" + arrS[i].ToString();
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                }
            }
        }

    }
        #endregion



   
}
复制代码

三:解压公共方法:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FileServicesBLLContract.Common
{
    public class UnZip
    {
        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="SrcFile">压缩包路径</param>
        /// <param name="DstFile">要解压的路径</param>
        public static void UnZipFile(string SrcFile, string DstFile)
        {
            string[] FileProperties = new string[2];
            FileProperties[0] = SrcFile;//待解压的文件  
            FileProperties[1] = DstFile;//解压后放置的目标目录  
            UnZipClass UnZc = new UnZipClass();
            UnZc.UnZip(FileProperties);

        }
    }
}
复制代码
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;

namespace FileServicesBLLContract.Common
{
   public class UnZipClass
    {
       public void UnZip(string[] args)
       {
           ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));

           ZipEntry theEntry;
           while ((theEntry = s.GetNextEntry()) != null)
           {

               string directoryName = Path.GetDirectoryName(args[1]);
               string fileName = Path.GetFileName(theEntry.Name);

               //生成解压目录  
               //Directory.CreateDirectory(directoryName);

               if (!Directory.Exists(directoryName))
               {
                   Directory.CreateDirectory(directoryName);
               }

               if (fileName != String.Empty)
               {
                   string filePath = (args[1] + theEntry.Name).Replace(fileName, "");
                   if (!Directory.Exists(filePath))
                   {
                       Directory.CreateDirectory(filePath);
                   }
                   //解压文件到指定的目录  
                   FileStream streamWriter = File.Create((args[1] + theEntry.Name).Replace("'", ""));

                   int size = 2048;
                   byte[] data = new byte[2048];
                   while (true)
                   {
                       size = s.Read(data, 0, data.Length);
                       if (size > 0)
                       {
                           streamWriter.Write(data, 0, size);
                       }
                       else
                       {
                           break;
                       }
                   }

                   streamWriter.Close();
               }
           }
           s.Close();
       }
    }
}
复制代码

四:服务端:

服务接口

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
using SynFilesContract.Course;
using ELearning.Model.Course;

namespace SynFilesContract
{
    // 注意: 如果更改此处的接口名称 "IContract",也必须更新 App.config 中对 "IContract" 的引用。
    [ServiceContract]
    public interface SynIFileServicesInterface
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file">文件对象</param>
        /// <param name="type">上传文件类型 0、照片;1、SCROM文件;2、三分屏文件</param>\
        /// <param name="UrlName">课件编号</param>
        /// 
        /// <param name="UrlName">课程编号</param>
        /// <returns></returns>
        [OperationContract]
        UploadFileInfo UplodaFile(UploadFileInfo file, string Type, string UrlName, string Path);




        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="strPath">文件名</param>
        /// <param name="offSet">当前指针</param>
        /// <param name="intoBuffer">每次上传字节大小</param>
        /// <param name="UploadType">上传文件类型1、SCROM课程   2、ThreadSreen课程</param>
        /// <param name="UserId">用户Id</param>
        /// <param name="PathNow">当前文件上传路径</param>
        /// <param name="FullName">客户端文件上传路径</param>
        /// <param name="FileLength">客户端文件原始字节长度</param>
        /// <returns></returns>
        [OperationContract]
        bool UploadFile(string FileName, long offSet, byte[] intoBuffer,string FullName, string Path,long FileLength);
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginUploadFile(string strPath, long offSet, byte[] intoBuffer,  string FullName, string Path,long FileLength, AsyncCallback ra, object state);
        bool EndUploadFile(IAsyncResult ra);

        /// <summary>
        /// 获取文件当前上传的长度
        /// </summary>
        /// <param name="FileName">文件名</param>
        /// <param name="UploadType">上传文件类型1、SCROM课程   2、ThreadSreen课程</param>
        /// <param name="UserId">用户Id</param>
        /// <param name="PathNow">当前文件上传路径</param>
        /// <returns>长度</returns>
        [OperationContract]
        long GetFilesLength(string FileName,string paths);
    }
   
}
复制代码

实现:

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Threading;
using ELearning.Model.Course;
using ICSharpCode.SharpZipLib.Zip;
using System.ServiceModel;
using ServicesHelper.Base;

namespace SynFilesContract
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class SynFileServiceContract : SynIFileServicesInterface
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file">文件对象</param>
        /// <param name="type">上传文件类型 0、照片;1、SCROM文件;2、三分屏文件</param>\
        /// <param name="UrlName">课件编号</param>
        /// <param name="UrlName">课程编号</param>
        /// <returns></returns>

        public UploadFileInfo UplodaFile(UploadFileInfo file, string Type, string UrlName, string Path)
        {
            try
            {
                return Course.UploadFile.UplodaFile(file, Type, UrlName, Path);
            }
            catch (Exception ex)
            {

                WriteLog.WriteErrorLog(ex, "UplodaFile");
                return null;
       
            }
        }


        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="strPath">文件名</param>
        /// <param name="offSet">当前指针</param>
        /// <param name="intoBuffer">每次上传字节大小</param>
        /// <param name="UploadType">上传文件类型1、SCROM课程   2、ThreadSreen课程</param>
        /// <param name="UserId">用户Id</param>
        /// <param name="PathNow">当前文件上传路径</param>
        /// <returns></returns>
        public bool UploadFile(string FileName, long offSet, byte[] intoBuffer, string FullName, string Paths, long FileLength)
        {
            lock (this)
            {
                //标准话文件名
                FileName = FileName.Replace("/", "").Replace("\\", "");
                NewFile(Paths);
                string Path = Paths + FileName;
                if (offSet < 0)
                {
                    offSet = 0;
                }

                byte[] buffer = intoBuffer;

                if (buffer != null)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        try
                        {
                            FileStream filesStream = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                            // 高兴 9.3  判断文件是否上传完成 ,如果上传完成,则更新上传记录XML
                            //如果没完成
                            filesStream.Seek(offSet, SeekOrigin.Begin);
                            filesStream.Write(buffer, 0, buffer.Length);
                            filesStream.Flush();
                            //上传完成
                            if (filesStream.Length >= FileLength)
                            {
                                filesStream.Close();
                                filesStream.Dispose();
                                Thread.Sleep(1000);
                                try
                                {
                                    //解压 2012-09-25 ning 
                                    if (FileName.Split('.')[1].ToString() == "rar" || FileName.Split('.')[1].ToString() == "zip")
                                    {
                                        //Paths的值格式为E:\New_Elearing\RescSyn\UpFiles\SCROM/flash/ 
                                        //FileName的值格式为u8_demo.zip
                                        UnZip(Paths + FileName, Paths + FileName.Split('.')[0].ToString() + "/");
                                    }
                                    File.Delete(Paths + FileName);
                                    File.WriteAllText("D://SynOk.txt", Paths + "======" + FileName);
                                }
                                catch (Exception e)
                                {
                                    File.WriteAllText("D://SynUnOk.txt", e.Message.ToString());
                                }
                                //解压
                            }
                            else
                            {
                                filesStream.Close();
                                filesStream.Dispose();
                            }
                            
                            return true;
                        }
                        catch { Thread.Sleep(100); }
                    }

                }
                else
                {
                }
                return false;
            }
        }
        public IAsyncResult BeginUploadFile(string strPath, long offSet, byte[] intoBuffer, string FullName, string Path,long FileLength, AsyncCallback ra, object state)
        {
            throw new NotImplementedException();
        }
        public bool EndUploadFile(IAsyncResult ra)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 获取文件当前上传的长度
        /// </summary>
        /// <param name="FileName">文件名</param>
        /// <param name="UploadType">上传文件类型1、SCROM课程   2、ThreadSreen课程</param>
        /// <param name="UserId">用户Id</param>
        /// <param name="PathNow">文件上传相对路径</param>
        /// <returns>长度</returns>
        public long GetFilesLength(string FileName, string Paths)
        {
            //string filePath = ConfigurationSettings.AppSettings["HostFileDirectory"].Trim() + "\\" + FileName;
            //string filePath = ConfigurationSettings.AppSettings["UploadFilePath"].ToString() + FileName;
            lock (this)
            {
                string filePath = "";
                filePath = Paths + FileName.Replace("\\", "").Replace("/","");

                if (File.Exists(filePath))
                {
                    using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
                    {
                        return fs.Length;
                    }
                }
                return 0;
            }
        }

        //传入文件地址,如果不存在则创建
        /// <summary>
        /// 文件地址
        /// </summary>
        /// <param name="filePath"></param>
        public void NewFile(string filePath)
        {
            File.WriteAllText("d://path.txt", filePath);
            string[] arrS = filePath.Split('\\');
            string path = arrS[0].ToString();
            for (int i = 1; i < arrS.Length; i++)
            {
                if (arrS[i].ToString() != "")
                {
                    path += "\\" + arrS[i].ToString();
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                }
            }
        }

        /// <summary>
        /// 解压文件
        /// </summary>
        /// <param name="SrcFile">压缩包路径</param>
        /// <param name="DstFile">要解压的路径</param>
        private void UnZip(string SrcFile, string DstFile)
        {
            //string SrcFile = @"D:\CM0103.zip";
            //string DstFile = @"D:\Temp\";
            string[] FileProperties = new string[2];
            FileProperties[0] = SrcFile;//待解压的文件  
            FileProperties[1] = DstFile;//解压后放置的目标目录  
            UnZipClass UnZc = new UnZipClass();
            UnZc.UnZip(FileProperties);

        }

    }

    /// <summary>
    /// 解压文件类
    /// </summary>
    public class UnZipClass
    {
        public void UnZip(string[] args)
        {
            ZipInputStream s = new ZipInputStream(File.OpenRead(args[0]));

            ZipEntry theEntry;
            while ((theEntry = s.GetNextEntry()) != null)
            {

                string directoryName = Path.GetDirectoryName(args[1]);
                string fileName = Path.GetFileName(theEntry.Name);

                //生成解压目录  
                //Directory.CreateDirectory(directoryName);

                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }

                if (fileName != String.Empty)
                {
                    string filePath = (args[1] + theEntry.Name).Replace(fileName, "");
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    //解压文件到指定的目录  
                    FileStream streamWriter = File.Create((args[1] + theEntry.Name).Replace("'",""));

                    int size = 2048;
                    byte[] data = new byte[2048];
                    while (true)
                    {
                        size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }

                    streamWriter.Close();
                }
            }
            s.Close();
        }
    }
}
复制代码

 

分享到:
评论

相关推荐

    C#大文件传输之SOCKET同步、异步、WCF同步、异步

    该示例,整合了C#文件传输中的SOCKET同步、异步、WCF同步、异步,并分别提供了进度条,以便查看各类传输的效率(SOCKET同步&gt;SOCKET异步&gt;WCF同步&gt;WCF异步)。 运行的时候,需要自己添加一个可供传输的文件。可查看...

    C#网络应用编程实验 WCF和HTTP文件传输练习

    C#网络应用编程第三版(人民邮电出版社)课后上机练习实验 实验四 WCF和HTTP文件传输练习 关键技术是使用Stream传输和保存文件。 此代码仅供参考。

    wcf分块传输大文件的例子

    在处理大文件传输时,WCF 提供了一种分块传输机制,以解决一次性传输大文件可能导致的性能问题和网络拥塞。本示例将探讨如何在 WCF 中实现大文件的分块传输。 在传统的文件传输中,如果文件过大,一次性传输可能会...

    C#WCF和HTTP文件传输练习.zip

    在本项目中,我们主要探讨的是使用C#进行网络编程,特别是通过Windows Communication Foundation (WCF)服务和HTTP协议来实现代理文件传输。WCF是.NET Framework中的一个组件,它提供了一种统一的方式来创建分布式...

    WCF 上传大文件的问题

    在不进行配置调整的情况下,这些限制可能不足以处理大文件传输。例如,最大消息大小默认为65,536字节(64KB),这显然不足以容纳大多数大文件。 要解决这个问题,我们需要修改服务的行为配置(behaviors配置)。在...

    WCF 远程文件操作进度显示

    例如,选择TCP绑定以支持大文件传输。 ```xml &lt;!-- ... --&gt; ``` **二、远程文件操作** 1. **上传文件**:客户端将文件内容作为字节数组发送到服务端,服务端接收并保存文件。 2. **...

    WCF文件传输

    **WCF文件传输详解** Windows Communication Foundation(WCF)是微软.NET Framework中的一项核心服务,用于构建可互操作的、安全的、可靠的分布式应用程序。它为开发者提供了一组丰富的API,用于实现各种通信模式...

    WCF实现文件上传

    - **安全性**:WCF支持多种安全模式,如Transport、Message或TransportWithMessageCredential,确保文件传输过程的安全性。可以设置凭据、加密和消息认证来防止未授权访问。 - **性能**:考虑使用高效的绑定(如...

    C#写的WCF文件上传示例

    **C# WCF 文件上传示例详解** C#(C Sharp)是微软开发的一...通过以上步骤,我们可以创建一个高效、可靠的C# WCF文件上传服务,特别是对于处理大文件的场景。这个示例不仅适合初学者学习,也适用于实际项目中的应用。

    WPF+WCF大文件上传控件

    WPF+WCF做的大文件上传控件,在WPF客户端把大文件分割成二进制数组,每次往服务器上写100K,可断点续传。页面做的比较丑,没认真设计,只为实现功能。另外还有一个Silverlight+WCF版的。

    WCF实现文件上传与下载

    在标题和描述中提到的“WCF实现文件上传与下载”,这是利用WCF服务来处理大文件传输的一个场景。WCF通过定义服务合同和服务实现,允许客户端和服务器之间交换数据。对于文件上传和下载这样的大文件操作,WCF提供了...

    WCF大文件断点下载示例

    WCF大文件断点下载 一个服务端,使用WCF自承载,默认采用了RESF模式,直接提供了HTTP下载,也可以开启NET TCP等其它模式。HTTP下载时,IE是不支持断点续传的,下载软件中,只有网络传送带支持断点续传,其它的软件...

    通过wcf实现文件传递

    在文件传输的场景下,我们需要定义一个服务契约来声明服务可以接收和发送文件。服务契约由接口定义,其中包含了OperationContract特性标记的方法,这些方法表示可调用的服务操作。 ```csharp [ServiceContract] ...

    A.4 WCF和HTTP文件传输练习

    在实际操作中,文件传输可能会涉及大容量的数据流,因此我们需要考虑效率和性能。WCF提供了流传输模式,允许数据以流的形式传输,减少了内存消耗。此外,为了保证文件传输的安全性,我们还可以启用消息认证、加密和...

    WCF 实现 文件分段上传、支持多个文件一起处理、Log4Net日志记录

    1. **WCF 文件传输**: WCF提供了多种方式来处理文件传输。通过定义服务合同和服务行为,我们可以创建一个允许客户端上传文件的服务。在服务端,我们需要创建一个接收文件流的方法,而在客户端则需要创建一个调用该...

    WCF 实现文件上传下载

    - 对于大文件,可以考虑分块上传和下载,避免一次性加载整个文件导致内存压力。还可以利用流处理技术,减少内存占用。 7. **错误处理**: - 在服务端和客户端都需要有适当的异常处理机制,捕获并处理可能出现的...

    Rest WCF资源文件

    **RESTful风格的WCF资源文件详解** REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,以简洁、无状态、可缓存的方式进行数据交互。在.NET框架中,WCF(Windows ...

    WCF大文件断点下载.rar_wcf_wcf文件上传_worthsdn_下载_远程下载

    本教程主要探讨了如何利用WCF实现大文件的断点下载功能,这是一个在远程文件传输中非常实用的技术。WCF文件上传服务允许用户在不完整的网络连接情况下继续文件传输,提高了用户体验并降低了数据丢失的风险。 首先,...

    WCF实现文件的上传和下载.zip

    通常,我们可以使用`byte[]`数组来传输文件内容,或者使用流(Stream)对象,以支持大文件传输。 - 实现服务:在服务实现类中,这个方法将接收到的文件数据保存到服务端的某个位置,如根目录下。对于优化,可以考虑...

    WCF大文件分段上传下载winform

    **WCF大文件分段上传下载WinForm技术详解** Windows Communication Foundation(WCF)是微软.NET框架中的一个核心组件,用于构建高度可配置、安全、可靠的服务。在处理大文件时,由于网络传输的限制和内存管理的...

Global site tag (gtag.js) - Google Analytics