delphi – 计算目录大小API?

任何人都知道得到一个directoy的大小的其他方式,而不是通过计算文件的文件来计算它的大小? 我对一些win32 API函数感兴趣。 我已经谷歌关于这一点,但我没有find相关的信息,所以我在这里问。

PS:我知道如何通过使用findfirst和findnext来计算目录大小,并且总和所有文件的大小。

Solutions Collecting From Web of "delphi – 计算目录大小API?"

获取一个目录的大小是一个相当大的问题,主要是因为它是你无法定义的。 问题的例子:

  • 一些文件系统,包括Linux上的NTFS和大多数文件系统,都支持“硬链接”的概念。 也就是说,同一个文件可能会出现在多个地方。 软链接(重分析点)构成相同的问题。
  • Windows允许将文件系统挂载到目录。 例如:“C:\ DriveD”可能与“D:\”是一样的。
  • 你想在磁盘上的文件大小或文件的实际大小?
  • 你关心实际的目录条目吗? 他们也占用空间!
  • 你如何处理你无法访问的文件? 或者你没有权限浏览目录? 你数这些吗?

考虑到这一切意味着唯一可能的实现是递归实现。 你可以写你自己的,或者希望你找到一个现成的,但最终的表现将是一样的。

我不认为有这样的API。 我不认为Windows知道答案。 即它将不得不递归搜索树并使用Marcelo指出的技术来汇总每个文件夹。
如果有这样一个API调用可用,那么其他的东西也会使用它,Windows将能够立即告诉你文件夹的大小。

我已经有一个函数列出文件夹(和子文件夹)的文件和一个读取文件的大小。 所以,我只写了一个把这两个放在一起的小程序。

ListFilesOf

function ListFilesOf(CONST aFolder, FileType: string; CONST ReturnFullPath, DigSubdirectories: Boolean): TTSL; { If DigSubdirectories is false, it will return only the top level files, else it will return also the files in subdirectories of subdirectories. If FullPath is true the returned files will have full path. FileType can be something like '*.*' or '*.exe;*.bin' Will show also the Hidden/System files. Source Marco Cantu Delphi 2010 HandBook // Works with UNC paths} VAR i: Integer; s: string; SubFolders, filesList: TStringDynArray; MaskArray: TStringDynArray; Predicate: TDirectory.TFilterPredicate; procedure ListFiles(CONST aFolder: string); VAR strFile: string; begin Predicate:= function(const Path: string; const SearchRec: TSearchRec): Boolean VAR Mask: string; begin for Mask in MaskArray DO if System.Masks.MatchesMask(SearchRec.Name, Mask) then EXIT(TRUE); EXIT(FALSE); end; filesList:= TDirectory.GetFiles (aFolder, Predicate); for strFile in filesList DO if strFile<> '' { Bug undeva: imi intoarce doua intrari empty ('') } then Result.Add(strFile); end; begin { I need this in order to prevent the EPathTooLongException (reported by some users) } if aFolder.Length >= MAXPATH then begin MesajError('Path is longer than '+ IntToStr(MAXPATH)+ ' characters!'); EXIT(NIL); end; if NOT System.IOUtils.TDirectory.Exists (aFolder) then RAISE Exception.Create('Folder does not exist! '+ CRLF+ aFolder); Result:= TTSL.Create; { Split FileType in subcomponents } MaskArray:= System.StrUtils.SplitString(FileType, ';'); { Search the parent folder } ListFiles(aFolder); { Search in all subfolders } if DigSubdirectories then begin SubFolders:= TDirectory.GetDirectories(aFolder, TSearchOption.soAllDirectories, NIL); for s in SubFolders DO if cIO.DirectoryExists(s) { This solves the problem caused by broken 'Symbolic Link' folders } then ListFiles(s); end; { Remove full path } if NOT ReturnFullPath then for i:= 0 to Result.Count-1 DO Result[i]:= TPath.GetFileName(Result[i]); end; 

GetFileSize

 { Works with >4GB files Source: http://stackoverflow.com/questions/1642220/getting-size-of-a-file-in-delphi-2010-or-later } function GetFileSize(const aFilename: String): Int64; VAR info: TWin32FileAttributeData; begin if GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then Result:= Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32) else Result:= -1; end; 

最后:

 function GetFolderSize(aFolder: string; FileType: string= '*.*'; DigSubdirectories: Boolean= TRUE): Int64; VAR i: Integer; TSL: TTSL; begin Result:= 0; TSL:= ListFilesOf(aFolder, FileType, TRUE, DigSubdirectories); TRY for i:= 0 to TSL.Count-1 DO Result:= Result+ GetFileSize(TSL[i]); FINALLY FreeAndNil(TSL); END; end; 

注意:
1.您只能计算文件夹中某些文件类型的大小。 例如,在包含BMP和JPEG文件的文件夹中,如果您需要,只能获取BMP文件的文件夹大小。
2.支持多个文件类型,如下所示:'. bmp; 巴纽”。
3.您可以选择是否阅读或不确定子文件夹的大小。

进一步的改进 :通过消除GetFolderSize并将GetFileSize直接移动到ListFilesOf中,可以大量减少代码的大小

保证使用Delphi XE7。

如果你已经知道如何做另一个级别,只需使用递归来获得每个级别。 当你的函数遍历当前目录时,如果它出现在子目录中,则递归地调用该函数以获取该子目录的大小。

您可以使用FindFile组件。 它会递归你的目录。

http://www.delphiarea.com/products/delphi-components/findfile/

以前许多重复发现的例子首先查找下一个实现并不考虑更大的文件容量。 这些例子不会产生正确的结果。 提供适应更大文件容量的递归例程。

 {*----------------------------------------------------------------------------- Procedure: GetDirSize Author: archman Date: 21-May-2015 @Param dir: string; subdir: Boolean @Return Int64 -----------------------------------------------------------------------------} function TBCSDirSizeC.GetDirSize(dir: string; subdir: Boolean): Int64; var rec: TSearchRec; found: Integer; begin Result := 0; if dir[Length(dir)] <> '\' then dir := dir + '\'; found := FindFirst(dir + '*.*', faAnyFile, rec); while found = 0 do begin Inc(Result, rec.Size); if (rec.Attr and faDirectory > 0) and (rec.Name[1] <> '.') and (subdir = True) then Inc(Result, GetDirSize(dir + rec.Name, True)); found := FindNext(rec); end; System.SysUtils.FindClose(rec); end; 

请访问下面的链接,了解过程的完整说明。 http://bcsjava.com/blg/wordpress/2015/06/05/bcs-directory-size-delphi-xe8/