8

我有这段代码可以将所有文件从源目录复制F:\到目标目录。

public void Copy(string sourceDir, string targetDir)
{
  //Exception occurs at this line.
    string[] files = System.IO.Directory.GetFiles(sourceDir, "*.jpg", 
                                             SearchOption.AllDirectories);

    foreach (string srcPath in files)
    {
       File.Copy(srcPath, srcPath.Replace(sourceDir, targetDir), true);
    }
}

并获得例外。

如果我省略SearchOption.AllDirectories并且它可以工作但只复制文件F:\

4

4 回答 4

5

使用以下函数代替 System.IO.Directory.GetFiles:

IEnumerable<String> GetAllFiles(string path, string searchPattern)
    {
        return System.IO.Directory.EnumerateFiles(path, searchPattern).Union(
            System.IO.Directory.EnumerateDirectories(path).SelectMany(d =>
            {
                try
                {
                    return GetAllFiles(d,searchPattern);
                }
                catch (UnauthorizedAccessException e)
                {
                    return Enumerable.Empty<String>();
                }
            }));
    }
于 2015-02-19T16:22:50.077 回答
2

文件系统对象受制于安全性。某些文件系统对象的安全性使得它们只能由某些用户访问。您遇到执行代码的用户没有足够权限访问的文件。

您无权访问此特定文件夹的原因是为了保护系统上不同用户的安全。有问题的文件夹是该驱动器上的回收站。每个不同的用户都有自己的私人回收站,只有他们有权访问。如果任何人都可以访问任何其他用户的回收站,那么用户将能够读取彼此的文件,这明显违反了系统的安全策略。

解决此问题的最简单方法可能是跳过驱动器根级别的隐藏文件夹。这个简单的更改足以解决您的问题,因为您肯定不想复制回收站。

于 2014-03-18T09:57:15.993 回答
0

该文件夹是一个安全的系统文件夹(您的 bin,每个驱动器都有自己的 bin)。只需将您的 file.copy 放入 try catch 语句并忽略/记录所有失败。这样,您将只复制实际文件并跳过系统文件/文件夹。

如果你真的想避免 try catch 语句。使用 fileinfo 和 directory info 类来确定哪些文件夹/文件属于系统并将引发异常。

于 2014-03-18T09:53:38.287 回答
0

这应该可以解决问题:

private IEnumerable<string> RecursiveFileSearch(string path, string pattern, ICollection<string> filePathCollector = null)
{
    try
    {
        filePathCollector = filePathCollector ?? new LinkedList<string>();

        var matchingFilePaths = Directory.GetFiles(path, pattern);

        foreach(var matchingFile in matchingFilePaths)
        {
            filePathCollector.Add(matchingFile);
        }

        var subDirectories = Directory.EnumerateDirectories(path);

        foreach (var subDirectory in subDirectories)
        {
            RecursiveFileSearch(subDirectory, pattern, filePathCollector);
        }

        return filePathCollector;
    }
    catch (Exception error)
    {
        bool isIgnorableError = error is PathTooLongException ||
            error is UnauthorizedAccessException;

        if (isIgnorableError)
        {
            return Enumerable.Empty<string>();
        }

        throw error;
    }
}
于 2019-12-12T14:38:55.933 回答