Как лучше всего перебирать папки и подпапки, чтобы получить размер файла, общее количество файлов и общий размер папки в каждой папке, начиная с указанного места?
Лучший способ перебирать папки и подпапки
Ответы (6)
Используйте Directory.GetFiles(). В нижней части этой страницы приведен полностью рекурсивный пример.
Примечание. Используйте приведенный ниже ответ Криса Данауэя для более современного подхода при использовании .NET 4 и выше.
// For Directory.GetFiles and Directory.GetDirectories
// For File.Exists, Directory.Exists
using System;
using System.IO;
using System.Collections;
public class RecursiveFileProcessor
{
public static void Main(string[] args)
{
foreach(string path in args)
{
if(File.Exists(path))
{
// This path is a file
ProcessFile(path);
}
else if(Directory.Exists(path))
{
// This path is a directory
ProcessDirectory(path);
}
else
{
Console.WriteLine("{0} is not a valid file or directory.", path);
}
}
}
// Process all files in the directory passed in, recurse on any directories
// that are found, and process the files they contain.
public static void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
ProcessFile(fileName);
// Recurse into subdirectories of this directory.
string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach(string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
}
// Insert logic for processing found files here.
public static void ProcessFile(string path)
{
Console.WriteLine("Processed file '{0}'.", path);
}
}
dir и перенаправить вывод и проанализировать его (или передать в файл и прочитать его). Конечно, я не рассматриваю это, если не ожидаю более 50 000 файлов в одном каталоге.
- person quentin-starin; 14.05.2011
FindFirstFile и т. д. вместо использования dir, хотя я уверен, что .NET все равно с этим справляется.
- person Lloyd; 15.01.2013
Если вы используете .NET 4, вы можете использовать методы System.IO.DirectoryInfo.EnumerateDirectories и System.IO.DirectoryInfo.EnumerateFiles. Если вы используете метод Directory.GetFiles, как рекомендовали другие сообщения, вызов метода не вернется, пока он не получит ВСЕ записи. Это может занять много времени, если вы используете рекурсию.
Из документации:
Методы
EnumerateFilesиGetFilesразличаются следующим образом:
- Когда вы используете
EnumerateFiles, вы можете начать перечисление коллекции объектовFileInfoдо того, как будет возвращена вся коллекция.- Когда вы используете
GetFiles, вы должны дождаться возврата всего массива объектовFileInfo, прежде чем вы сможете получить доступ к массиву.Поэтому, когда вы работаете с большим количеством файлов и каталогов,
EnumerateFilesможет быть более эффективным.
Для перебора всех каталогов, подпапок и файлов, независимо от того, сколько подпапок и файлов.
string [] filenames;
fname = Directory.GetFiles(jak, "*.*", SearchOption.AllDirectories).Select(x => Path.GetFileName(x)).ToArray();
затем из массива вы можете получить то, что хотите, через цикл или как хотите.
Для просмотра файлов и папок обычно используются DirectoryInfo и FileInfo. Тип FileInfo имеет свойство Length, которое возвращает размер файла в байтах.
Я думаю, что вы должны написать свой собственный код для перебора файлов и вычисления общего размера файла, но это должна быть довольно простая рекурсивная функция.
Обратите внимание, что вам нужно будет выполнить проверки проверки.
string[] fileNames = Directory.GetFiles("c:\\", "*.*", SearchOption.AllDirectories);
int fileCount = fileNames.Count();
long fileSize = fileNames.Select(file => new FileInfo(file).Length).Sum(); // in bytes
Directory.Exists (иначе DirectoryNotFoundException). Я не могу думать ни о чем другом, но, возможно, я что-то упустил.
- person HuBeZa; 03.03.2011
Вот пример использования предложения Питера выше и рекурсии.
using System;
using System.IO;
namespace FileSystemUtils
{
class Program
{
static void Main(string[] args)
{
string folderPath = "C:\\docs";
DirectoryInfo startDir = new DirectoryInfo(folderPath);
RecurseFileStructure recurseFileStructure = new RecurseFileStructure();
recurseFileStructure.TraverseDirectory(startDir);
}
public class RecurseFileStructure
{
public void TraverseDirectory(DirectoryInfo directoryInfo)
{
var subdirectories = directoryInfo.EnumerateDirectories();
foreach (var subdirectory in subdirectories)
{
TraverseDirectory(subdirectory);
}
var files = directoryInfo.EnumerateFiles();
foreach (var file in files)
{
HandleFile(file);
}
}
void HandleFile(FileInfo file)
{
Console.WriteLine("{0}", file.Name);
}
}
}
}