C# 备份、还原、拷贝远程文件夹

最近一直都很忙,非常抱歉好久没有写过博客了。最近遇到拷贝远程文件的一些工作,比如我们发布的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\test192.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
复制代码

 

posted on   dz45693  阅读(5432)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示