http://www.cnblogs.com/happygx/archive/2013/10/29/3393973.htmlhtml
WCF傳輸文件的時候能夠設置每次文件的傳輸大小,若是是小文件的時候,能夠很方便的將文件傳遞到服務端,可是若是文件比較大的話,就不可取了數據庫
遇到大文件的話能夠採起分段傳輸的方式進行文件傳輸服務器
思路:多線程
一、客戶端循環傳遞併發
二、將文件分割成指定大小的字節塊app
三、每次傳輸一小塊後,客戶端將當前文件的讀取指針移動到指定位置函數
四、服務端每次依照傳遞過來的字節文件追加post
問題:假設文件有好幾個G大小,按照上述方式進行文件傳輸,當文件傳遞到99%的時候忽然因爲客觀緣由而形成文件傳輸失敗,直接會形成服務器已經上傳的文件不可用,必須從新上傳this
解決方案:url
能夠採起斷點續傳的模式
一、當服務器第一次傳輸文件的時候,能夠先經過服務檢查服務器上是否已經存在當前文件,若是存在則返回服務器上文件的最大指針位置,若是不存在則默認爲0
二、判斷服務器指針最大位置是否大於等於當前文件指針位置;若是大於等於,則文件已經存在
a)大於等於:因爲每次上傳的文件字節數是固定的,假設傳遞到最後一塊,本地文件小於要求的傳遞數量,服務端仍是按照規定大小的字節數進行寫文件
二、客戶端拿到服務器上返回的文件指針位置後,循環發送文件開始,將讀取文件指針直接移動到服務器返回的文件指針位置
文件傳輸案例:
一、能夠斷點續傳
二、同時傳輸多臺服務器
三、顯示計算當前文件的上傳速度
四、傳遞完成後文件自動解壓
一:客戶端服務鏈接
//同時存在多臺服務器 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> /// 初始化計數器 /// 一、二、三、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、照片;一、SCROM文件;二、三分屏文件</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">上傳文件類型一、SCROM課程 二、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">上傳文件類型一、SCROM課程 二、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、照片;一、SCROM文件;二、三分屏文件</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">上傳文件類型一、SCROM課程 二、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">上傳文件類型一、SCROM課程 二、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(); } } }