介绍一种有效的临时文件处理架构
点击次数:25 次 发布日期:2008-11-26 22:30:33 作者:源代码网
|
源代码网推荐 之前研究过CS,但是CS的问题是只允许附带一个文件,所以并不能够解决附带多个文件的处理问题,尤其是用户可能会传上来大量的图片而之后又废弃不用的情况。 源代码网推荐 源代码网推荐 源代码网推荐 就是说程序在设计的时候就应该考虑好用户上传了一些图片或图片,然后废弃不用的情况,你不能对任何程序都做个图片库或者文件库来管理用户传上来的文件或者图片。 源代码网推荐 源代码网推荐 其实这个架构很久之前就总结好了,不过之前一直通过数据库来解决这个问题,最近坐到架构师的位置上,就不得不认真细致的来把这个问题做好。 源代码网推荐 举个例子: 源代码网推荐 比如 源代码网推荐 下面是我做的一个页面的图片上传页面, 源代码网推荐
源代码网推荐 对于用户上传上来的临时文件,系统会保存到一个临时文件目录中,同时附加一个xml文件记录该文件的信息,如文件大小、文件类型、上传时间等。而在附加文件的页面则只需保存一个ViewState中保存的string类型的列表通过实际为Guid类型的标识符来跟踪这些文件。 源代码网推荐 如下面的代码所示: 源代码网推荐 1 protected const string hiddenFileNamePattern = "{0}.syattachment"; 源代码网推荐 2 protected const string hiddenFileNameMetaDataPattern = "{0}.meta"; 源代码网推荐 3 源代码网推荐 4 源代码网推荐 5 /**//// <summary> 源代码网推荐 6 /// 插入临时文件 源代码网推荐 7 /// </summary> 源代码网推荐 8 /// <param name="key"></param> 源代码网推荐 9 /// <param name="stream"></param> 源代码网推荐 10 public static void Insert(string key, FileInfo tempFile) 源代码网推荐 11 { 源代码网推荐 12 if (string.IsNullOrEmpty(key)) 源代码网推荐 13 throw new ArgumentNullException("key", "temporary file key can"t be null."); 源代码网推荐 14 源代码网推荐 15 if (tempFile == null) 源代码网推荐 16 throw new ArgumentNullException("tempFile", "temporary file can"t be null."); 源代码网推荐 17 源代码网推荐 18 源代码网推荐 19 // save the temporary file to temporary file storage location 源代码网推荐 20 string contentFilename = GetFileName(key, false); 源代码网推荐 21 FileHelper.SaveToDisk(tempFile.ContentStream, contentFilename); 源代码网推荐 22 源代码网推荐 23 源代码网推荐 24 //生成附属的xml文件,记录该文件的信息 源代码网推荐 25 string metaFilename = GetFileName(key, true); 源代码网推荐 26 XmlWriter tempWriter = XmlWriter.Create(metaFilename); 源代码网推荐 27 源代码网推荐 28 源代码网推荐 29 源代码网推荐 30 tempWriter.WriteStartDocument(); 源代码网推荐 31 tempWriter.WriteStartElement("file"); 源代码网推荐 32 tempWriter.WriteAttributeString("key", key); 源代码网推荐 33 tempWriter.WriteAttributeString("isTemporary", "true"); 源代码网推荐 34 源代码网推荐 35 tempWriter.WriteStartElement("fileName"); 源代码网推荐 36 tempWriter.WriteString(tempFile.FileName); 源代码网推荐 37 tempWriter.WriteEndElement(); 源代码网推荐 38 源代码网推荐 39 tempWriter.WriteStartElement("extension"); 源代码网推荐 40 tempWriter.WriteString(tempFile.FileExtension); 源代码网推荐 41 tempWriter.WriteEndElement(); 源代码网推荐 42 源代码网推荐 43 tempWriter.WriteStartElement("contentType"); 源代码网推荐 44 tempWriter.WriteString(tempFile.ContentType); 源代码网推荐 45 tempWriter.WriteEndElement(); 源代码网推荐 46 源代码网推荐 47 tempWriter.WriteStartElement("contentSize"); 源代码网推荐 48 tempWriter.WriteString(tempFile.Length.ToString()); 源代码网推荐 49 tempWriter.WriteEndElement(); 源代码网推荐 50 源代码网推荐 51 tempWriter.WriteStartElement("createdDate"); 源代码网推荐 52 tempWriter.WriteString(DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss")); 源代码网推荐 53 tempWriter.WriteEndElement(); 源代码网推荐 54 源代码网推荐 55 tempWriter.WriteEndDocument(); 源代码网推荐 56 源代码网推荐 57 tempWriter.Close(); 源代码网推荐 58 }上面的代码第一部分先保存了文件的数据流,而第二部分则保存了文件的附属信息。 源代码网推荐 源代码网推荐 临时文件加到服务器上了,被废弃了的情况下,系统会自动在指定时间后删除不用的临时文件,代码如下: 源代码网推荐 1 public void DeleteExpiredTemporaryFiles() 源代码网推荐 2 { 源代码网推荐 3 HttpContext context = HttpContext.Current; 源代码网推荐 4 FileUtilsConfiguration fileConfig = FileUtilsConfiguration.Instance(); 源代码网推荐 5 string tempLocation = context.Server.MapPath(fileConfig.TemporaryLocation); 源代码网推荐 6 int minutes = fileConfig.ExpireTimes;//超时时间,以分钟计 源代码网推荐 7 源代码网推荐 8 DateTime now = DateTime.Now; 源代码网推荐 9 源代码网推荐 10 //获取该目录下的所有文件 源代码网推荐 11 string[] fileNames = Directory.GetFiles(tempLocation, "*.meta"); 源代码网推荐 12 foreach (string fileName in fileNames) 源代码网推荐 13 { 源代码网推荐 14 XmlDocument doc = new XmlDocument(); 源代码网推荐 15 doc.Load(fileName); 源代码网推荐 16 源代码网推荐 17 DateTime createdDate = Convert.ToDateTime(doc.SelectSingleNode("/file/createdDate").InnerText); 源代码网推荐 18 源代码网推荐 19 if (createdDate.AddMinutes(20) < now) 源代码网推荐 20 { 源代码网推荐 21 string key = System.IO.Path.GetFileNameWithoutExtension(fileName); 源代码网推荐 22 //删除文件 源代码网推荐 23 File.Delete(tempLocation + key + ".syattachment"); 源代码网推荐 24 源代码网推荐 25 //删除文件附属信息 源代码网推荐 26 File.Delete(tempLocation + key + ".meta"); 源代码网推荐 27 } 源代码网推荐 28 } 源代码网推荐 29 源代码网推荐 30 源代码网推荐 31 源代码网推荐 32 } 源代码网推荐 上面的代码则说明了如何删除临时文件,他运行在TemporaryFileJob上,类似于CS的Job定时执行线程的逻辑,请不明白这块的人去看看关于Teligent.Tasks的分析文章。首先是获取特定目录下的全部后缀为meta的文件,然后以xml的方式打开查找到createdDate信息,一旦发现过期20分钟的文件,则自动删除。 源代码网推荐 源代码网推荐 下面的代码则解释了如何使用上面的临时文件管理架构。 源代码网推荐 源代码网推荐 源代码网推荐 源代码网推荐 1 protected List<string> PhotoKeys 源代码网推荐 2 { 源代码网推荐 3 get 源代码网推荐 4 { 源代码网推荐 5 if (ViewState["PhotoKeys"] == null) 源代码网推荐 6 ViewState["PhotoKeys"] = new List<string>(); 源代码网推荐 7 源代码网推荐 8 return (List<string>)ViewState["PhotoKeys"]; 源代码网推荐 9 } 源代码网推荐 10 } 源代码网推荐 11 源代码网推荐 12 #endregion 源代码网推荐 13 源代码网推荐 14 protected void Page_Load(object sender, EventArgs e) 源代码网推荐 15 { 源代码网推荐 16 源代码网推荐 17 } 源代码网推荐 18 源代码网推荐 19 protected void CheckBox1_CheckedChanged(object sender, EventArgs e) 源代码网推荐 20 { 源代码网推荐 21 源代码网推荐 22 } 源代码网推荐 23 源代码网推荐 24 protected void UploadPhotoButton_Click(object sender, EventArgs e) 源代码网推荐 25 { 源代码网推荐 26 if (eventPhotoUpload.PostedFile.ContentLength <= 0) 源代码网推荐 27 { 源代码网推荐 28 Label_AddPhotoMessage.Text = "请先选择要上传的文件"; 源代码网推荐 29 return; 源代码网推荐 30 } 源代码网推荐 31 源代码网推荐 32 if (eventPhotoUpload.PostedFile.ContentLength > 1024 * 1024 * 4) 源代码网推荐 33 { 源代码网推荐 34 Label_AddPhotoMessage.Text = "抱歉,照片文件限制在4M以下"; 源代码网推荐 35 return; 源代码网推荐 36 } 源代码网推荐 37 源代码网推荐 38 //保存文件 源代码网推荐 39 string key = Guid.NewGuid().ToString(); 源代码网推荐 40 FileInfo file = new FileInfo(eventPhotoUpload.PostedFile); 源代码网推荐 41 源代码网推荐 42 TemporaryManager.Insert(key, file); 源代码网推荐 43 源代码网推荐 44 this.PhotoKeys.Add("t_" + key); 源代码网推荐 45 源代码网推荐 46 BindEventPhotos(); 源代码网推荐 47 } 源代码网推荐 48 源代码网推荐 49 private void BindEventPhotos() 源代码网推荐 50 { 源代码网推荐 51 List<FileMetaData> files = new List<FileMetaData>(); 源代码网推荐 52 foreach (string key in PhotoKeys) 源代码网推荐 53 { 源代码网推荐 54 bool isTemp = key.StartsWith("t_"); 源代码网推荐 55 string filekey = key.Substring(2); 源代码网推荐 56 if (isTemp) 源代码网推荐 57 { 源代码网推荐 58 files.Add(TemporaryManager.GetTemporaryFileMetaData(filekey)); 源代码网推荐 59 } 源代码网推荐 60 } 源代码网推荐 61 源代码网推荐 62 this.PhotoList.DataSource = files; 源代码网推荐 63 this.PhotoList.DataBind(); 源代码网推荐 64 }上面的代码是指把图片标识保存到以ViewState为存储后台的string类型的列表中,采用string类型的原因是我想在临时文件的标识前加"t_"以提高文件的获取效率。 源代码网推荐 而BindEventPhotos则会根据标识是否有前缀"t_"来判断是从正式图片目录(或者数据库)还是临时文件目录来提取图片信息。 源代码网推荐 源代码网推荐 恩,因为博客园不能放附件的问题,所以需要代码的请收藏该页,待我整理好后即会更新此页面。 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
