FileUploadHelper.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web;
  6. using System.IO;
  7. using System.Web.UI;
  8. using System.Web.Mvc;
  9. using Bowin.Common;
  10. using Ionic.Zip;
  11. using Bowin.Common.Log;
  12. namespace EMIS.Utility
  13. {
  14. public class FileUploadHelper
  15. {
  16. public class RemoteFileInfo
  17. {
  18. public string FileName { get; set; }
  19. public string RemotePath { get; set; }
  20. }
  21. public static string GetFileUploadSessionName(Guid formID)
  22. {
  23. return Const.UPLOAD_SESSION_NAME + "_" + formID.ToString();
  24. }
  25. private const long BUFFER_SIZE = 4096;
  26. /// <summary>
  27. /// savePath是相对与web上传路径的子路径,如:web上传路径为~/Content/DownFile,savePath为SOC/2018-201901,则实际上传的路径为~/Content/DownFile/SOC/2018-201901
  28. /// </summary>
  29. /// <param name="fileList"></param>
  30. /// <param name="savePath"></param>
  31. /// <returns></returns>
  32. public static List<string> UploadFile(HttpFileCollectionBase fileList, string savePath = null)
  33. {
  34. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  35. List<string> result = new List<string>();
  36. string filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  37. string physicalPath = HttpContext.Current.Server.MapPath(filePath);
  38. string dayFolderName = DateTime.Today.ToString("yyyy-MM");
  39. string tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\") + dayFolderName + "\\";
  40. if (!string.IsNullOrEmpty(savePath))
  41. {
  42. filePath += "/" + savePath;
  43. physicalPath = HttpContext.Current.Server.MapPath(filePath);
  44. tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\");
  45. }
  46. else
  47. {
  48. filePath += "/" + dayFolderName;
  49. }
  50. if (!Directory.Exists(tagetPhysicalPath))
  51. {
  52. Directory.CreateDirectory(tagetPhysicalPath);
  53. }
  54. foreach (HttpPostedFile file in fileList)
  55. {
  56. var newFileName = Guid.NewGuid().ToString() + "." + Path.GetExtension(file.FileName);
  57. var webFileName = filePath + "/" + newFileName;
  58. var physicalFileName = tagetPhysicalPath + newFileName;
  59. file.SaveAs(physicalFileName);
  60. result.Add(urlHelper.Content(webFileName));
  61. }
  62. return result;
  63. }
  64. /// <summary>
  65. /// savePath是相对与web上传路径的子路径,如:web上传路径为~/Content/DownFile,savePath为SOC/2018-201901,则实际上传的路径为~/Content/DownFile/SOC/2018-201901
  66. /// </summary>
  67. /// <param name="file"></param>
  68. /// <param name="savePath"></param>
  69. /// <returns></returns>
  70. public static string UploadFile(HttpPostedFileBase file, string savePath = null)
  71. {
  72. if (file == null || string.IsNullOrEmpty(file.FileName)) return null;
  73. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  74. string filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  75. string dayFolderName = DateTime.Today.ToString("yyyy-MM");
  76. var physicalFileName = UploadFileInternal(file, savePath);
  77. if (!string.IsNullOrEmpty(savePath))
  78. {
  79. filePath += "/" + savePath;
  80. }
  81. else
  82. {
  83. filePath += "/" + dayFolderName;
  84. }
  85. var webFileName = filePath + "/" + Path.GetFileName(physicalFileName);
  86. return urlHelper.Content(webFileName);
  87. }
  88. public static string UploadFile(MemoryStream file, string extName, string savePath = null)
  89. {
  90. if (file == null || file.Length == 0) return null;
  91. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  92. string filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  93. string dayFolderName = DateTime.Today.ToString("yyyy-MM");
  94. var physicalFileName = UploadFileInternal(file, extName, savePath);
  95. if (!string.IsNullOrEmpty(savePath))
  96. {
  97. filePath += "/" + savePath;
  98. }
  99. else
  100. {
  101. filePath += "/" + dayFolderName;
  102. }
  103. var webFileName = filePath + "/" + Path.GetFileName(physicalFileName);
  104. return urlHelper.Content(webFileName);
  105. }
  106. public static void DeleteFile(string filePath)
  107. {
  108. DeleteFileInternal(filePath);
  109. }
  110. /// <summary>
  111. /// savePath是相对与web上传路径的子路径,如:web上传路径为~/Content/DownFile,savePath为SOC/2018-201901,则实际上传的路径为~/Content/DownFile/SOC/2018-201901
  112. /// </summary>
  113. /// <param name="file"></param>
  114. /// <param name="savePath"></param>
  115. /// <returns></returns>
  116. public static IList<string> UploadFileAndExtractFile(HttpPostedFileBase file, string savePath = null)
  117. {
  118. var physicalFileName = UploadFileInternal(file, savePath);
  119. if (physicalFileName == null) return new List<string>();
  120. var targetPhysicalFileName = physicalFileName.Replace(Path.GetExtension(physicalFileName), "");
  121. var result = ZIPHelper.SevenZip_ExtractStream(physicalFileName, targetPhysicalFileName);
  122. //var filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  123. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  124. result = result.Select(s => urlHelper.Content("~/" + s.Replace(HttpContext.Current.Server.MapPath("~/"), "").Replace("\\", "//"))).ToList();
  125. return result;
  126. }
  127. /// <summary>
  128. /// savePath是相对与web上传路径的子路径,如:web上传路径为~/Content/DownFile,savePath为SOC/2018-201901,则实际上传的路径为~/Content/DownFile/SOC/2018-201901
  129. /// </summary>
  130. /// <param name="file"></param>
  131. /// <param name="savePath"></param>
  132. /// <returns></returns>
  133. public static string UploadFileInternal(HttpPostedFileBase file, string savePath = null)
  134. {
  135. LogHelper.WriteLog(LogType.ServiceLog, "----进入UploadFileInternal方法-----");
  136. if (file == null || string.IsNullOrEmpty(file.FileName)) return null;
  137. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  138. string filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  139. string physicalPath = HttpContext.Current.Server.MapPath(filePath);
  140. string dayFolderName = DateTime.Today.ToString("yyyy-MM");
  141. string tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\") + dayFolderName + "\\";
  142. if (!string.IsNullOrEmpty(savePath))
  143. {
  144. filePath += "/" + savePath;
  145. physicalPath = HttpContext.Current.Server.MapPath(filePath);
  146. tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\");
  147. }
  148. if (!Directory.Exists(tagetPhysicalPath))
  149. {
  150. Directory.CreateDirectory(tagetPhysicalPath);
  151. }
  152. var newFileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
  153. var physicalFileName = tagetPhysicalPath + newFileName;
  154. file.SaveAs(physicalFileName);
  155. return physicalFileName;
  156. }
  157. public static string UploadFileInternal(MemoryStream file, string extName, string savePath = null)
  158. {
  159. if (file == null || file.Length == 0) return null;
  160. UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
  161. string filePath = Const.LOCAL_SETTING_UPLOAD_FILEPATH;
  162. string physicalPath = HttpContext.Current.Server.MapPath(filePath);
  163. string dayFolderName = DateTime.Today.ToString("yyyy-MM");
  164. string tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\") + dayFolderName + "\\";
  165. if (!string.IsNullOrEmpty(savePath))
  166. {
  167. filePath += "/" + savePath;
  168. physicalPath = HttpContext.Current.Server.MapPath(filePath);
  169. tagetPhysicalPath = (physicalPath.EndsWith("\\") ? physicalPath : physicalPath + "\\");
  170. }
  171. if (!Directory.Exists(tagetPhysicalPath))
  172. {
  173. Directory.CreateDirectory(tagetPhysicalPath);
  174. }
  175. var newFileName = Guid.NewGuid().ToString() + extName;
  176. var physicalFileName = tagetPhysicalPath + newFileName;
  177. FileStream fs = File.Create(physicalFileName);
  178. var fileData = file.GetBuffer();
  179. fs.Write(fileData, 0, fileData.Length);
  180. fs.Flush();
  181. fs.Close();
  182. return physicalFileName;
  183. }
  184. public static void DeleteFileInternal(string filePath)
  185. {
  186. string fullPath = HttpContext.Current.Server.MapPath("~" + filePath);
  187. File.Delete(fullPath);
  188. }
  189. /// <summary>
  190. /// 批量下载文件并打包
  191. /// </summary>
  192. /// <param name="packageName">打包文件的文件名</param>
  193. /// <param name="fileNames">下载的临时文件的虚拟路径数组</param>
  194. /// <param name="remotePaths">远程文件地址数组</param>
  195. /// <remarks>fileNames和remotePaths的长度必须一致,并且同一索引的fileNames元素和remotePaths元素对应</remarks>
  196. /// <example>
  197. /// fileInfos[0].FileName = "文件1.txt";
  198. /// fileInfos[0].RemotePath = "http://www.google.com/html1.txt";
  199. /// fileInfos[1].FileName = "文件2.txt";
  200. /// fileInfos[1].RemotePath = "http://www.google.com/html2.txt";
  201. /// fileInfos[2].FileName = "文件3.txt";
  202. /// fileInfos[2].RemotePath = "http://www.google.com/html3.txt";
  203. ///
  204. /// packagePath = "c:\aa.rar";
  205. ///
  206. /// 执行结果:将http://www.google.com/html1.txt下载并保存为文件1.txt,
  207. /// http://www.google.com/html2.txt下载并保存为文件2.txt,
  208. /// http://www.google.com/html3.txt下载并保存为文件3.txt
  209. /// 然后将这三个文件打成压缩包,保存在c:\aa.rar中
  210. /// </example>
  211. public static Stream DownLoadFiles(string packageName, string downloadName, IList<RemoteFileInfo> fileInfos)
  212. {
  213. string rarTmpPathName = "RarTmp" + Guid.NewGuid().ToString();
  214. if (fileInfos.Count == 0)
  215. {
  216. throw new Exception("导出相片失败,找不到相片");
  217. //return;
  218. }
  219. #region 下载文件
  220. string physicalPath = HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName);
  221. Directory.CreateDirectory(HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName));
  222. //去重复
  223. var fileInfosDistinct = fileInfos.GroupBy(x => new { x.FileName, x.RemotePath }).Select(w => new { w.Key.FileName, w.Key.RemotePath }).ToList();
  224. var downloadedFileInfo = fileInfosDistinct.Take(0).ToList();
  225. foreach (var fileInfo in fileInfosDistinct)
  226. {
  227. try
  228. {
  229. var localfilePath = Path.GetDirectoryName(
  230. HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName + "/" + fileInfo.FileName)
  231. );
  232. if (!Directory.Exists(localfilePath))
  233. {
  234. Directory.CreateDirectory(localfilePath);
  235. }
  236. FileManager.DownloadFile(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName + "/" + fileInfo.FileName, fileInfo.RemotePath);
  237. downloadedFileInfo.Add(fileInfo);
  238. }
  239. catch (Exception ex)
  240. {
  241. string e = ex.ToString();
  242. continue;
  243. }
  244. }
  245. if (downloadedFileInfo.Count == 0)
  246. {
  247. throw new Exception("所有的下载文件都不存在,无法下载。");
  248. }
  249. #endregion
  250. System.Web.HttpServerUtility server = System.Web.HttpContext.Current.Server;
  251. #region 打包
  252. string packageFullPath = HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + packageName);
  253. string tmpFilePath = HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName);
  254. using (ZipFile zipNew = new ZipFile())
  255. {
  256. zipNew.AlternateEncoding = Encoding.UTF8;
  257. zipNew.AlternateEncodingUsage = ZipOption.AsNecessary;
  258. //去重复,压缩时若有重复文件会报“已添加了具有相同键的项”错误
  259. foreach (var fileInfo in downloadedFileInfo)
  260. {
  261. string UrlList = tmpFilePath + @"\" + fileInfo.FileName;
  262. zipNew.AddFile(UrlList, @"\" + Path.GetDirectoryName(fileInfo.FileName));
  263. }
  264. zipNew.Save(packageFullPath + ".zip");
  265. }
  266. Directory.Delete(HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + rarTmpPathName), true);
  267. #endregion
  268. #region 弹出下载窗口
  269. System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
  270. response.Clear();
  271. response.WriteFile(HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + packageName + ".zip"));
  272. string httpHeader = "attachment;filename=" + server.UrlEncode(downloadName) + ".zip";
  273. response.AppendHeader("Content-Disposition", httpHeader);
  274. response.Flush();
  275. System.IO.File.Delete(HttpContext.Current.Server.MapPath(Const.LOCAL_SETTING_UPLOAD_FILEPATH + "/" + packageName + ".zip"));//删除临时文件
  276. //response.End();
  277. return response.OutputStream;
  278. #endregion
  279. }
  280. }
  281. }