WCF大文件传输【转】

http://www.cnblogs.com/happygx/archive/2013/10/29/3393973.html

 

  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();
        }
    }
}

转载于:https://www.cnblogs.com/anorthwolf/p/4097351.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值