UltimateFileServer.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net.Sockets;
  6. using System.Net;
  7. using System.Threading;
  8. using System.IO;
  9. using System.Security.Cryptography;
  10. using System.Drawing;
  11. using HslCommunication.BasicFramework;
  12. using HslCommunication.LogNet;
  13. using HslCommunication.Core;
  14. namespace HslCommunication.Enthernet
  15. {
  16. /// <summary>
  17. /// 终极文件管理服务器,实现所有的文件分类管理,读写分离,不支持直接访问文件名
  18. /// </summary>
  19. public class UltimateFileServer : Core.Net.NetworkFileServerBase
  20. {
  21. #region Constructor
  22. /// <summary>
  23. /// 实例化一个对象
  24. /// </summary>
  25. public UltimateFileServer( )
  26. {
  27. }
  28. #endregion
  29. #region 文件列表存储器
  30. /// <summary>
  31. /// 所有文件组操作的词典锁
  32. /// </summary>
  33. internal Dictionary<string, GroupFileContainer> m_dictionary_group_marks = new Dictionary<string, GroupFileContainer>( );
  34. /// <summary>
  35. /// 词典的锁
  36. /// </summary>
  37. private SimpleHybirdLock hybirdLock = new SimpleHybirdLock( );
  38. /// <summary>
  39. /// 获取当前目录的读写锁,如果没有会自动创建
  40. /// </summary>
  41. /// <param name="filePath">相对路径名</param>
  42. /// <returns>读写锁</returns>
  43. public GroupFileContainer GetGroupFromFilePath( string filePath )
  44. {
  45. GroupFileContainer GroupFile = null;
  46. hybirdLock.Enter( );
  47. // lock operator
  48. if (m_dictionary_group_marks.ContainsKey( filePath ))
  49. {
  50. GroupFile = m_dictionary_group_marks[filePath];
  51. }
  52. else
  53. {
  54. GroupFile = new GroupFileContainer( LogNet, filePath );
  55. m_dictionary_group_marks.Add( filePath, GroupFile );
  56. }
  57. hybirdLock.Leave( );
  58. return GroupFile;
  59. }
  60. #endregion
  61. #region 接收文件数据并更新文件列表
  62. /// <summary>
  63. /// 从套接字接收文件并保存,更新文件列表
  64. /// </summary>
  65. /// <param name="socket">套接字</param>
  66. /// <param name="savename">保存的文件名</param>
  67. /// <returns></returns>
  68. private OperateResult ReceiveFileFromSocketAndUpdateGroup(
  69. Socket socket,
  70. string savename
  71. )
  72. {
  73. FileInfo info = new FileInfo( savename );
  74. string guidName = CreateRandomFileName( );
  75. string fileName = info.DirectoryName + "\\" + guidName;
  76. OperateResult<FileBaseInfo> receive = ReceiveFileFromSocket( socket, fileName, null );
  77. if(!receive.IsSuccess)
  78. {
  79. DeleteFileByName( fileName );
  80. return receive;
  81. }
  82. // 更新操作
  83. GroupFileContainer fileManagment = GetGroupFromFilePath( info.DirectoryName );
  84. string oldName = fileManagment.UpdateFileMappingName(
  85. info.Name,
  86. receive.Content.Size,
  87. guidName,
  88. receive.Content.Upload,
  89. receive.Content.Tag
  90. );
  91. // 删除旧的文件
  92. DeleteExsistingFile( info.DirectoryName, oldName );
  93. // 回发消息
  94. return SendStringAndCheckReceive( socket, 1, "成功" );
  95. }
  96. #endregion
  97. #region Private Method
  98. /// <summary>
  99. /// 根据文件的显示名称转化为真实存储的名称
  100. /// </summary>
  101. /// <param name="factory">第一大类</param>
  102. /// <param name="group">第二大类</param>
  103. /// <param name="id">第三大类</param>
  104. /// <param name="fileName">文件显示名称</param>
  105. /// <returns></returns>
  106. private string TransformFactFileName( string factory, string group, string id, string fileName )
  107. {
  108. string path = ReturnAbsoluteFilePath( factory, group, id );
  109. GroupFileContainer fileManagment = GetGroupFromFilePath( path );
  110. return fileManagment.GetCurrentFileMappingName( fileName );
  111. }
  112. /// <summary>
  113. /// 删除已经存在的文件信息
  114. /// </summary>
  115. /// <param name="path"></param>
  116. /// <param name="fileName"></param>
  117. private void DeleteExsistingFile( string path, string fileName )
  118. {
  119. if (!string.IsNullOrEmpty( fileName ))
  120. {
  121. string fileUltimatePath = path + "\\" + fileName;
  122. FileMarkId fileMarkId = GetFileMarksFromDictionaryWithFileName( fileName );
  123. fileMarkId.AddOperation( ( ) =>
  124. {
  125. if (!DeleteFileByName( fileUltimatePath ))
  126. {
  127. LogNet?.WriteInfo( ToString(), StringResources.FileDeleteFailed + fileUltimatePath );
  128. }
  129. } );
  130. }
  131. }
  132. #endregion
  133. #region Protect Override
  134. /// <summary>
  135. /// 处理数据
  136. /// </summary>
  137. /// <param name="obj"></param>
  138. protected override void ThreadPoolLogin( object obj )
  139. {
  140. if (obj is Socket)
  141. {
  142. Socket socket = obj as Socket;
  143. OperateResult result = new OperateResult( );
  144. // 获取ip地址
  145. string IpAddress = ((IPEndPoint)(socket.RemoteEndPoint)).Address.ToString( );
  146. // 接收操作信息
  147. int customer;
  148. string fileName;
  149. string Factory;
  150. string Group;
  151. string Identify;
  152. if (!ReceiveInformationHead(
  153. socket,
  154. out customer,
  155. out fileName,
  156. out Factory,
  157. out Group,
  158. out Identify).IsSuccess)
  159. {
  160. return;
  161. }
  162. string relativeName = ReturnRelativeFileName( Factory, Group, Identify, fileName );
  163. if (customer == HslProtocol.ProtocolFileDownload)
  164. {
  165. // 先获取文件的真实名称
  166. string guidName = TransformFactFileName( Factory, Group, Identify, fileName );
  167. // 获取文件操作锁
  168. FileMarkId fileMarkId = GetFileMarksFromDictionaryWithFileName( guidName );
  169. fileMarkId.EnterReadOperator( );
  170. // 发送文件数据
  171. OperateResult send = SendFileAndCheckReceive( socket, ReturnAbsoluteFileName( Factory, Group, Identify, guidName ), fileName, "", "", null );
  172. if (!send.IsSuccess)
  173. {
  174. fileMarkId.LeaveReadOperator( );
  175. LogNet?.WriteError( ToString( ), $"{StringResources.FileDownloadFailed} : {send.Message} :{relativeName} ip:{IpAddress}" );
  176. return;
  177. }
  178. else
  179. {
  180. LogNet?.WriteInfo( ToString( ), StringResources.FileDownloadSuccess + ":" + relativeName );
  181. }
  182. fileMarkId.LeaveReadOperator( );
  183. // 关闭连接
  184. socket?.Close( );
  185. }
  186. else if (customer == HslProtocol.ProtocolFileUpload)
  187. {
  188. string fullFileName = ReturnAbsoluteFileName( Factory, Group, Identify, fileName );
  189. // 上传文件
  190. CheckFolderAndCreate( );
  191. FileInfo info = new FileInfo( fullFileName );
  192. try
  193. {
  194. if (!Directory.Exists( info.DirectoryName ))
  195. {
  196. Directory.CreateDirectory( info.DirectoryName );
  197. }
  198. }
  199. catch (Exception ex)
  200. {
  201. LogNet?.WriteException( ToString( ), StringResources.FilePathCreateFailed + fullFileName, ex );
  202. socket?.Close( );
  203. return;
  204. }
  205. // 接收文件并回发消息
  206. if (ReceiveFileFromSocketAndUpdateGroup(
  207. socket, // 网络套接字
  208. fullFileName ).IsSuccess)
  209. {
  210. socket?.Close( );
  211. LogNet?.WriteInfo( ToString( ), StringResources.FileUploadSuccess + ":" + relativeName );
  212. }
  213. else
  214. {
  215. LogNet?.WriteInfo( ToString( ), StringResources.FileUploadFailed + ":" + relativeName );
  216. }
  217. }
  218. else if (customer == HslProtocol.ProtocolFileDelete)
  219. {
  220. string fullFileName = ReturnAbsoluteFileName( Factory, Group, Identify, fileName );
  221. FileInfo info = new FileInfo( fullFileName );
  222. GroupFileContainer fileManagment = GetGroupFromFilePath( info.DirectoryName );
  223. // 新增删除的任务
  224. DeleteExsistingFile( info.DirectoryName, fileManagment.DeleteFile( info.Name ) );
  225. // 回发消息
  226. if (SendStringAndCheckReceive(
  227. socket, // 网络套接字
  228. 1, // 没啥含义
  229. "success" // 没啥含意
  230. ).IsSuccess)
  231. {
  232. socket?.Close( );
  233. }
  234. LogNet?.WriteInfo( ToString( ), StringResources.FileDeleteSuccess + ":" + relativeName );
  235. }
  236. else if (customer == HslProtocol.ProtocolFileDirectoryFiles)
  237. {
  238. GroupFileContainer fileManagment = GetGroupFromFilePath( ReturnAbsoluteFilePath( Factory, Group, Identify ) );
  239. if (SendStringAndCheckReceive(
  240. socket,
  241. HslProtocol.ProtocolFileDirectoryFiles,
  242. fileManagment.JsonArrayContent ).IsSuccess)
  243. {
  244. socket?.Close( );
  245. }
  246. }
  247. else if (customer == HslProtocol.ProtocolFileDirectories)
  248. {
  249. List<string> folders = new List<string>( );
  250. foreach (var m in GetDirectories( Factory, Group, Identify ))
  251. {
  252. DirectoryInfo directory = new DirectoryInfo( m );
  253. folders.Add( directory.Name );
  254. }
  255. Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.FromObject( folders.ToArray( ) );
  256. if (SendStringAndCheckReceive(
  257. socket,
  258. HslProtocol.ProtocolFileDirectoryFiles,
  259. jArray.ToString( ) ).IsSuccess)
  260. {
  261. socket?.Close( );
  262. }
  263. }
  264. else
  265. {
  266. // close not supported client
  267. socket?.Close( );
  268. }
  269. }
  270. }
  271. #endregion
  272. #region Object Override
  273. /// <summary>
  274. /// 获取本对象的字符串表示形式
  275. /// </summary>
  276. /// <returns></returns>
  277. public override string ToString( )
  278. {
  279. return "UltimateFileServer";
  280. }
  281. #endregion
  282. }
  283. }