在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例常用C#方法 → c# 实现离线文件功能

c# 实现离线文件功能

常用C#方法

下载此实例
  • 开发语言:C#
  • 实例大小:7.10KB
  • 下载次数:32
  • 浏览次数:729
  • 发布时间:2014-03-24
  • 实例类别:常用C#方法
  • 发 布 人:aspnet
  • 文件格式:.txt
  • 所需积分:2
 相关标签: 离线文件

实例介绍

【实例简介】
【实例截图】

【核心代码】

1.客户端发送离线文件
当用户选择好一个文件,并点击“发送离线文件”按钮时,其目的是要将这个文件传送给服务端,这可以直接使用IFileOutter的BeginSendFile方法:
/// <summary>
/// 发送方准备发送文件(夹)。
/// </summary>
/// <param name="accepterID">接收文件(夹)的用户ID</param>
/// <param name="fileOrDirPath">被发送文件(夹)的路径</param>
/// <param name="comment">其它附加备注。如果是在类似FTP的服务中,该参数可以是保存文件(夹)的路径</param>
/// <param name="projectID">返回文件传送项目的编号</param>
void BeginSendFile(string accepterID, string fileOrDirPath, string comment, out string projectID);
如果将参数accepterID传入null,表示文件的接收者就是服务端。那么我们要如何区分,这不是一个最终由服务端接收的文件,而是要传给另一个用户的离线文件了?这里,我们可以巧用comment参数,比如,comment参数如果为null,就表示普通的上传文件;comment不为null,就表示一个离线文件,并且其值就是文件最终接收者的ID。(当然,如果在你的项目中,comment参数已经有了其它用途,我们可以进一步扩展它,加上一些标签,使其能够标志出离线文件)。
下面这个调用示例,就是将Test.txt文件离线发送给aa01。
string filePath = ...; //要发送文件的路径
string projectID = null;
fileOutter.BeginSendFile(null, filePath, "aa01", out projectID);
2.服务端接收离线文件
客户端调用BeginSendFile方法请求发送文件后,服务端会触发IFileController的FileRequestReceived事件。同理,我们判断该事件的comment参数,当其不为null时,表示是个离线文件。在答复客户端同意接收文件之前,我们需要先将离线文件的相关信息保存起来,这里我们使用OfflineFileItem类来封装这些信息。
/// <summary>
/// 离线文件条目
/// </summary>
public class OfflineFileItem

/// <summary>
/// 条目的唯一编号,数据库自增序列,主键。
/// </summary>
public string AutoID { get; set; }

/// <summary>
/// 离线文件的名称。
/// </summary>
public string FileName { get; set; }

/// <summary>
/// 文件的大小。
/// </summary>
public ulong FileLength { get; set; }

/// <summary>
/// 发送者ID。
/// </summary>
public string SenderID { get; set; }

/// <summary>
/// 接收者ID。
/// </summary>
public string AccepterID { get; set; }

/// <summary>
/// 在服务器上存储离线文件的临时路径。
/// </summary>
public string RelayFilePath { get; set; }
}
 
有了OfflineFileItem的定义之后,我们就可以处理IFileController的FileRequestReceived事件了。
 
 
 
rapidServerEngine.FileController.FileRequestReceived = new CbFileRequestReceived(fileController_FileRequestReceived);

ObjectManager<string, OfflineFileItem> offlineFileItemManager = new ObjectManager<string, OfflineFileItem>(); //可以把ObjectManager类看作一个线程安全的Dictionary。
void fileController_FileRequestReceived(string projectID, string senderID, string fileName, ulong totalSize, ResumedProjectItem resumedFileItem, string comment)
{
string saveFilePath = "......" ;//根据某种策略得到存放文件的路径
if (comment != null) //根据约定,comment不为null,表示为离线文件,其值为最终接收者的ID。
{
string accepterID = comment;
OfflineFileItem item = new OfflineFileItem();
item.AccepterID = accepterID;
item.FileLength = totalSize;
item.FileName = fileName;
item.SenderID = senderID ;
item.RelayFilePath = saveFilePath;
offlineFileItemManager.Add(projectID, item);
}

//给客户端回复同意,并开始准备接收文件。
rapidServerEngine.FileController.BeginReceiveFile(projectID ,saveFilePath);
}
上面的代码做了三件事情:
(1)根据某种策略得到存放文件的路径。
(2)创建一个离线文件信息条目,保存在内存中。
(3)回复客户端,并准备接收文件。
需要重点说明的是第一点,对于一般的小型项目,在服务端我们可以将所有的离线文件存放在当前服务器的某个目录下;但是对于大型项目,一般需要使用DFS(分布式文件系统)来存储这些临时的离线文件。
客户端收到服务器的回复后,会正式开始传送文件,如果传送过程中,因为某种原因导致传送中断,则服务端会触发IFileController.FileReceivingEvents的FileTransDisruptted事件。在该事件处理函数中,我们从内存中移除对应的离线文件信息条目:
 
rapidServerEngine.FileController.FileReceivingEvents.FileTransDisruptted = new CbGeneric<TransferingProject, FileTransDisrupttedType>(fileReceivingEvents_FileTransDisruptted);

void fileReceivingEvents_FileTransDisruptted(TransferingProject project, FileTransDisrupttedType type)
{
offlineFileItemManager.Remove(project.ProjectID);
}
 
如果文件正常传送完毕,则服务端会触发IFileController.FileReceivingEvents的FileTransCompleted事件。此时,我们将对应的离线文件信息条目从内存转移存储到数据库中,以防止服务器重启时导致信息丢失:
 
rapidServerEngine.FileController.FileReceivingEvents.FileTransCompleted = new CbGeneric<TransferingProject>(fileReceivingEvents_FileTransCompleted);

IOfflineFilePersister offlineFilePersister = ......;
void fileReceivingEvents_FileTransCompleted(TransferingProject project)
{
OfflineFileItem item = offlineFileItemManager.Get(project.ProjectID);
offlineFilePersister.Add(item);
offlineFileItemManager.Remove(project.ProjectID);
}
 
 
 
我们设计IOfflineFilePersister接口,用于与数据库中的OfflineFileItem表交互。
 
 
public interface IOfflineFilePersister
{
/// <summary>
/// 将一个离线文件条目保存到数据库中。
/// </summary>
void Add(OfflineFileItem item);

/// <summary>
///从数据库中删除主键值为ID的条目。
/// </summary>
void Remove(string id);

/// <summary>
/// 从数据库中提取接收者为指定用户的所有离线文件条目。
/// </summary>
List<OfflineFileItem> GetByAccepter(string accepterID);
}
 
我们可以使用ADO.NET或者EntityFramework实现上述接口。
3.服务端发送离线文件给最终接收者
当真正的接收者上线时,服务端要把相关的离线文件发送给他。通过预定UserManager的SomeOneConnected事件,我们知道用户上线的时刻。
 
 
rapidServerEngine.UserManager.SomeOneConnected = new CbGeneric<UserData>(userManager_SomeOneConnected);

void userManager_SomeOneConnected(UserData data)
{
List<OfflineFileItem> list = offlineFilePersister.GetByAccepter(data.UserID);
if (list != null)
{
foreach (OfflineFileItem item in list)
{
string projectID = null ;
rapidServerEngine.FileController.BeginSendFile(item.AccepterID, item.RelayFilePath, item.SenderID, out projectID);
offlineFilePersister.Remove(item.AutoID);
File.Delete(item.RelayFilePath);
}
}
}
上面的代码做了三件事情:
(1)从数据库中查找所有接收者为登录用户的离线文件信息条目。
(2)将离线文件逐个发送给这个用户
(3)从数据库中删除相应的条目,从磁盘上删除对应的离线文件。


标签: 离线文件

实例下载地址

c# 实现离线文件功能

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警