Я должен вычислить размер каталога в .NET VB
Я знаю следующие 2 метода
Метод 1: из MSDN http://msdn.microsoft.com/en-us/library/system.io.directory.aspx
'Следующий пример вычисляет размер каталога' и его подкаталогов, если таковые имеются, и отображает общий размер 'в байтах.
Imports System
Imports System.IO
Public Class ShowDirSize
Public Shared Function DirSize(ByVal d As DirectoryInfo) As Long
Dim Size As Long = 0
' Add file sizes.
Dim fis As FileInfo() = d.GetFiles()
Dim fi As FileInfo
For Each fi In fis
Size += fi.Length
Next fi
' Add subdirectory sizes.
Dim dis As DirectoryInfo() = d.GetDirectories()
Dim di As DirectoryInfo
For Each di In dis
Size += DirSize(di)
Next di
Return Size
End Function 'DirSize
Public Shared Sub Main(ByVal args() As String)
If args.Length <> 1 Then
Console.WriteLine("You must provide a directory argument at the command line.")
Else
Dim d As New DirectoryInfo(args(0))
Dim dsize As Long = DirSize(d)
Console.WriteLine("The size of {0} and its subdirectories is {1} bytes.", d, dsize)
End If
End Sub 'Main
End Class 'ShowDirSize
Метод 2: от Какого лучший способ состоит в том, чтобы вычислить размер каталога в.NET?
Dim size As Int64 = (From strFile In My.Computer.FileSystem.GetFiles(strFolder, _
FileIO.SearchOption.SearchAllSubDirectories) _
Select New System.IO.FileInfo(strFile).Length).Sum()
Оба этих метода хорошо работают. Однако они берут партию времени для вычисления размера каталога, если существует партия подпапок. например, у меня есть каталог с 150 000 подпапок. Вышеупомянутые методы заняли приблизительно 1 час 30 минут для вычисления размера каталога. Однако, если я проверяю размер из окон, требуется меньше чем минута.
Предложите лучше и более быстрые способы вычислить размер каталога.
Хотя в этом ответе речь идет о Python, концепция применима и здесь.
Проводник Windows использует системные вызовы API FindFirstFile
и FindNextFile
рекурсивно для получения информации о файлах, а затем может получить доступ к размерам файлов очень быстро через данные, которые передаются обратно через struct
, WIN32_FIND_DATA
: http://msdn.microsoft.com/en-us/library/aa365740(v=VS.85).aspx.
Мое предложение - реализовать эти вызовы API с помощью P/Invoke, и я верю, что вы получите значительный прирост производительности.
Параллельное выполнение работы должно ускорить ее, по крайней мере, на многоядерных машинах. Попробуйте этот код C #. Вам нужно будет перевести для VB.NET.
private static long DirSize(string sourceDir, bool recurse)
{
long size = 0;
string[] fileEntries = Directory.GetFiles(sourceDir);
foreach (string fileName in fileEntries)
{
Interlocked.Add(ref size, (new FileInfo(fileName)).Length);
}
if (recurse)
{
string[] subdirEntries = Directory.GetDirectories(sourceDir);
Parallel.For<long>(0, subdirEntries.Length, () => 0, (i, loop, subtotal) =>
{
if ((File.GetAttributes(subdirEntries[i]) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
subtotal += DirSize(subdirEntries[i], true);
return subtotal;
}
return 0;
},
(x) => Interlocked.Add(ref size, x)
);
}
return size;
}