知识动手实践一次,就可以变成自己的了。不然一直是老师的,书本的。
这几天做了一个小小的项目,需要用到文件下载功能,期初想到只是单个的文件,后面想到如果很多文件怎么办?于是又想到文件压缩。几经波折实践,总是达到了我想要的效果了。现今把作为一个笔记记录下来,以便下次之用。
#region 物理路径和相对路径的转换 //本地路径转换成URL相对路径 public static string urlconvertor(string imagesurl1) { string tmpRootDir = HttpContext.Current.Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录 string imagesurl2 = imagesurl1.Replace(tmpRootDir, ""); //转换成相对路径 imagesurl2 = imagesurl2.Replace(@"", @"/"); //imagesurl2 = imagesurl2.Replace(@"Aspx_Uc/", @""); return imagesurl2; } //相对路径转换成服务器本地物理路径 public static string urlconvertorlocal(string imagesurl1) { string tmpRootDir = HttpContext.Current.Server.MapPath(System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录 string imagesurl2 = tmpRootDir + imagesurl1.Replace(@"/", @""); //转换成绝对路径 return imagesurl2; } #endregion /// <summary> /// 获取物理地址 /// </summary> public static string MapPathFile(string FileName) { return HttpContext.Current.Server.MapPath(FileName); } /// <summary> /// 普通下载 /// </summary> /// <param name="FileName">文件虚拟路径</param> public static bool DownLoadold(string FileName) { bool bools = false; string destFileName = FileName;// urlconvertor(FileName);// MapPathFile(FileName); if (File.Exists(destFileName)) { FileInfo fi = new FileInfo(destFileName); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.ClearHeaders(); HttpContext.Current.Response.Buffer = false; HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(Path.GetFileName(destFileName), System.Text.Encoding.UTF8)); HttpContext.Current.Response.AppendHeader("Content-Length", fi.Length.ToString()); HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.WriteFile(destFileName); HttpContext.Current.Response.Flush(); AiLvYou.Common.DownUnit.FilePicDelete(destFileName);//删除当前下载的文件 HttpContext.Current.Response.End(); bools = true; } return bools; }
//检查文件是否已经存在存在才下载 public static bool FileExists(string path) { bool ret = false; System.IO.FileInfo file = new System.IO.FileInfo(path); if (file.Exists) { ret = true; } return ret; } /// <summary> /// 删除单个文件 /// </summary> /// <param name="path"></param> /// <returns></returns> public static bool FilePicDelete(string path) { bool ret = false; System.IO.FileInfo file = new System.IO.FileInfo(path); if (file.Exists) { file.Delete(); ret = true; } //else //删除目录 //{ // Directory.Delete(file ); //} return ret; } /// <summary> /// 用递归方法删除文件夹目录及文件 /// </summary> /// <param name="dir">带文件夹名的路径</param> public static void DeleteFolder(string dir) { if (Directory.Exists(dir)) //如果存在这个文件夹删除之 { foreach (string d in Directory.GetFileSystemEntries(dir)) { if (File.Exists(d)) File.Delete(d); //直接删除其中的文件 else DeleteFolder(d); //递归删除子文件夹 } Directory.Delete(dir, true); //删除已空文件夹 } }
第一种压缩方法 用WinRAR 需要安装此软件 ,而且压缩了整个目录,目前还没有解决
//会有整个目录 public void RARsave(string patch, string rarPatch, string rarName) { String the_rar; RegistryKey the_Reg; Object the_Obj; String the_Info; ProcessStartInfo the_StartInfo; Process the_Process; try { the_Reg = Registry.ClassesRoot.OpenSubKey(@"WinRAR"); the_Obj = the_Reg.GetValue(""); the_rar = the_Obj.ToString(); the_Reg.Close(); the_rar = the_rar.Substring(1, the_rar.Length - 7); Directory.CreateDirectory(patch);//20151222 //命令参数 //the_Info = " a " + rarName + " " + @"C:Test?70821.txt"; //文件压缩 the_Info = " a " + rarName + " " + patch +" -r"; the_StartInfo = new ProcessStartInfo(); the_StartInfo.FileName = "WinRar";//the_rar; the_StartInfo.Arguments = the_Info; the_StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //打包文件存放目录 the_StartInfo.WorkingDirectory = rarPatch; the_Process = new Process(); the_Process.StartInfo = the_StartInfo; the_Process.Start(); the_Process.WaitForExit(); the_Process.Close(); } catch (Exception ex) { throw ex; } }
/**//**************************************** * 函数名称:CopyDir * 功能说明:将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。 * 参 数:srcPath:原始路径,aimPath:目标文件夹 * 调用示列: * string srcPath = Server.MapPath("test/"); * string aimPath = Server.MapPath("test1/"); * EC.FileObj.CopyDir(srcPath,aimPath); *****************************************/ /**//// <summary> /// 指定文件夹下面的所有内容copy到目标文件夹下面 /// </summary> /// <param name="srcPath">原始路径</param> /// <param name="aimPath">目标文件夹</param> public static void CopyDir(string srcPath, string aimPath) { try { // 检查目标目录是否以目录分割字符结束如果不是则添加之 if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar) aimPath += Path.DirectorySeparatorChar; // 判断目标目录是否存在如果不存在则新建之 if (!Directory.Exists(aimPath)) Directory.CreateDirectory(aimPath); // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组 //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法 //string[] fileList = Directory.GetFiles(srcPath); string[] fileList = Directory.GetFileSystemEntries(srcPath); //遍历所有的文件和目录 foreach (string file in fileList) { //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 if (Directory.Exists(file)) CopyDir(file, aimPath + Path.GetFileName(file)); //否则直接Copy文件 else File.Copy(file, aimPath + Path.GetFileName(file), true); } } catch (Exception ee) { throw new Exception(ee.ToString()); } }
使用代码:
protected void btndown_Click(object sender, EventArgs e) { string Folder = DateTime.Now.ToString("HHMMss"); string savefilepath = HttpContext.Current.Server.MapPath("/admin/ueditor/net/htmlfile/upload"); string savefilepath2 = HttpContext.Current.Server.MapPath("/admin/ueditor/net/htmlfile/upload/image"); string tempFolder = Path.Combine(savefilepath, Folder); Directory.CreateDirectory(tempFolder); CopyDir(savefilepath2, tempFolder); // RARsave(@"D:images", tempFolder, Folder);控制了解压目录但是没有文件 RARsave(tempFolder, tempFolder, Folder); }
第二种压缩方法,使用了 ICSharpCode.SharpZipLib.dll 文件。先下载,放到bin目录下,然后引用。
实现代码
/// <summary> /// 生成压缩文件 /// </summary> /// <param name="strZipPath">生成的zip文件的路径</param> /// <param name="strZipTopDirectoryPath">源文件的上级目录</param> /// <param name="intZipLevel">T压缩等级</param> /// <param name="strPassword">压缩包解压密码</param> /// <param name="filesOrDirectoriesPaths">源文件路径</param> /// <returns></returns> private bool Zip(string strZipPath, string strZipTopDirectoryPath, int intZipLevel, string strPassword, string[] filesOrDirectoriesPaths) { try { List<string> AllFilesPath = new List<string>(); if (filesOrDirectoriesPaths.Length > 0) // get all files path { for (int i = 0; i < filesOrDirectoriesPaths.Length; i++) { if (File.Exists(filesOrDirectoriesPaths[i])) { AllFilesPath.Add(filesOrDirectoriesPaths[i]); } else if (Directory.Exists(filesOrDirectoriesPaths[i])) { GetDirectoryFiles(filesOrDirectoriesPaths[i], AllFilesPath); } } } if (AllFilesPath.Count > 0) { ZipOutputStream zipOutputStream = new ZipOutputStream(File.Create(strZipPath)); zipOutputStream.SetLevel(intZipLevel); zipOutputStream.Password = strPassword; for (int i = 0; i < AllFilesPath.Count; i++) { string strFile = AllFilesPath[i].ToString(); try { if (strFile.Substring(strFile.Length - 1) == "") //folder { string strFileName = strFile.Replace(strZipTopDirectoryPath, ""); if (strFileName.StartsWith("")) { strFileName = strFileName.Substring(1); } ZipEntry entry = new ZipEntry(strFileName); entry.DateTime = DateTime.Now; zipOutputStream.PutNextEntry(entry); } else //file { FileStream fs = File.OpenRead(strFile); byte[] buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); string strFileName = strFile.Replace(strZipTopDirectoryPath, ""); if (strFileName.StartsWith("")) { strFileName = strFileName.Substring(0); } ZipEntry entry = new ZipEntry(strFileName); entry.DateTime = DateTime.Now; zipOutputStream.PutNextEntry(entry); zipOutputStream.Write(buffer, 0, buffer.Length); fs.Close(); fs.Dispose(); } } catch { continue; } } zipOutputStream.Finish(); zipOutputStream.Close(); return true; } else { return false; } } catch { return false; } } /// <summary> /// Gets the directory files. /// </summary> /// <param name="strParentDirectoryPath">源文件路径</param> /// <param name="AllFilesPath">所有文件路径</param> private void GetDirectoryFiles(string strParentDirectoryPath, List<string> AllFilesPath) { string[] files = Directory.GetFiles(strParentDirectoryPath); for (int i = 0; i < files.Length; i++) { AllFilesPath.Add(files[i]); } string[] directorys = Directory.GetDirectories(strParentDirectoryPath); for (int i = 0; i < directorys.Length; i++) { GetDirectoryFiles(directorys[i], AllFilesPath); } if (files.Length == 0 && directorys.Length == 0) //empty folder { AllFilesPath.Add(strParentDirectoryPath); } }
调用代码:
protected void btndowmload_Click(object sender, EventArgs e) { //http://www.cnblogs.com/LYunF/archive/2012/02/18/2357591.html string Folder = DateTime.Now.ToString("HHMMss"); string savefilepath = HttpContext.Current.Server.MapPath("/admin/ueditor/net/htmlfile/upload"); string savefilepath2 = HttpContext.Current.Server.MapPath("/admin/ueditor/net/htmlfile/upload/image"); // 判断目标目录是否存在如果不存在则新建之 /* string newfilepath = Path.Combine(savefilepath, Folder); if (!Directory.Exists(newfilepath)) Directory.CreateDirectory(newfilepath);//问题目录问题 string newfilepath2 = HttpContext.Current.Server.MapPath("/admin/ueditor/net/htmlfile/upload"+"/"+Folder); string strZipTopDirectoryPath = newfilepath2; string tempFolder = Path.Combine(newfilepath2, Folder); */ string tempFolder = Path.Combine(savefilepath, Folder); string strZipTopDirectoryPath = savefilepath; string strZipPath = tempFolder + ".zip"; int intZipLevel = 6; string strPassword = ""; string[] filesOrDirectoriesPaths = new string[] { savefilepath2 }; bool flag = Zip(strZipPath, strZipTopDirectoryPath, intZipLevel, strPassword, filesOrDirectoriesPaths); if (flag) { ResponseFile(strZipPath); } }
下载代码:
protected void ResponseFile(string fileName) { FileInfo fileInfo = new FileInfo(fileName); Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); // Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); //upload 这里可以改变下载名称 Response.AddHeader("Content-Disposition", "attachment;filename=upload.zip"); // Response.AddHeader("Content-Length", fileInfo.Length.ToString()); Response.AddHeader("Content-Transfer-Encoding", "binary"); Response.ContentType = "application/octet-stream"; Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); Response.WriteFile(fileInfo.FullName); Response.Flush(); // string tempPath = fileName.Substring(0, fileName.LastIndexOf("\")); AiLvYou.Common.DownUnit.FilePicDelete(fileName); // Directory.Delete(tempPath); Response.End(); }