马上要过年了,现在也没有什么事情要做,今天就给大家讲讲基于WebService的文件上传,和下载,其实我们只是通过WebService来实现文件流的传输
下面说说我设计的文件上传系统
需求:
1.要可定制文件策略,也就是我可以允许系统上传什么格式的文件,每个格式文件允许多大 ,这些都可以通过后台来设定
2.上传文件的存储位置要支持多种,以便以后有所变动,目前支持有:数据库,Ftp,磁盘 三种存储介质
3. 更新同一个文件的时候,文件版本号自动变动,例如A文件 V1.0再次更新文件后版本号自动变为V1.1
4.文件被下载的时候,要有下载日志 ,用于记录文件的那个版本都被什么人下载过
数据库设计:
Files 文件表, 用于记录文件的主要信息,文件名,大小,版本号,上传人等信息
FileUpStrategy 文件上传策略表,用于设定可以上传的文件类型,大小等信息
FileContent 文件内容,用于支持数据库存储
FileContentType 文件内容类型 ,用于输出正确的文件流,例如:pdf格式的文件,内容类型 application/pdf 这个要在 Response.ContentType进行指定
FileDownLog 文件下载日志,用于记录下载日志的一些信息
FileScope 文件作用范围,这个标明文件的用途,可以和权限系统联系在一起,那个部门可以上传什么用途的文件
关键代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Net;
using System.Configuration;
using NHibernate;
using NHibernate.Criterion;
using System.Web.Caching;
using System.Web;
using AdminNet.Model.FileManager;
using AdminNet.IBLL.FileManager;
using AdminNet.Common;
namespace AdminNet.BLL.FileManager
{
public class File : Common, IFile
{
#region 文件基本信息
#region 文件查询
private IList Find(DetachedCriteria dc)
{
BaseDaoInIt();
ObjectNotNull(dc);
IList temp;
try
{
temp = BaseDao.FindByDetachedCriteria(dc);
BaseDao.Clear();
}
catch (Exception ex)
{
throw new DcException("获取文件失败", ex);
}
return temp;
}
public IList FindFile(Dictionary<string, object> dic, int offSet, int maxSize)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
if (offSet < 0 || maxSize < 0)
{
throw new DcException("offSet或maxSize不能小于0");
}
if (maxSize > 0)
{
dc.SetFirstResult(offSet * maxSize);
dc.SetMaxResults(maxSize);
}
dc.AddOrder(Order.Desc("CreateDate"));
foreach (KeyValuePair<string, object> kvp in dic)
{
object o = kvp.Value;
if (o is string)
{
if (!isNullOrEmpty(kvp.Value.ToString()))
{
if (kvp.Key.Equals("CreateDate"))
{
string[] str = kvp.Value.ToString().Split(new char[] { ';' });
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
if (DateTime.TryParse(str[0], out dt1) && DateTime.TryParse(str[1], out dt2))
{
dc.Add(Restrictions.Between(kvp.Key, dt1, dt2.AddDays(1)));
}
}
else
{
dc.Add(Restrictions.Like(kvp.Key, "%" + kvp.Value + "%"));
}
}
}
if (o is int)
{
if (kvp.Key.Equals("Id"))
{
dc.Add(Restrictions.Eq(kvp.Key, stringToInt32(o.ToString())));
}
else
{
dc.Add(Restrictions.Ge(kvp.Key, stringToInt32(o.ToString())));
}
}
if (o is IList)
{
IList lt = o as IList;
dc.Add(Restrictions.In(kvp.Key, stringToInt32(lt)));
}
if (o is double)
{
dc.Add(Restrictions.Ge(kvp.Key, double.Parse(o.ToString())));
}
}
return Find(dc);
}
public int CountFile(Dictionary<string, object> dic)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.SetProjection(Projections.RowCount());
foreach (KeyValuePair<string, object> kvp in dic)
{
object o = kvp.Value;
if (o is string)
{
if (!isNullOrEmpty(kvp.Value.ToString()))
{
if (kvp.Key.Equals("CreateDate"))
{
string[] str = kvp.Value.ToString().Split(new char[] { ';' });
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
if (DateTime.TryParse(str[0], out dt1) && DateTime.TryParse(str[1], out dt2))
{
dc.Add(Restrictions.Between(kvp.Key, dt1, dt2.AddDays(1)));
}
}
else
{
dc.Add(Restrictions.Like(kvp.Key, "%" + kvp.Value + "%"));
}
}
}
if (o is int)
{
if (kvp.Key.Equals("Id"))
{
dc.Add(Restrictions.Eq(kvp.Key, stringToInt32(o.ToString())));
}
else
{
dc.Add(Restrictions.Ge(kvp.Key, stringToInt32(o.ToString())));
}
}
if (o is IList)
{
IList lt = o as IList;
dc.Add(Restrictions.In(kvp.Key, stringToInt32(lt)));
}
if (o is double)
{
dc.Add(Restrictions.Ge(kvp.Key, double.Parse(o.ToString())));
}
}
return stringToInt32(Find(dc)[0].ToString());
}
#endregion
#region 文件基本信息保存
public int Save(FM_FileInfo file)
{
int status = 0;
BaseDaoInIt();
ObjectNotNull(file);
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("FileDisplayName", file.FileDisplayName);
dic.Add("FileScope_Id", file.FileScope_Id);
int count = CountFile(dic);
if (count > 0)
{
status = -4;
}
else
{
file.CreateDate = DBNow();
file.FileUpDate = file.CreateDate;
file.FileUpdateDate = file.FileUpDate;
try
{
BaseDao.Save(file);
FileStoreDeviceFactory.GetFileStoreDevice(file).Save(file);
status = 1;
}
catch (Exception ex)
{
throw new DcException("保存文件失败", ex);
}
}
return status;
}
#endregion
#region 修改文件
public int Update(FM_FileInfo file)
{
int status = 200;
BaseDaoInIt();
ObjectNotNull(file);
file.FileUpdateDate = DBNow();
file.FileVersion += 0.1;
try
{
BaseDao.Update(file);
FileStoreDeviceFactory.GetFileStoreDevice(file).Update(file);
UpdateFileContent(file);
}
catch (Exception ex)
{
throw new DcException("更新文件失败", ex);
}
return status;
}
#endregion
#region 删除文件
public int Delete(FM_FileInfo file)
{
int status = 200;
ObjectNotNull(file);
file.Flag = (int)Flag.Delete;
file.DeleteDate = DBNow();
BaseDao.Update(file);
return status;
}
#endregion
private void UpdateFileContent(FM_FileInfo file)
{
FileStoreDeviceFactory.GetFileStoreDevice(file).Update(file);
}
#endregion
#region 文件内容
public byte[] FindFileContent(Dictionary<string, object> dic, int offSet, int maxSize, FM_FileDownLogInfo downLog)
{
byte[] fileContent = new byte[0];
IList lt = FindFile(dic, 0, 1);
if (lt != null && lt.Count > 0)
{
FM_FileInfo ff = lt[0] as FM_FileInfo;
fileContent = FileStoreDeviceFactory.GetFileStoreDevice(ff).Find(ff);
if (fileContent != null)
{
downLog.File_Id = ff.Id;
downLog.FileNum = ff.FileNum;
Save(downLog);
}
}
return fileContent;
}
#endregion
#region 文件下载日志
#region
public IList FindFileLog(Dictionary<string, object> dic, int offSet, int maxSize)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileDownLogInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
if (offSet < 0 || maxSize < 0)
{
throw new DcException("offSet或maxSize不能小于0");
}
if (maxSize > 0)
{
dc.SetFirstResult(offSet * maxSize);
dc.SetMaxResults(maxSize);
}
foreach (KeyValuePair<string, object> kvp in dic)
{
dc.Add(Restrictions.Eq(kvp.Key, kvp.Value));
}
return Find(dc);
}
public void Save(FM_FileDownLogInfo fileDownLog)
{
BaseDaoInIt();
ObjectNotNull(fileDownLog);
try
{
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("Id", fileDownLog.File_Id);
IList temp = FindFile(dic, 0, 1);
if (temp != null && temp.Count > 0)
{
FM_FileInfo file = temp[0] as FM_FileInfo;
if (file != null)
{
file.FileDownNum += 1;
fileDownLog.FileName = file.FileDisplayName;
BaseDao.Update(file);
fileDownLog.FileDownVersion = file.FileVersion;
}
}
BaseDao.Save(fileDownLog);
}
catch (Exception ex)
{
throw new DcException("记录下载日志失败", ex);
}
}
#endregion
#region 统计个数
public int CountFileLog(Dictionary<string, object> dic)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileDownLogInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
foreach (KeyValuePair<string, object> kvp in dic)
{
dc.Add(Restrictions.Eq(kvp.Key, kvp.Value));
}
dc.SetProjection(Projections.RowCount());
return stringToInt32(Find(dc)[0].ToString());
}
#endregion
#endregion
#region 文件作用范围
public IList FindFileScope()
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileScopeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
return Find(dc);
}
public IList FindFileScope(IList fileScodeId)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileScopeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.Add(Restrictions.In("Id", IlistToString(fileScodeId)));
return Find(dc);
}
#endregion
#region 文件类型
public Hashtable FindFileContentType()
{
if (object.Equals(HttpRuntime.Cache[CacheKeys.FileContentType], null))
{
Hashtable ht = new Hashtable();
try
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileContentTypeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
IList temp = Find(dc);
foreach (FM_FileContentTypeInfo f in temp)
{
if (!ht.ContainsKey(f.FileType))
{
ht.Add(f.FileType.ToLower(), f.FileContentType);
}
}
HttpRuntime.Cache[CacheKeys.FileContentType] = ht; //使用缓存
}
catch (Exception ex)
{
throw new DcException("获取文件类型失败", ex);
}
}
Hashtable httemp = HttpRuntime.Cache[CacheKeys.FileContentType] as Hashtable;
return httemp;
}
#endregion
#region 文件上传策略
public int FileUpStrategy(FM_FileInfo file)
{
int status = 0;
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileUpStrategyInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.Add(Restrictions.Eq("FileScopeDes", file.Type));
dc.Add(Restrictions.Eq("FileType", file.FileType));
try
{
IList lt = Find(dc);
if (lt != null && lt.Count > 0)
{
status = -1;
foreach (FM_FileUpStrategyInfo ffus in lt)
{
if (ffus.FileLenght >= file.FileLenght || ffus.FileLenght.Equals(0))
{
status = 1;
break;
}
}
}
else
{
status = -2;
}
}
catch
{
status = 0;
}
return status;
}
#endregion
#region 获取目前日期时间
private string Now()
{
StringBuilder sb = new StringBuilder();
DateTime dt = DateTime.Now;
sb.AppendFormat("{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}{6:000}", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
return sb.ToString();
}
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Net;
using System.Configuration;
using NHibernate;
using NHibernate.Criterion;
using System.Web.Caching;
using System.Web;
using AdminNet.Model.FileManager;
using AdminNet.IBLL.FileManager;
using AdminNet.Common;
namespace AdminNet.BLL.FileManager
{
public class File : Common, IFile
{
#region 文件基本信息
#region 文件查询
private IList Find(DetachedCriteria dc)
{
BaseDaoInIt();
ObjectNotNull(dc);
IList temp;
try
{
temp = BaseDao.FindByDetachedCriteria(dc);
BaseDao.Clear();
}
catch (Exception ex)
{
throw new DcException("获取文件失败", ex);
}
return temp;
}
public IList FindFile(Dictionary<string, object> dic, int offSet, int maxSize)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
if (offSet < 0 || maxSize < 0)
{
throw new DcException("offSet或maxSize不能小于0");
}
if (maxSize > 0)
{
dc.SetFirstResult(offSet * maxSize);
dc.SetMaxResults(maxSize);
}
dc.AddOrder(Order.Desc("CreateDate"));
foreach (KeyValuePair<string, object> kvp in dic)
{
object o = kvp.Value;
if (o is string)
{
if (!isNullOrEmpty(kvp.Value.ToString()))
{
if (kvp.Key.Equals("CreateDate"))
{
string[] str = kvp.Value.ToString().Split(new char[] { ';' });
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
if (DateTime.TryParse(str[0], out dt1) && DateTime.TryParse(str[1], out dt2))
{
dc.Add(Restrictions.Between(kvp.Key, dt1, dt2.AddDays(1)));
}
}
else
{
dc.Add(Restrictions.Like(kvp.Key, "%" + kvp.Value + "%"));
}
}
}
if (o is int)
{
if (kvp.Key.Equals("Id"))
{
dc.Add(Restrictions.Eq(kvp.Key, stringToInt32(o.ToString())));
}
else
{
dc.Add(Restrictions.Ge(kvp.Key, stringToInt32(o.ToString())));
}
}
if (o is IList)
{
IList lt = o as IList;
dc.Add(Restrictions.In(kvp.Key, stringToInt32(lt)));
}
if (o is double)
{
dc.Add(Restrictions.Ge(kvp.Key, double.Parse(o.ToString())));
}
}
return Find(dc);
}
public int CountFile(Dictionary<string, object> dic)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.SetProjection(Projections.RowCount());
foreach (KeyValuePair<string, object> kvp in dic)
{
object o = kvp.Value;
if (o is string)
{
if (!isNullOrEmpty(kvp.Value.ToString()))
{
if (kvp.Key.Equals("CreateDate"))
{
string[] str = kvp.Value.ToString().Split(new char[] { ';' });
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
if (DateTime.TryParse(str[0], out dt1) && DateTime.TryParse(str[1], out dt2))
{
dc.Add(Restrictions.Between(kvp.Key, dt1, dt2.AddDays(1)));
}
}
else
{
dc.Add(Restrictions.Like(kvp.Key, "%" + kvp.Value + "%"));
}
}
}
if (o is int)
{
if (kvp.Key.Equals("Id"))
{
dc.Add(Restrictions.Eq(kvp.Key, stringToInt32(o.ToString())));
}
else
{
dc.Add(Restrictions.Ge(kvp.Key, stringToInt32(o.ToString())));
}
}
if (o is IList)
{
IList lt = o as IList;
dc.Add(Restrictions.In(kvp.Key, stringToInt32(lt)));
}
if (o is double)
{
dc.Add(Restrictions.Ge(kvp.Key, double.Parse(o.ToString())));
}
}
return stringToInt32(Find(dc)[0].ToString());
}
#endregion
#region 文件基本信息保存
public int Save(FM_FileInfo file)
{
int status = 0;
BaseDaoInIt();
ObjectNotNull(file);
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("FileDisplayName", file.FileDisplayName);
dic.Add("FileScope_Id", file.FileScope_Id);
int count = CountFile(dic);
if (count > 0)
{
status = -4;
}
else
{
file.CreateDate = DBNow();
file.FileUpDate = file.CreateDate;
file.FileUpdateDate = file.FileUpDate;
try
{
BaseDao.Save(file);
FileStoreDeviceFactory.GetFileStoreDevice(file).Save(file);
status = 1;
}
catch (Exception ex)
{
throw new DcException("保存文件失败", ex);
}
}
return status;
}
#endregion
#region 修改文件
public int Update(FM_FileInfo file)
{
int status = 200;
BaseDaoInIt();
ObjectNotNull(file);
file.FileUpdateDate = DBNow();
file.FileVersion += 0.1;
try
{
BaseDao.Update(file);
FileStoreDeviceFactory.GetFileStoreDevice(file).Update(file);
UpdateFileContent(file);
}
catch (Exception ex)
{
throw new DcException("更新文件失败", ex);
}
return status;
}
#endregion
#region 删除文件
public int Delete(FM_FileInfo file)
{
int status = 200;
ObjectNotNull(file);
file.Flag = (int)Flag.Delete;
file.DeleteDate = DBNow();
BaseDao.Update(file);
return status;
}
#endregion
private void UpdateFileContent(FM_FileInfo file)
{
FileStoreDeviceFactory.GetFileStoreDevice(file).Update(file);
}
#endregion
#region 文件内容
public byte[] FindFileContent(Dictionary<string, object> dic, int offSet, int maxSize, FM_FileDownLogInfo downLog)
{
byte[] fileContent = new byte[0];
IList lt = FindFile(dic, 0, 1);
if (lt != null && lt.Count > 0)
{
FM_FileInfo ff = lt[0] as FM_FileInfo;
fileContent = FileStoreDeviceFactory.GetFileStoreDevice(ff).Find(ff);
if (fileContent != null)
{
downLog.File_Id = ff.Id;
downLog.FileNum = ff.FileNum;
Save(downLog);
}
}
return fileContent;
}
#endregion
#region 文件下载日志
#region
public IList FindFileLog(Dictionary<string, object> dic, int offSet, int maxSize)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileDownLogInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
if (offSet < 0 || maxSize < 0)
{
throw new DcException("offSet或maxSize不能小于0");
}
if (maxSize > 0)
{
dc.SetFirstResult(offSet * maxSize);
dc.SetMaxResults(maxSize);
}
foreach (KeyValuePair<string, object> kvp in dic)
{
dc.Add(Restrictions.Eq(kvp.Key, kvp.Value));
}
return Find(dc);
}
public void Save(FM_FileDownLogInfo fileDownLog)
{
BaseDaoInIt();
ObjectNotNull(fileDownLog);
try
{
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("Id", fileDownLog.File_Id);
IList temp = FindFile(dic, 0, 1);
if (temp != null && temp.Count > 0)
{
FM_FileInfo file = temp[0] as FM_FileInfo;
if (file != null)
{
file.FileDownNum += 1;
fileDownLog.FileName = file.FileDisplayName;
BaseDao.Update(file);
fileDownLog.FileDownVersion = file.FileVersion;
}
}
BaseDao.Save(fileDownLog);
}
catch (Exception ex)
{
throw new DcException("记录下载日志失败", ex);
}
}
#endregion
#region 统计个数
public int CountFileLog(Dictionary<string, object> dic)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileDownLogInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
foreach (KeyValuePair<string, object> kvp in dic)
{
dc.Add(Restrictions.Eq(kvp.Key, kvp.Value));
}
dc.SetProjection(Projections.RowCount());
return stringToInt32(Find(dc)[0].ToString());
}
#endregion
#endregion
#region 文件作用范围
public IList FindFileScope()
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileScopeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
return Find(dc);
}
public IList FindFileScope(IList fileScodeId)
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileScopeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.Add(Restrictions.In("Id", IlistToString(fileScodeId)));
return Find(dc);
}
#endregion
#region 文件类型
public Hashtable FindFileContentType()
{
if (object.Equals(HttpRuntime.Cache[CacheKeys.FileContentType], null))
{
Hashtable ht = new Hashtable();
try
{
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileContentTypeInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
IList temp = Find(dc);
foreach (FM_FileContentTypeInfo f in temp)
{
if (!ht.ContainsKey(f.FileType))
{
ht.Add(f.FileType.ToLower(), f.FileContentType);
}
}
HttpRuntime.Cache[CacheKeys.FileContentType] = ht; //使用缓存
}
catch (Exception ex)
{
throw new DcException("获取文件类型失败", ex);
}
}
Hashtable httemp = HttpRuntime.Cache[CacheKeys.FileContentType] as Hashtable;
return httemp;
}
#endregion
#region 文件上传策略
public int FileUpStrategy(FM_FileInfo file)
{
int status = 0;
DetachedCriteria dc = DetachedCriteria.For(typeof(FM_FileUpStrategyInfo));
dc.Add(Restrictions.Eq("Flag", (int)Flag.Normal));
dc.Add(Restrictions.Eq("FileScopeDes", file.Type));
dc.Add(Restrictions.Eq("FileType", file.FileType));
try
{
IList lt = Find(dc);
if (lt != null && lt.Count > 0)
{
status = -1;
foreach (FM_FileUpStrategyInfo ffus in lt)
{
if (ffus.FileLenght >= file.FileLenght || ffus.FileLenght.Equals(0))
{
status = 1;
break;
}
}
}
else
{
status = -2;
}
}
catch
{
status = 0;
}
return status;
}
#endregion
#region 获取目前日期时间
private string Now()
{
StringBuilder sb = new StringBuilder();
DateTime dt = DateTime.Now;
sb.AppendFormat("{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}{6:000}", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
return sb.ToString();
}
#endregion
}
}