C#为IO操作补充文件夹复制小功能

最近学者使用FileSystemWatcher组件,自己写了一个小服务程序,让其一直监视着收藏夹并将该文件夹内的所有内容同步到其它盘符下的一个文件夹。这样做的原因是几次重装系统都忘了备份收藏夹,导致后来很多链接都没有了,非常苦恼。现在不怕了呵呵!在使用FileSystemWatcher的过程中发现System.IO并没有提供Directory.Copy()这样的方法,于是试着写了2个。

第一个是递归调用的,即A:首先判断源文件夹下是否有文件?B:有,则拷贝所有文件到目的文件夹C:否则判断是否有文件夹,如有就重复A、B、C,如果没有就退出递归。注意,在复制文件的时候要考虑到3个问题:即源文件是否可读?目标文件路径的上一级文件夹是否存在?如果存在文件夹,那么存不存在同名文件?解决这三个问题就好办了:

递归法:

ContractedBlock.gif ExpandedBlockStart.gif Code
        public static void Copy(string dir1, string dir2)
        {
            
//如果要被复制的文件夹不存在,程序返回。
            if (!Directory.Exists(dir1)) return;
            
//如果目标文件夹不存在,则创建它。
            if (!Directory.Exists(dir2)) Directory.CreateDirectory(dir2);
            
//给文件夹添加分隔符“\”               
            if (!dir1.EndsWith("\\")) dir1 += "\\";
            
if (!dir2.EndsWith("\\")) dir2 += "\\";
            
//复制文件。递归出口为当前目录下无文件。
            string[] files = Directory.GetFiles(dir1);
            
if (files.Length != 0)
            {
                
foreach (string f in files)

                    
if (!File.Exists(dir2 + Path.GetFileName(f)) && FileExt.CanOpen(f))
                    {
                        File.Copy(f, dir2 
+ Path.GetFileName(f));

                    }

            }
            
//复制子目录。递归出口为当前目录下无子目录。
            DirectoryInfo di = new DirectoryInfo(dir1);
            DirectoryInfo[] subdirsInfo 
= di.GetDirectories();
            
if (subdirsInfo.Length != 0)
            {
                
foreach (DirectoryInfo sdi in subdirsInfo)
                {
                    Copy(sdi.FullName, dir2 
+ sdi);
                }
            }

        }

第二中非递归法。算法上说了,所有的递归方法都可以改写为循环方法,这样改写的效率可能会有较大的提高,但是我还不会改写这个递归。看了微软的Directory.GetFiles(string path,string searchPattern,SearchOption.AllSubDirectories)还是很复杂的,果然不是递归获取所有文件。于是利用它首先取得dir1下的所有文件,然后将这些文件一个个地复制到dir2中不失为一种改善,初步测试发现在拷贝多层文件夹大量小文件时有优势。代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        /// <summary>
        
/// 复制dir1目录内的所有内容到dir2目录中。
        
/// </summary>
        
/// <param name="dir1">要被复制的目录。</param>
        
/// <param name="dir2">目标目录</param>
        
/// <returns>复制结果。成功为true,否则为false。</returns>
        public static bool Copy(string dir1, string dir2)
        {
            
bool res = false;
            
if (!dir1.EndsWith("\\")) dir1 += "\\";
            
if (!dir2.EndsWith("\\")) dir2 += "\\";
            
if (!Directory.Exists(dir2)) Directory.CreateDirectory(dir2);
            
string[] allFiles = GetAllFiles(dir1);
            
for (int j = 0; j < allFiles.Length; j++)
            {
                
string oldFileName = allFiles[j];
                //获取并判断存放第j个文件的件夹是否存在,如果不存在就创建它
                
string dirName = string.Format("{0}{1}", dir2, oldFileName.Substring(oldFileName.IndexOf('\\', dir1.Length - 1), oldFileName.LastIndexOf('\\'- dir1.Length + 2));
                
if (!Directory.Exists(dirName))
                    Directory.CreateDirectory(dirName);

                
if (FileExt.CanOpen(oldFileName) && !File.Exists(string.Format("{0}{1}", dirName, Path.GetFileName(oldFileName))))
                    File.Copy(oldFileName, 
string.Format("{0}{1}", dirName, Path.GetFileName(oldFileName)), true);
            }

            res 
= true;
            
return res;
        }

还有一个判断文件是否可读的方法,参看网上的介绍:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        /// <summary>
        
/// 文件是否可读。是否可操作。
        
/// </summary>
        
/// <param name="path">文件路径。</param>
        
/// <returns>能否操作。true、false。</returns>
        public static bool CanOpen(string path)
        {
            
bool canOpen = true;
            
try
            {
                FileStream fs 
= new FileStream(path, FileMode.Open);
                
if (fs != null)
                    fs.Close();
                fs.Dispose();
            }
            
catch
            {
                canOpen 
= false;
            }
            
return canOpen;
        }

完整代就不用列出来了,希望有用哦。

 

 

 

转载于:https://www.cnblogs.com/jf_dai/archive/2009/11/09/1599271.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值