WCF大文件传输【转】

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

  WCF传输文件的时候可以设置每次文件的传输大小,如果是小文件的时候,可以很方便的将文件传递到服务端,但是如果文件比较大的话,就不可取了

遇到大文件的话可以采取分段传输的方式进行文件传输

思路:

1、客户端循环传递

2、将文件分割成指定大小的字节块

3、每次传输一小块后,客户端将当前文件的读取指针移动到指定位置

4、服务端每次依照传递过来的字节文件追加

问题:假设文件有好几个G大小,按照上述方式进行文件传输,当文件传递到99%的时候突然由于客观原因而造成文件传输失败,直接会造成服务器已经上传的文件不可用,必须重新上传

解决方案:

可以采取断点续传的模式

1、当服务器第一次传输文件的时候,可以先通过服务检查服务器上是否已经存在当前文件,如果存在则返回服务器上文件的最大指针位置,如果不存在则默认为0

2、判断服务器指针最大位置是否大于等于当前文件指针位置;如果大于等于,则文件已经存在

  a)大于等于:由于每次上传的文件字节数是固定的,假设传递到最后一块,本地文件小于要求的传递数量,服务端还是按照规定大小的字节数进行写文件

2、客户端拿到服务器上返回的文件指针位置后,循环发送文件开始,将读取文件指针直接移动到服务器返回的文件指针位置

文件传输案例:

1、可以断点续传

2、同时传输多台服务器

3、显示计算当前文件的上传速度

4、传递完成后文件自动解压

一:客户端服务连接

WCF大文件传输【转】
 //同时存在多台服务器
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);
WCF大文件传输【转】

构造函数:

WCF大文件传输【转】
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 }
WCF大文件传输【转】

三:解压公共方法:

WCF大文件传输【转】
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); }
}
}
WCF大文件传输【转】
WCF大文件传输【转】
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();
}
}
}
WCF大文件传输【转】

四:服务端:

服务接口

WCF大文件传输【转】
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);
} }
WCF大文件传输【转】

实现:

WCF大文件传输【转】
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();
}
}
}
上一篇:关于python的多行注释,启动新浏览器,循环语句乘法口诀


下一篇:Python中的单例模式——装饰器实现剖析