检查是否有文件夹的文件 [英] Checking if folder has files

查看:155
本文介绍了检查是否有文件夹的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有计划,写入到数据库,文件夹满或空。现在,我使用

I have program which writes to database which folders are full or empty. Now I'm using

bool hasFiles=false;
(Directory.GetFiles(path).Length >0) ? hasFiles=true: hasFiles=false;



但它需要将近一小时,我不能这样做在这个时候任何事情。

but it takes almost one hour, and I can't do anything in this time.

有没有检查,如果文件夹中有任何文件中的任何最快的方法是什么?

Is there any fastest way to check if folder has any file ?

推荐答案

以加快这样的横网络搜索的关键是减少通过网络的请求数。而不是让所有的目录,然后检查每个的文件,试图让一切从一个电话。

The key to speeding up such a cross-network search is to cut down the number of requests across the network. Rather than getting all the directories, and then checking each for files, try and get everything from one call.

在.NET 3.5没有一个方法来递归得到所有文件和文件夹,所以你必须建立它自己(见下文)。在.NET 4中新的重载存在这种一步到位。

In .NET 3.5 there is no one method to recursively get all files and folders, so you have to build it yourself (see below). In .NET 4 new overloads exist to to this in one step.

使用的DirectoryInfo 人们也沾到信息是否。返回的名字是一个文件或目录,这减少了调用以及

Using DirectoryInfo one also gets information on whether the returned name is a file or directory, which cuts down calls as well.

这意味着分裂的所有目录和文件的列表变成是这样的:

This means splitting a list of all the directories and files becomes something like this:

struct AllDirectories {
  public List<string> DirectoriesWithoutFiles { get; set; }
  public List<string> DirectoriesWithFiles { get; set; }
}

static class FileSystemScanner {
  public AllDirectories DivideDirectories(string startingPath) {
    var startingDir = new DirectoryInfo(startingPath);

    // allContent IList<FileSystemInfo>
    var allContent = GetAllFileSystemObjects(startingDir);
    var allFiles = allContent.Where(f => !(f.Attributes & FileAttributes.Directory))
                             .Cast<FileInfo>();
    var dirs = allContent.Where(f => (f.Attributes & FileAttributes.Directory))
                         .Cast<DirectoryInfo>();
    var allDirs = new SortedList<DirectoryInfo>(dirs, new FileSystemInfoComparer());

    var res = new AllDirectories {
      DirectoriesWithFiles = new List<string>()
    };
    foreach (var file in allFiles) {
      var dirName = Path.GetDirectoryName(file.Name);
      if (allDirs.Remove(dirName)) {
        // Was removed, so first time this dir name seen.
        res.DirectoriesWithFiles.Add(dirName);
      }
    }
    // allDirs now just contains directories without files
    res.DirectoriesWithoutFiles = new List<String>(addDirs.Select(d => d.Name));
  }

  class FileSystemInfoComparer : IComparer<FileSystemInfo> {
    public int Compare(FileSystemInfo l, FileSystemInfo r) {
      return String.Compare(l.Name, r.Name, StringComparison.OrdinalIgnoreCase);
    }
  }
}



实施 GetAllFileSystemObjects 依赖于.NET版本。在.NET 4中,很容易:

Implementing GetAllFileSystemObjects depends on the .NET version. On .NET 4 it is very easy:

ILIst<FileSystemInfo> GetAllFileSystemObjects(DirectoryInfo root) {
  return root.GetFileSystemInfos("*.*", SearchOptions.AllDirectories);
}

在早期版本中,需要多一点的工作:

On earlier versions a little more work is needed:

ILIst<FileSystemInfo> GetAllFileSystemObjects(DirectoryInfo root) {
  var res = new List<FileSystemInfo>();
  var pending = new Queue<DirectoryInfo>(new [] { root });

  while (pending.Count > 0) {
    var dir = pending.Dequeue();
    var content = dir.GetFileSystemInfos();
    res.AddRange(content);
    foreach (var dir in content.Where(f => (f.Attributes & FileAttributes.Directory))
                               .Cast<DirectoryInfo>()) {
      pending.Enqueue(dir);
    }
  }

  return res;
}

这方法调用到文件系统中的几次越好,只有一次的。 NET 4或每个在早期版本中,允许网络客户端和服务器,以尽量减少底层的文件系统调用和网络往返次数目录。

This approach calls into the filesystem as few times as possible, just once on .NET 4 or once per directory on earlier versions, allowing the network client and server to minimise the number of underlying filesystem calls and network round trips.

获得 FileSystemInfo 实例有需要多个文件系统操作的缺点(我相信这是有点取决于操作系统),但每个名称的任何解决方案需要知道,如果它是一个文件或目录,所以这是不可以避免的在一定程度上(而不是诉诸 FindFileFirst函数 / FindNextFile / FindClose

Getting FileSystemInfo instances has the disadvantage of needing multiple file system operations (I believe this is somewhat OS dependent), but for each name any solution needs to know if it is a file or directory so this is not avoidable at some level (without resorting to P/Invoke of FindFileFirst/FindNextFile/FindClose).

除此之外,上面会用一个分区扩展方法简单:

Aside, the above would be easier with a partition extension method:

Tuple<IEnumerable<T>,IEnumerable<T>> Extensions.Partition<T>(
                                                 this IEnumerable<T> input,
                                                 Func<T,bool> parition);



编写偷懒将是一个有趣的练习(仅消耗输入过的之一,当一些迭代输出,而缓冲所述其他)。

Writing that to be lazy would be an interesting exercise (only consuming input when something iterates over one of the outputs, while buffering the other).

这篇关于检查是否有文件夹的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆