最近学者使用FileSystemWatcher组件,自己写了一个小服务程序,让其一直监视着收藏夹并将该文件夹内的所有内容同步到其它盘符下的一个文件夹。这样做的原因是几次重装系统都忘了备份收藏夹,导致后来很多链接都没有了,非常苦恼。现在不怕了呵呵!在使用FileSystemWatcher的过程中发现System.IO并没有提供Directory.Copy()这样的方法,于是试着写了2个。
第一个是递归调用的,即A:首先判断源文件夹下是否有文件?B:有,则拷贝所有文件到目的文件夹C:否则判断是否有文件夹,如有就重复A、B、C,如果没有就退出递归。注意,在复制文件的时候要考虑到3个问题:即源文件是否可读?目标文件路径的上一级文件夹是否存在?如果存在文件夹,那么存不存在同名文件?解决这三个问题就好办了:
递归法:
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中不失为一种改善,初步测试发现在拷贝多层文件夹大量小文件时有优势。代码如下:
/// <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;
}
还有一个判断文件是否可读的方法,参看网上的介绍:
/// <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;
}
完整代就不用列出来了,希望有用哦。