C# 如何递归判断目录下的文件是否有大小为0的情况

求教 ① 给定一个父目录 X,
然后检查 X 目录下面的文件,
如果有文件大小为 0,就返回 false,
如果没有大小为 0 的,就返回 true。
就算没有文件也返回 true。
(只用来检查文件大小是否为 0,而不在乎这个目录下面有不有文件)

② 但是这个父 X 目录下可能还有子目录 A,B,C,
子目录 A 中又可能包含孙目录 A1,A2,A3。
这些目录中可能都有文件。
不管他们有这些目录以及目录的后代总共有多少个目录,
反正就只检查这些目录下有不有文件大小为 0 的。
如果全部都没有 0 的,返回 true;如果有文件为 0 的,哪怕只有一个,返回 false。

---以上是原问题---
修改

-------------------------------------------------------
-如果全部都没有 0 的,返回 true;如果有文件为 0 的,哪怕只有一个,返回 false。
+如果全部都没有 0 的,返回 true;如果有文件大小为 0 的,哪怕只有一个,返回 false。
-------------------------------------------------------
// 检查文件大小是否为 0,文件为 0,返回 false
bool Check0 (string file) {
    FileInfo fi = new FileInfo (file);
    if (fi.Length == 0) return false;
    return true;
}

// 检查目录下,是否有文件大小为0,有文件为0,返回 false
bool Check1 (string folder) {
    string[] files = Directory.GetFiles(folder);
    if (files.Length == 0) return true; // 如果没有文件,返回 true
    foreach (string file in files) {
        // 遍历目录下的文件
        if (Check0(file))
        {
            continue;
        }
        else {
            return false;
        }
    }
    return true; // 如果目录下没有文件,也算是正确的,只针对有不有文件为0检查
}

bool CheckChilder(string folder) {
    // 检查是不是有子目录
    string[] subFolders = Directory.GetDirectories(folder);
    return subFolders.Length > 0;
}

// 检查当前目录中,所有存在的文件,是否有文件为0的。
bool Check2 (string folder) {
    // 先检查当前目录下的文件
    if (!Check1(folder)) return false;
    // 当前目录下的文件没有问题,进行下一步
    // 判断是否有子目录
    if (!CheckChilder(folder)) return true;
    // 有子目录
    string[] subFolders = Directory.GetDirectories(folder);
    foreach (string subFolder in subFolders) {
        if (!Check1(subFolder)) return false;
        if (!CheckChilder(subFolder)) continue;
        // TODO有子目录 的情况,不会写了
    }
}
// Console.WriteLine(Check2(@"C:\Users\Administrator\Desktop\3CUV34154.5\"));

以上代码写得可能本身就有问题,求完善
假设目录结构是这样的
e3f2a6bd61c890edeb6dba9b5801a2c.png
然后要检查 /3CUV34154.5 这个大的目录

阅读 3k
2 个回答

三个条件:

  1. 如果存在空文件,返回 false
  2. 如果没有文件,返回 true
  3. 如果不存在空文件,返回 true

其中 2、3 可以合并为:不存在空文件(也包含不存在文件)返回 true。

考虑到存在递归遍历的情况,所以写一个检查是否存在空文件的函数,将结果取反就能得到答案。所以下面的代码不用改,但是要对最终结果取返。

bool CheckEmptyFile(string folder)
{
    if (Directory.GetFiles(folder)
        .Any(file => new FileInfo(file).Length == 0))
    {
        return true;
    }

    return Directory.GetDirectories(folder)
        .Any(dir => CheckEmptyFile(dir));
}

这里用的 Any 是 Linq 扩展提供的方法,意思是判断集合中是否存在一个符合指定条件的项。

如果改用常规则的 foreach 来写就是

bool CheckEmptyFile(string folder)
{
    foreach (var file in Directory.GetFiles(folder))
    {
        if (new FileInfo(file).Length == 0)
        {
            return true;
        }
    }

    foreach (var dir in Directory.GetDirectories(folder))
    {
        if (CheckEmptyFile(dir))
        {
            return true;
        }
    }

    return false;
}

如果要确实按题目检查不存在空文件的文件夹,可以把判断逻辑反过来,写个 CheckNoEmptyFile

bool CheckNoEmptyFile(string folder)
{
    foreach (var file in Directory.GetFiles(folder))
    {
        if (new FileInfo(file).Length == 0)
        {
            return false;
        }
    }

    foreach (var dir in Directory.GetDirectories(folder))
    {
        if (!CheckNoEmptyFile(dir))
        {
            return false;
        }
    }

    return true;
}

Linq 版

bool CheckNoEmptyFile(string folder)
{
    if (Directory.GetFiles(folder)
        .Any(file => new FileInfo(file).Length == 0))
    {
        // 只要有空文件,就返回 false
        return false;
    }

    // 所以子目录(递归)都没有空文件,才返回 true
    return Directory.GetDirectories(folder)
        .All(dir => CheckNoEmptyFile(dir));
}

你这是某种练习还是项目需求?

如果是项目需求,用不着递归这么麻烦,Directory.GetFiles 有第二个参数可以指定的,可以直接拿到所有后代目录的文件的。

using System.IO;
using System.Linq;

bool Check(string folder) {
    DirectoryInfo directory = new DirectoryInfo(folder);
    FileInfo[] files = directory.GetFiles("*", SearchOption.AllDirectories);
    return files.Length == 0 || !files.Any(f => f.Length == 0);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进