zoukankan      html  css  js  c++  java
  • 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_ElearingRescSynUpFilesSCROM/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();
            }
        }
    }
  • 相关阅读:
    移动端布局四: rem适配布局,em和rem介绍,媒体查询显示不同样式,媒体查询调用不同css样式
    移动端布局三: flex布局
    InnoDB存储引擎 (第4章 表)
    InnoDB存储引擎 (第3章 文件)
    《MySQL技术内幕:InnoDB存储引擎》笔记
    InnoDB存储引擎 (第2章 InnoDB存储引擎)
    InnoDB存储引擎 (第1章 MySQL体系结构和存储引擎)
    MySql 技术内幕 (第10章 分区)
    MySql 技术内幕 (第9章 索引)
    MySql 技术内幕 (第6章 聚合和旋转操作)
  • 原文地址:https://www.cnblogs.com/happygx/p/3393973.html
Copyright © 2011-2022 走看看