最近一直都很忙,非常抱歉好久沒有寫過博客了。最近遇到拷貝遠程文件的一些工作,比如我們發布的web站點的時候,開發提供一個zip壓縮包,我們需要上傳到遠程的服務器A,然后在部署(文件拷貝)到遠程環境B和C,ABC都在一個局域網里面。文件壓縮需要引用 System.IO.Compression和System.IO.Compression.FileSystem
首先我們需要一個工具類來轉換文件路徑,本地地址與遠程地址的轉換 比如192.168.0.1上的D:\test 轉換 為\\192.168.0.1\D$\test,文件路徑的拼接,
public class PathUtil { public static string GetRemotePath(string ip, string localPath) { if (!localPath.Contains(":")) { throw new Exception($"{localPath}路徑必須是全路徑且是本地路徑"); } localPath = localPath.Replace(":", "$"); return $@"\\{ip}\{localPath}"; } public static string GetLocaPath(string remotePath) { int index = remotePath.IndexOf("$"); if (index < 1) { throw new Exception($"{remotePath}路徑必須包含磁盤信息"); } string temp = remotePath.Substring(index - 1); temp = temp.Replace("$", ":"); return temp; } public static string Combine(string path1, string path2) { path1 = path1.Trim(); path2 = path2.Trim(); if (path1.EndsWith("\\") && path2.StartsWith("\\")) { string ret = (path1 + path2).Replace("\\", ""); return ret; } else if (!path1.EndsWith("\\") && !path2.StartsWith("\\")) { return path1 + "\\" + path2; } // if ((path1.EndsWith("\\") && !path2.StartsWith("\\")) || //(!path1.EndsWith("\\") && path2.StartsWith("\\"))) { } return path1 + path2; } }
備份遠程目錄的文件夾 (首先備份遠程A目錄到本地臨時文件zip->拷貝到遠程B->刪除本地臨時文件zip)
還原遠程文件(部署發布包)(遠程文件解壓到本地臨時目錄->拷貝到目標服務器->刪除本地臨時目錄)
文件夾得拷貝就比較簡單,遞歸調用文件復制就okay了,比如 \\192.168.0.1\D$\test 拷貝到 \\192.168.0.2\D$\test下 (建議先刪除存在文件在拷貝)。
相關code如下:
#region 文件操作部分 /// <summary> /// 把一個目錄下的文件拷貝的目標目錄下 /// </summary> /// <param name="sourceFolder">源目錄</param> /// <param name="targerFolder">目標目錄</param> /// <param name="removePrefix">移除文件名部分路徑</param> public void CopyFiles(string sourceFolder, string targerFolder, string removePrefix = "") { if (string.IsNullOrEmpty(removePrefix)) { removePrefix = sourceFolder; } if (!Directory.Exists(targerFolder)) { Directory.CreateDirectory(targerFolder); } DirectoryInfo directory = new DirectoryInfo(sourceFolder); //獲取目錄下的文件 FileInfo[] files = directory.GetFiles(); foreach (FileInfo item in files) { if (item.Name == "Thumbs.db") { continue; } string tempPath = item.FullName.Replace(removePrefix, string.Empty); tempPath = targerFolder + tempPath; FileInfo fileInfo = new FileInfo(tempPath); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } File.Delete(tempPath); item.CopyTo(tempPath, true); } //獲取目錄下的子目錄 DirectoryInfo[] directors = directory.GetDirectories(); foreach (var item in directors) { CopyFiles(item.FullName, targerFolder, removePrefix); } } /// <summary> /// 備份遠程文件夾為zip文件 /// </summary> /// <param name="sourceFolder">備份目錄</param> /// <param name="targertFile">目標文件</param> /// <returns></returns> public bool BackZip(string sourceFolder, string targertFile) { string tempfileName = PathUtil.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip"); bool ret = false; try { ZipFile.CreateFromDirectory(sourceFolder, tempfileName, CompressionLevel.Optimal, false); var parentDirect = (new FileInfo(targertFile)).Directory; if (!parentDirect.Exists) { parentDirect.Create(); } File.Copy(tempfileName, targertFile, true); ret = true; } catch (Exception ex) { throw new Exception($"備份目錄{sourceFolder}出錯{ex.Message}"); } finally { if (File.Exists(tempfileName)) { File.Delete(tempfileName); } } return ret; } /// <summary> /// 把遠程文件還原為遠程目錄 /// </summary> /// <param name="sourceFile">遠程文件</param> /// <param name="targetFolder">遠程目錄</param> /// <returns></returns> public bool RestoreZip(string sourceFile, string targetFolder) { string tempFolderName = PathUtil.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); bool ret = false; try { using (ZipArchive readZip = ZipFile.OpenRead(sourceFile)) { readZip.ExtractToDirectory(tempFolderName); } string copyFolder = tempFolderName; //if (!Directory.GetFiles(copyFolder).Any() && Directory.GetDirectories(copyFolder).Length == 1) //{ // copyFolder = Directory.GetDirectories(copyFolder)[0]; //} CopyFiles(copyFolder, targetFolder, copyFolder); ret = true; } catch (Exception ex) { throw new Exception($"發布文件{sourceFile}到{targetFolder}出錯{ex.Message}"); } finally { if (Directory.Exists(tempFolderName)) { Directory.Delete(tempFolderName, true); } } return ret; } #endregion