WCF传输文件的时候可以设置每次文件的传输大小,如果是小文件的时候,可以很方便的将文件传递到服务端,但是如果文件比较大的话,就不可取了
遇到大文件的话可以采取分段传输的方式进行文件传输
思路:
1、客户端循环传递
2、将文件分割成指定大小的字节块
3、每次传输一小块后,客户端将当前文件的读取指针移动到指定位置
4、服务端每次依照传递过来的字节文件追加
问题:假设文件有好几个G大小,按照上述方式进行文件传输,当文件传递到99%的时候突然由于客观原因而造成文件传输失败,直接会造成服务器已经上传的文件不可用,必须重新上传
解决方案:
可以采取断点续传的模式
1、当服务器第一次传输文件的时候,可以先通过服务检查服务器上是否已经存在当前文件,如果存在则返回服务器上文件的最大指针位置,如果不存在则默认为0
2、判断服务器指针最大位置是否大于等于当前文件指针位置;如果大于等于,则文件已经存在
a)大于等于:由于每次上传的文件字节数是固定的,假设传递到最后一块,本地文件小于要求的传递数量,服务端还是按照规定大小的字节数进行写文件
2、客户端拿到服务器上返回的文件指针位置后,循环发送文件开始,将读取文件指针直接移动到服务器返回的文件指针位置
文件传输案例:
1、可以断点续传
2、同时传输多台服务器
3、显示计算当前文件的上传速度
4、传递完成后文件自动解压
一:客户端服务连接
//同时存在多台服务器 string[] SynServiceAddress = ConfigurationSettings.AppSettings["IpAddress"].ToString().Split('|'); SynFilesContract.Course.SynCustomServerFileInfo cusSelectPath = new SynFilesContract.Course.SynCustomServerFileInfo(new FileInfo(ServicePath)); ChannelFactory<SynFilesContract.SynIFileServicesInterface> duplexChannelFactory = null; string ServiceFileName = "\\" + fileName; for (int i = 0; i < SynServiceAddress.Length; i++) { string ServiceIP = SynServiceAddress[i]; if (ServiceIP != "") { ServiceIP = ServiceIP + "/Design_Time_Addresses/SynFilesContract/Service1/"; EndpointAddress address = new EndpointAddress(ServiceIP); //设置传输类型协议 WSHttpBinding binding = new WSHttpBinding(); //设置协议属性 binding.Security.Mode = System.ServiceModel.SecurityMode.None; binding.MaxReceivedMessageSize = 2147483647; binding.ReaderQuotas = new XmlDictionaryReaderQuotas() { MaxStringContentLength = 2147483647 }; binding.SendTimeout = TimeSpan.Parse("00:10:00"); binding.CloseTimeout = TimeSpan.Parse("12:00:00"); binding.ReceiveTimeout = TimeSpan.Parse("23:10:00"); binding.OpenTimeout = TimeSpan.Parse("00:01:00"); binding.ReliableSession.Enabled = false; binding.ReliableSession.InactivityTimeout = TimeSpan.Parse("23:10:00"); binding.MessageEncoding = WSMessageEncoding.Mtom; duplexChannelFactory = new ChannelFactory<SynFilesContract.SynIFileServicesInterface>(binding, address); binding.MessageEncoding = WSMessageEncoding.Mtom; ServiceThrottlingBehavior Behavior = new ServiceThrottlingBehavior(); //限流与PerCall MaxConcurrentCalls与MaxConcurrentInstances控制每个服务的吞吐量 int CallsNum = 1000; int InstancesNum = 1000; int SessionNum = 1000; try { CallsNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentCalls"].ToString()); } catch { } try { InstancesNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentInstances"].ToString()); } catch { } try { SessionNum = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentSessions"].ToString()); } catch { } //最大并发调用 Behavior.MaxConcurrentCalls = CallsNum; //最大并发实例 Behavior.MaxConcurrentInstances = InstancesNum; //最大并发会话 Behavior.MaxConcurrentSessions = SessionNum; FileUpload fileUpload = new FileUpload(cusSelectPath, duplexChannelFactory, ServiceFileName, UserId, CourseType, ServiceIP, CoursePathNow); //针对传递不同的服务器启用多线程传输 Thread thread = new Thread(fileUpload.Start); thread.Start(); //添加文件服务器上传路径 /// <summary> /// 文件服务器同步记录 /// </summary> /// <param name="fileName">文件名称</param> /// <param name="ServicePath">文件在服务器的IP地址</param> /// <param name="FileType">处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传</param> /// <param name="inThread">发送给其他文件服务器启用的线程</param> /// <param name="userId">用户ID(解压压缩文件同步时用到)</param> /// <param name="courseType">上传的文件类型</param> /// <param name="CoursePathNow">上传到文件服务器的地址</param> fileUpload.AddFilePercent(fileName, cusSelectPath.FullName, CourseType, ServiceIP, thread, CoursePathNow);
构造函数:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Configuration; using System.ServiceModel.Channels; using System.ServiceModel; using System.Threading; using System.Net; using System.Net.Sockets; using System.Xml.Linq; using ICSharpCode.SharpZipLib.Zip; namespace FileServicesBLLContract.Common { public delegate void OnDownPosChanage(int pos, long speed); public delegate void OnDownOver(); public enum MakeFileType { Down, Upload } public class FileUpload { /// <summary> /// 线程的集合 /// </summary> public List<Thread> list = new List<Thread>(); /// <summary> /// 计数器 /// </summary> public static List<int> listCertificateContract = listCertificate(); /// <summary> /// 初始化计数器 /// 1、2、3、4分别代表不同的处理服务器 /// </summary> /// <returns></returns> private static List<int> listCertificate() { List<int> listCertificate = new List<int>(); listCertificate.Add(1); listCertificate.Add(2); listCertificate.Add(3); listCertificate.Add(4); return listCertificate; } public event OnDownPosChanage OnChange = null; public event OnDownOver OnDownOver = null; public int DowPrcet = 0; public struct DownInfo { public MakeFileType MakeFileType; public SynFilesContract.SynIFileServicesInterface Contract; public SynFilesContract.Course.SynCustomServerFileInfo CurrentFileInfo; public long offset; } public DownInfo CurrentDownInfo = new DownInfo(); //文件名称 public string LocalFileName = string.Empty; //文件全路径名 public string LocalFileFullName = string.Empty; //一秒前文件上传速度大小 public long UpdateFileSpeedFirst = 0; //一秒后文件上传大小 public long UpdateFileSpeedEnd = 0; //当前时间 public DateTime dt = DateTime.Now; //一秒后时间 public string EndUploadFileSpeed = ""; //文件服务器文件所在的地址(续传时需要读取改地址) public string ServicePath = ""; //上传到的具体地址 public string CoursePathNow = ""; //上传文件的大小 public long FileLength = 0; public Thread th = null; /// <summary> /// 用户ID /// </summary> string UserId = ""; /// <summary> /// 上传的类型 /// </summary> string CourseType = ""; /// <summary> /// /// </summary> /// <param name="CurretFileInfo"></param> /// <param name="Channel"></param> /// <param name="LocalFileName"></param> /// <param name="userId"></param> /// <param name="courseType"></param> /// <param name="servicePath">文件服务器文件所在的地址,续传有值,上传时传入""</param> public FileUpload(SynFilesContract.Course.SynCustomServerFileInfo CurretFileInfo, ChannelFactory<SynFilesContract.SynIFileServicesInterface> Channel, string LocalFileName, string userId, string courseType, string servicePath, string coursePathNow) { CoursePathNow = coursePathNow; ServicePath = servicePath; UserId = userId; CourseType = courseType; SynFilesContract.SynIFileServicesInterface Contract = Channel.CreateChannel(); CurrentDownInfo.CurrentFileInfo = CurretFileInfo; CurrentDownInfo.Contract = Contract; this.LocalFileName = LocalFileName; this.LocalFileFullName = CurretFileInfo.FullName; } public void Start() { string UrlAddress = ConfigurationManager.AppSettings["UrlAddress"].ToString(); //for (int i = 0; i < UrlAddress.Split('|').Length; i++) //{ Thread thread = new Thread(UploadFile); thread.Start(); //} } /// <summary> /// 上传方法 /// </summary> public void UploadFile() { int UploadF = 0; int UploadXml = 0; string path = ""; string UrlAddress = ConfigurationManager.AppSettings["UrlAddress"].ToString(); path = UrlAddress + CoursePathNow + "\\"; //表示需要续传 //if (ServicePath != "") //{ // path = ServicePath; //} //else //{ // int Url = listCertificateContract[0]; // listCertificateContract.Add(listCertificateContract[0]); // listCertificateContract.RemoveAt(0); // if (Url == 1) // { // path = UrlAddress.Split('|')[0].ToString(); // } // else if (Url == 2) // { // path = UrlAddress.Split('|')[1].ToString(); // } // else if (Url == 3) // { // path = UrlAddress.Split('|')[2].ToString(); // } // else // { // path = UrlAddress.Split('|')[3].ToString(); // } //} //lock (this) //{ EndUploadFileSpeed = dt.AddSeconds(2).ToLongTimeString(); FileStream fs = new FileStream(this.CurrentDownInfo.CurrentFileInfo.FullName, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[102400]; bool result = true; NewFile(path); //初始化查询服务器上面当前文件的字节位置大小 long dataInfo = CurrentDownInfo.Contract.GetFilesLength(this.LocalFileName, path); AutoResetEvent ar = new AutoResetEvent(false); //定位当前文件的续传位置 fs.Position = dataInfo; //用全局变量获取文件的大小,不用每次都读取 //FileLength = fs.Read(buffer, 0, buffer.Length); try { while ((dataInfo = fs.Read(buffer, 0, buffer.Length)) > 0) { ar.Reset(); //开始传输 CurrentDownInfo.Contract.BeginUploadFile(this.LocalFileName, fs.Position - dataInfo, buffer, this.LocalFileFullName, path, fs.Length, new AsyncCallback(delegate(IAsyncResult ra) { try { result = CurrentDownInfo.Contract.EndUploadFile(ra); } catch { result = false; } ar.Set(); }), null); ar.WaitOne(); if (!result) { if (UploadF >= 3) { break; } else { //如果传输完成,则更新文件的传输记录 UploadFile(); } UploadF++; } if (dt.ToLongTimeString() == EndUploadFileSpeed) { EndUploadFileSpeed = dt.AddSeconds(2).ToLongTimeString(); dt = DateTime.Now; //后秒前文件上传速度大小 即当前传输文件的速度 UpdateFileSpeedEnd = ((UpdateFileSpeedFirst - (fs.Length - fs.Position)) / 1024) / 2; //前秒前文件上传速度大小 UpdateFileSpeedFirst = 0; } else { dt = DateTime.Now; if (UpdateFileSpeedFirst == 0) { UpdateFileSpeedFirst = fs.Length - fs.Position; } } CurrentDownInfo.offset = fs.Position; int pos = Convert.ToInt32(CurrentDownInfo.offset * 100 / fs.Length); if (DowPrcet != pos) { DowPrcet = pos; if (OnChange != null) { OnChange(DowPrcet, UpdateFileSpeedEnd); } } if (fs.Position >= fs.Length) { if (UploadXml >= 3) { //文件已经上传完成 //RemoveFilePercent(this.LocalFileName, this.CurrentDownInfo.CurrentFileInfo.FullName, "1", path); break; } else { //fs.Close(); //fs.Dispose(); Thread.Sleep(1000); RemoveFilePercent(this.LocalFileName, this.CurrentDownInfo.CurrentFileInfo.FullName, "1", ServicePath, fs, CoursePathNow); } UploadXml++; } } } catch { } fs.Close(); fs.Dispose(); if (result) { if (OnDownOver != null) { OnDownOver(); } } //} //sw.Stop(); //MessageBox.Show(sw.ElapsedMilliseconds.ToString()); } /// <summary> /// 文件服务器同步记录 /// </summary> /// <param name="fileName">文件名称</param> /// <param name="ServicePath">文件在服务器的IP地址</param> /// <param name="FileType">处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传</param> /// <param name="inThread">发送给其他文件服务器启用的线程</param> /// <param name="userId">用户ID(解压压缩文件同步时用到)</param> /// <param name="courseType">上传的文件类型</param> /// <param name="CoursePathNow">上传到文件服务器的地址</param> public void AddFilePercent(string fileName, string FilePath, string FileType, string ServicePath, Thread inThread, string CoursePathNow) { if (th == null) { th = inThread; } lock (this) { fileName = fileName.Replace("/", "").Replace("\\", ""); //添加XML string userXmlPath = "SynFileXml/SysFile.xml"; if (!Directory.Exists("SynFileXml")) { Directory.CreateDirectory("SynFileXml"); } if (FileType == "2") { XDocument doc = null; //string UrlAddress = ConfigurationManager.AppSettings["IpAddress"].ToString(); if (File.Exists(userXmlPath)) { doc = XDocument.Load(userXmlPath); //为Xml之追加节点, doc.Element("Data").Add( new XElement("Files", new XElement("FileName", fileName), new XElement("UserId", UserId), new XElement("CourseType", CourseType), new XElement("FilePath", FilePath), new XElement("CoursePathNow", CoursePathNow), new XElement("ServicePath", ServicePath))); } else { //已上传 doc = new XDocument(new XElement("Data", new XElement("Files", new XElement("FileName", fileName), new XElement("UserId", UserId), new XElement("CourseType", CourseType), new XElement("FilePath", FilePath), new XElement("CoursePathNow", CoursePathNow), new XElement("ServicePath", ServicePath)))); } doc.Save(userXmlPath); } else { //如果文件存在 //之前已经上传过,应该往现有文件里面添加新的节点数据 if (File.Exists(userXmlPath)) { XDocument doc = XDocument.Load(userXmlPath); var s1 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName && s.Element("ServicePath").Value == ServicePath select s; //如果当前文件上传信息存在 if (s1.Count() > 0) { if (FileType == "1") { //如果文件已经上传完成 s1.Remove(); doc.Save(userXmlPath); } } else { //如果当前文件上传信息不存在,则是新上传的文件,需要添加新的文件节点信息 //为Xml之追加节点, doc.Element("Data").Add( new XElement("Files", new XElement("FileName", fileName), new XElement("UserId", UserId), new XElement("CourseType", CourseType), new XElement("FilePath", FilePath), new XElement("CoursePathNow", CoursePathNow), new XElement("ServicePath", ServicePath))); doc.Save(userXmlPath); } } else { //已上传 XDocument doc = new XDocument(new XElement("Data", new XElement("Files", new XElement("FileName", fileName), new XElement("UserId", UserId), new XElement("CourseType", CourseType), new XElement("FilePath", FilePath), new XElement("CoursePathNow", CoursePathNow), new XElement("ServicePath", ServicePath)))); doc.Save(userXmlPath); } } } } /// <summary> /// 文件服务器同步记录 /// </summary> /// <param name="fileName">文件名称</param> /// <param name="ServicePath">文件服务器的ip地址</param> /// <param name="FileType">处理文件类型,1 文件上传完成、删除Xml文件记录,2,文件正在上传</param> public void RemoveFilePercent(string fileName, string FilePath, string FileType, string ServicePath, FileStream fs, string CoursePathNow) { lock (this) { fileName = fileName.Replace("/", "").Replace("\\", ""); //添加XML string userXmlPath = "SynFileXml/SysFile.xml"; if (!Directory.Exists("SynFileXml")) { Directory.CreateDirectory("SynFileXml"); } //如果文件存在 //之前已经上传过,应该往现有文件里面添加新的节点数据 if (File.Exists(userXmlPath)) { XDocument doc = XDocument.Load(userXmlPath); var s1 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName && s.Element("ServicePath").Value == ServicePath && s.Element("CoursePathNow").Value == CoursePathNow select s; //如果当前文件上传信息存在 if (s1.Count() > 0) { if (FileType == "1") { //如果文件已经上传完成 s1.Remove(); doc.Save(userXmlPath); //上传完成 var s2 = from s in doc.Element("Data").Elements("Files") where s.Element("FileName").Value == fileName select s; if (s2.Count() == 0 || s2 == null) { Thread.Sleep(1000); try { fs.Close(); fs.Dispose(); if (th != null) { th.Abort(); th.Join(); } //解压 2012-09-25 ning if (fileName.Split('.')[1].ToString() == "rar" || fileName.Split('.')[1].ToString() == "zip") { UnZip.UnZipFile(FilePath, FilePath.Substring(0, FilePath.LastIndexOf("\\") + 1) + fileName.Split('.')[0].ToString() + "/"); } Thread.Sleep(1000); //删除文件上传的压缩文件 File.Delete(FilePath); //调用同步文件写入数据库的方法 Thread.Sleep(3000); RescSyn.RescSyn.SynSource(UserId, CourseType); } catch { } } } } else { //如果当前文件上传信息不存在,则是新上传的文件,需要添加新的文件节点信息 //为Xml之追加节点, doc.Element("Data").Add( new XElement("Files", new XElement("FileName", fileName), new XElement("FilePath", FilePath), new XElement("ServicePath", ServicePath))); doc.Save(userXmlPath); } } else { //已上传 XDocument doc = new XDocument(new XElement("Data", new XElement("Files", new XElement("FileName", fileName), new XElement("FilePath", FilePath), new XElement("ServicePath", ServicePath)))); doc.Save(userXmlPath); } } } #region 考试管理服务1 //传入文件地址,如果不存在则创建 /// <summary> /// 文件地址 /// </summary> /// <param name="filePath"></param> public void NewFile(string filePath) { string[] arrS = filePath.Replace("/", "\\").Split('\\'); string path = arrS[0].ToString(); for (int i = 1; i < arrS.Length; i++) { if (arrS[i].ToString() != "") { path += "\\" + arrS[i].ToString(); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } } } #endregion }
三:解压公共方法:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace FileServicesBLLContract.Common { public class UnZip { /// <summary> /// 解压文件 /// </summary> /// <param name="SrcFile">压缩包路径</param> /// <param name="DstFile">要解压的路径</param> public static void UnZipFile(string SrcFile, string DstFile) { string[] FileProperties = new string[2]; FileProperties[0] = SrcFile;//待解压的文件 FileProperties[1] = DstFile;//解压后放置的目标目录 UnZipClass UnZc = new UnZipClass(); UnZc.UnZip(FileProperties); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ICSharpCode.SharpZipLib.Zip; using System.IO; namespace FileServicesBLLContract.Common { public class UnZipClass { public void UnZip(string[] args) { ZipInputStream s = new ZipInputStream(File.OpenRead(args[0])); ZipEntry theEntry; while ((theEntry = s.GetNextEntry()) != null) { string directoryName = Path.GetDirectoryName(args[1]); string fileName = Path.GetFileName(theEntry.Name); //生成解压目录 //Directory.CreateDirectory(directoryName); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } if (fileName != String.Empty) { string filePath = (args[1] + theEntry.Name).Replace(fileName, ""); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } //解压文件到指定的目录 FileStream streamWriter = File.Create((args[1] + theEntry.Name).Replace("'", "")); int size = 2048; byte[] data = new byte[2048]; while (true) { size = s.Read(data, 0, data.Length); if (size > 0) { streamWriter.Write(data, 0, size); } else { break; } } streamWriter.Close(); } } s.Close(); } } }
四:服务端:
服务接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.IO; using SynFilesContract.Course; using ELearning.Model.Course; namespace SynFilesContract { // 注意: 如果更改此处的接口名称 "IContract",也必须更新 App.config 中对 "IContract" 的引用。 [ServiceContract] public interface SynIFileServicesInterface { /// <summary> /// 上传文件 /// </summary> /// <param name="file">文件对象</param> /// <param name="type">上传文件类型 0、照片;1、SCROM文件;2、三分屏文件</param>\ /// <param name="UrlName">课件编号</param> /// /// <param name="UrlName">课程编号</param> /// <returns></returns> [OperationContract] UploadFileInfo UplodaFile(UploadFileInfo file, string Type, string UrlName, string Path); /// <summary> /// 上传文件 /// </summary> /// <param name="strPath">文件名</param> /// <param name="offSet">当前指针</param> /// <param name="intoBuffer">每次上传字节大小</param> /// <param name="UploadType">上传文件类型1、SCROM课程 2、ThreadSreen课程</param> /// <param name="UserId">用户Id</param> /// <param name="PathNow">当前文件上传路径</param> /// <param name="FullName">客户端文件上传路径</param> /// <param name="FileLength">客户端文件原始字节长度</param> /// <returns></returns> [OperationContract] bool UploadFile(string FileName, long offSet, byte[] intoBuffer,string FullName, string Path,long FileLength); [OperationContract(AsyncPattern = true)] IAsyncResult BeginUploadFile(string strPath, long offSet, byte[] intoBuffer, string FullName, string Path,long FileLength, AsyncCallback ra, object state); bool EndUploadFile(IAsyncResult ra); /// <summary> /// 获取文件当前上传的长度 /// </summary> /// <param name="FileName">文件名</param> /// <param name="UploadType">上传文件类型1、SCROM课程 2、ThreadSreen课程</param> /// <param name="UserId">用户Id</param> /// <param name="PathNow">当前文件上传路径</param> /// <returns>长度</returns> [OperationContract] long GetFilesLength(string FileName,string paths); } }
实现:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Configuration; using System.Threading; using ELearning.Model.Course; using ICSharpCode.SharpZipLib.Zip; using System.ServiceModel; using ServicesHelper.Base; namespace SynFilesContract { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] public class SynFileServiceContract : SynIFileServicesInterface { /// <summary> /// 上传文件 /// </summary> /// <param name="file">文件对象</param> /// <param name="type">上传文件类型 0、照片;1、SCROM文件;2、三分屏文件</param>\ /// <param name="UrlName">课件编号</param> /// <param name="UrlName">课程编号</param> /// <returns></returns> public UploadFileInfo UplodaFile(UploadFileInfo file, string Type, string UrlName, string Path) { try { return Course.UploadFile.UplodaFile(file, Type, UrlName, Path); } catch (Exception ex) { WriteLog.WriteErrorLog(ex, "UplodaFile"); return null; } } /// <summary> /// 上传文件 /// </summary> /// <param name="strPath">文件名</param> /// <param name="offSet">当前指针</param> /// <param name="intoBuffer">每次上传字节大小</param> /// <param name="UploadType">上传文件类型1、SCROM课程 2、ThreadSreen课程</param> /// <param name="UserId">用户Id</param> /// <param name="PathNow">当前文件上传路径</param> /// <returns></returns> public bool UploadFile(string FileName, long offSet, byte[] intoBuffer, string FullName, string Paths, long FileLength) { lock (this) { //标准话文件名 FileName = FileName.Replace("/", "").Replace("\\", ""); NewFile(Paths); string Path = Paths + FileName; if (offSet < 0) { offSet = 0; } byte[] buffer = intoBuffer; if (buffer != null) { for (int i = 0; i < 3; i++) { try { FileStream filesStream = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.ReadWrite); // 高兴 9.3 判断文件是否上传完成 ,如果上传完成,则更新上传记录XML //如果没完成 filesStream.Seek(offSet, SeekOrigin.Begin); filesStream.Write(buffer, 0, buffer.Length); filesStream.Flush(); //上传完成 if (filesStream.Length >= FileLength) { filesStream.Close(); filesStream.Dispose(); Thread.Sleep(1000); try { //解压 2012-09-25 ning if (FileName.Split('.')[1].ToString() == "rar" || FileName.Split('.')[1].ToString() == "zip") { //Paths的值格式为E:\New_Elearing\RescSyn\UpFiles\SCROM/flash/ //FileName的值格式为u8_demo.zip UnZip(Paths + FileName, Paths + FileName.Split('.')[0].ToString() + "/"); } File.Delete(Paths + FileName); File.WriteAllText("D://SynOk.txt", Paths + "======" + FileName); } catch (Exception e) { File.WriteAllText("D://SynUnOk.txt", e.Message.ToString()); } //解压 } else { filesStream.Close(); filesStream.Dispose(); } return true; } catch { Thread.Sleep(100); } } } else { } return false; } } public IAsyncResult BeginUploadFile(string strPath, long offSet, byte[] intoBuffer, string FullName, string Path,long FileLength, AsyncCallback ra, object state) { throw new NotImplementedException(); } public bool EndUploadFile(IAsyncResult ra) { throw new NotImplementedException(); } /// <summary> /// 获取文件当前上传的长度 /// </summary> /// <param name="FileName">文件名</param> /// <param name="UploadType">上传文件类型1、SCROM课程 2、ThreadSreen课程</param> /// <param name="UserId">用户Id</param> /// <param name="PathNow">文件上传相对路径</param> /// <returns>长度</returns> public long GetFilesLength(string FileName, string Paths) { //string filePath = ConfigurationSettings.AppSettings["HostFileDirectory"].Trim() + "\\" + FileName; //string filePath = ConfigurationSettings.AppSettings["UploadFilePath"].ToString() + FileName; lock (this) { string filePath = ""; filePath = Paths + FileName.Replace("\\", "").Replace("/",""); if (File.Exists(filePath)) { using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate)) { return fs.Length; } } return 0; } } //传入文件地址,如果不存在则创建 /// <summary> /// 文件地址 /// </summary> /// <param name="filePath"></param> public void NewFile(string filePath) { File.WriteAllText("d://path.txt", filePath); string[] arrS = filePath.Split('\\'); string path = arrS[0].ToString(); for (int i = 1; i < arrS.Length; i++) { if (arrS[i].ToString() != "") { path += "\\" + arrS[i].ToString(); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } } } } /// <summary> /// 解压文件 /// </summary> /// <param name="SrcFile">压缩包路径</param> /// <param name="DstFile">要解压的路径</param> private void UnZip(string SrcFile, string DstFile) { //string SrcFile = @"D:\CM0103.zip"; //string DstFile = @"D:\Temp\"; string[] FileProperties = new string[2]; FileProperties[0] = SrcFile;//待解压的文件 FileProperties[1] = DstFile;//解压后放置的目标目录 UnZipClass UnZc = new UnZipClass(); UnZc.UnZip(FileProperties); } } /// <summary> /// 解压文件类 /// </summary> public class UnZipClass { public void UnZip(string[] args) { ZipInputStream s = new ZipInputStream(File.OpenRead(args[0])); ZipEntry theEntry; while ((theEntry = s.GetNextEntry()) != null) { string directoryName = Path.GetDirectoryName(args[1]); string fileName = Path.GetFileName(theEntry.Name); //生成解压目录 //Directory.CreateDirectory(directoryName); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } if (fileName != String.Empty) { string filePath = (args[1] + theEntry.Name).Replace(fileName, ""); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } //解压文件到指定的目录 FileStream streamWriter = File.Create((args[1] + theEntry.Name).Replace("'","")); int size = 2048; byte[] data = new byte[2048]; while (true) { size = s.Read(data, 0, data.Length); if (size > 0) { streamWriter.Write(data, 0, size); } else { break; } } streamWriter.Close(); } } s.Close(); } } }
相关推荐
该示例,整合了C#文件传输中的SOCKET同步、异步、WCF同步、异步,并分别提供了进度条,以便查看各类传输的效率(SOCKET同步>SOCKET异步>WCF同步>WCF异步)。 运行的时候,需要自己添加一个可供传输的文件。可查看...
C#网络应用编程第三版(人民邮电出版社)课后上机练习实验 实验四 WCF和HTTP文件传输练习 关键技术是使用Stream传输和保存文件。 此代码仅供参考。
在处理大文件传输时,WCF 提供了一种分块传输机制,以解决一次性传输大文件可能导致的性能问题和网络拥塞。本示例将探讨如何在 WCF 中实现大文件的分块传输。 在传统的文件传输中,如果文件过大,一次性传输可能会...
在本项目中,我们主要探讨的是使用C#进行网络编程,特别是通过Windows Communication Foundation (WCF)服务和HTTP协议来实现代理文件传输。WCF是.NET Framework中的一个组件,它提供了一种统一的方式来创建分布式...
在不进行配置调整的情况下,这些限制可能不足以处理大文件传输。例如,最大消息大小默认为65,536字节(64KB),这显然不足以容纳大多数大文件。 要解决这个问题,我们需要修改服务的行为配置(behaviors配置)。在...
例如,选择TCP绑定以支持大文件传输。 ```xml <!-- ... --> ``` **二、远程文件操作** 1. **上传文件**:客户端将文件内容作为字节数组发送到服务端,服务端接收并保存文件。 2. **...
**WCF文件传输详解** Windows Communication Foundation(WCF)是微软.NET Framework中的一项核心服务,用于构建可互操作的、安全的、可靠的分布式应用程序。它为开发者提供了一组丰富的API,用于实现各种通信模式...
- **安全性**:WCF支持多种安全模式,如Transport、Message或TransportWithMessageCredential,确保文件传输过程的安全性。可以设置凭据、加密和消息认证来防止未授权访问。 - **性能**:考虑使用高效的绑定(如...
**C# WCF 文件上传示例详解** C#(C Sharp)是微软开发的一...通过以上步骤,我们可以创建一个高效、可靠的C# WCF文件上传服务,特别是对于处理大文件的场景。这个示例不仅适合初学者学习,也适用于实际项目中的应用。
WPF+WCF做的大文件上传控件,在WPF客户端把大文件分割成二进制数组,每次往服务器上写100K,可断点续传。页面做的比较丑,没认真设计,只为实现功能。另外还有一个Silverlight+WCF版的。
在标题和描述中提到的“WCF实现文件上传与下载”,这是利用WCF服务来处理大文件传输的一个场景。WCF通过定义服务合同和服务实现,允许客户端和服务器之间交换数据。对于文件上传和下载这样的大文件操作,WCF提供了...
WCF大文件断点下载 一个服务端,使用WCF自承载,默认采用了RESF模式,直接提供了HTTP下载,也可以开启NET TCP等其它模式。HTTP下载时,IE是不支持断点续传的,下载软件中,只有网络传送带支持断点续传,其它的软件...
在文件传输的场景下,我们需要定义一个服务契约来声明服务可以接收和发送文件。服务契约由接口定义,其中包含了OperationContract特性标记的方法,这些方法表示可调用的服务操作。 ```csharp [ServiceContract] ...
在实际操作中,文件传输可能会涉及大容量的数据流,因此我们需要考虑效率和性能。WCF提供了流传输模式,允许数据以流的形式传输,减少了内存消耗。此外,为了保证文件传输的安全性,我们还可以启用消息认证、加密和...
1. **WCF 文件传输**: WCF提供了多种方式来处理文件传输。通过定义服务合同和服务行为,我们可以创建一个允许客户端上传文件的服务。在服务端,我们需要创建一个接收文件流的方法,而在客户端则需要创建一个调用该...
- 对于大文件,可以考虑分块上传和下载,避免一次性加载整个文件导致内存压力。还可以利用流处理技术,减少内存占用。 7. **错误处理**: - 在服务端和客户端都需要有适当的异常处理机制,捕获并处理可能出现的...
**RESTful风格的WCF资源文件详解** REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,以简洁、无状态、可缓存的方式进行数据交互。在.NET框架中,WCF(Windows ...
本教程主要探讨了如何利用WCF实现大文件的断点下载功能,这是一个在远程文件传输中非常实用的技术。WCF文件上传服务允许用户在不完整的网络连接情况下继续文件传输,提高了用户体验并降低了数据丢失的风险。 首先,...
通常,我们可以使用`byte[]`数组来传输文件内容,或者使用流(Stream)对象,以支持大文件传输。 - 实现服务:在服务实现类中,这个方法将接收到的文件数据保存到服务端的某个位置,如根目录下。对于优化,可以考虑...
**WCF大文件分段上传下载WinForm技术详解** Windows Communication Foundation(WCF)是微软.NET框架中的一个核心组件,用于构建高度可配置、安全、可靠的服务。在处理大文件时,由于网络传输的限制和内存管理的...