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)); ChannelFactoryduplexChannelFactory = 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 (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(); //添加文件服务器上传路径 /// /// 文件服务器同步记录 /// /// 文件名称 /// 文件在服务器的IP地址 /// 处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传 /// 发送给其他文件服务器启用的线程 /// 用户ID(解压压缩文件同步时用到) /// 上传的文件类型 /// 上传到文件服务器的地址 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 { ////// 线程的集合 /// public List list = new List (); /// /// 计数器 /// public static List<int> listCertificateContract = listCertificate(); /// /// 初始化计数器 /// 1、2、3、4分别代表不同的处理服务器 /// /// 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; /// /// 用户ID /// string UserId = ""; /// /// 上传的类型 /// string CourseType = ""; /// /// /// /// /// /// /// /// /// 文件服务器文件所在的地址,续传有值,上传时传入"" public FileUpload(SynFilesContract.Course.SynCustomServerFileInfo CurretFileInfo, ChannelFactory 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(); //} } /// /// 上传方法 /// 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()); } /// /// 文件服务器同步记录 /// /// 文件名称 /// 文件在服务器的IP地址 /// 处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传 /// 发送给其他文件服务器启用的线程 /// 用户ID(解压压缩文件同步时用到) /// 上传的文件类型 /// 上传到文件服务器的地址 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); } } } } /// /// 文件服务器同步记录 /// /// 文件名称 /// 文件服务器的ip地址 /// 处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传 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 //传入文件地址,如果不存在则创建 /// /// 文件地址 /// /// 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 { ////// 解压文件 /// /// 压缩包路径 /// 要解压的路径 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 { ////// 上传文件 /// /// 文件对象 /// 上传文件类型 0、照片;1、SCROM文件;2、三分屏文件\ /// 课件编号 /// /// 课程编号 /// [OperationContract] UploadFileInfo UplodaFile(UploadFileInfo file, string Type, string UrlName, string Path); /// /// 上传文件 /// /// 文件名 /// 当前指针 /// 每次上传字节大小 /// 上传文件类型1、SCROM课程 2、ThreadSreen课程 /// 用户Id /// 当前文件上传路径 /// 客户端文件上传路径 /// 客户端文件原始字节长度 /// [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); /// /// 获取文件当前上传的长度 /// /// 文件名 /// 上传文件类型1、SCROM课程 2、ThreadSreen课程 /// 用户Id /// 当前文件上传路径 /// 长度 [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 { ////// 上传文件 /// /// 文件对象 /// 上传文件类型 0、照片;1、SCROM文件;2、三分屏文件\ /// 课件编号 /// 课程编号 /// 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; } } /// /// 上传文件 /// /// 文件名 /// 当前指针 /// 每次上传字节大小 /// 上传文件类型1、SCROM课程 2、ThreadSreen课程 /// 用户Id /// 当前文件上传路径 /// 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(); } /// /// 获取文件当前上传的长度 /// /// 文件名 /// 上传文件类型1、SCROM课程 2、ThreadSreen课程 /// 用户Id /// 文件上传相对路径 /// 长度 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; } } //传入文件地址,如果不存在则创建 /// /// 文件地址 /// /// 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); } } } } /// /// 解压文件 /// /// 压缩包路径 /// 要解压的路径 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); } } /// /// 解压文件类 /// 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(); } } }