Get size and dates of a file with one call

Just starting out? Need help? Post your questions and find answers here.
Lebostein
Addict
Addict
Posts: 807
Joined: Fri Jun 11, 2004 7:07 am

Re: Get size and dates of a file with one call

Post by Lebostein »

I have tried the 3 versions with 1727 files:

with stat64 = 12 ms
with PB-functions = 46 ms
with Directory = 29 ms

It seems the Directory-Thing is slower then expected....

Code: Select all

ImportC "": stat64(path.p-utf8, *buf): EndImport
Global Dim buf.q(17); 144 bytes = 18 * 8

Structure stats

  size.q
  atime.q
  mtime.q
  ctime.q

EndStructure

Procedure GetFileStats(directory, *stats.stats, file.s = #Empty$)

  Select directory
  Case -1
    stat64(file, @buf())
    *stats\size  = buf(12)
    *stats\atime = buf(4)
    *stats\mtime = buf(6)
    *stats\ctime = buf(10)
  Case -2
    *stats\size  = FileSize(file)
    *stats\atime = GetFileDate(file, #PB_Date_Accessed)
    *stats\mtime = GetFileDate(file, #PB_Date_Modified)
    *stats\ctime = GetFileDate(file, #PB_Date_Created)
  Default
    *stats\size  = DirectoryEntrySize(directory)
    *stats\atime = DirectoryEntryDate(directory, #PB_Date_Accessed)
    *stats\mtime = DirectoryEntryDate(directory, #PB_Date_Modified)
    *stats\ctime = DirectoryEntryDate(directory, #PB_Date_Created)
  EndSelect

EndProcedure

Define version, directory, scanpath.s, start, filename.s, stats.stats

version = 1 ; 2 ; 3
scanpath.s = "/Volumes/BACKUP1/Fotos/"
directory = ExamineDirectory(#PB_Any, scanpath, "*")
start = ElapsedMilliseconds()
While NextDirectoryEntry(directory)
  filename.s = DirectoryEntryName(directory)
  If DirectoryEntryType(directory) = #PB_DirectoryEntry_File
    Select version
    Case 1: GetFileStats(-1, stats, scanpath + filename)
    Case 2: GetFileStats(-2, stats, scanpath + filename)
    Case 3: GetFileStats(directory, stats)
    EndSelect
  EndIf
Wend
MessageRequester("Result", Str(ElapsedMilliseconds() - start))
FinishDirectory(directory)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Get size and dates of a file with one call

Post by wilbert »

How is the performance of FindFirstFile/FindNextFile on Windows ?

Code: Select all

Procedure.q FileTimeToUnixTime(*ft.Quad)
  ProcedureReturn *ft\q / 10000000 - 11644473600  
EndProcedure

Define hFind, fd.WIN32_FIND_DATA

t1 = ElapsedMilliseconds()

hFind = FindFirstFile_("*", @fd)
If hFind <> #INVALID_HANDLE_VALUE
  Repeat
    If Not fd\dwFileAttributes & #FILE_ATTRIBUTE_DIRECTORY
      
      Debug "name  : " + PeekS( @fd\cFileName[0] )
      Debug "size  : " + Str( fd\nFileSizeHigh<<32|fd\nFileSizeLow )
      Debug FormatDate("atime: %yyyy/%mm/%dd %hh:%ii:%ss", FileTimeToUnixTime(@fd\ftLastAccessTime))
      Debug FormatDate("mtime: %yyyy/%mm/%dd %hh:%ii:%ss", FileTimeToUnixTime(@fd\ftLastWriteTime))
      Debug FormatDate("ctime : %yyyy/%mm/%dd %hh:%ii:%ss", FileTimeToUnixTime(@fd\ftCreationTime))
      
    EndIf
  Until FindNextFile_(hFind, @fd) = #False
  FindClose_(hFind)
EndIf

For processing a whole directory on MacOS, you could also use readdir

Code: Select all

; MacOS, PB x64

Structure dirent
  d_fileno.l
  d_reclen.u
  d_type.a
  d_namlen.a
  d_name.a[256]
EndStructure

ImportC ""
  opendir(name.p-utf8)
EndImport

Global Dim buf.q(17); 144 bytes = 18 * 8

dp = opendir(".")
If dp
  *ep.dirent = readdir_(dp)
  While *ep
    If *ep\d_type & 8; regular file
      stat64_(@*ep\d_name, @buf())
      
      Debug "name  : " + PeekS(@*ep\d_name, -1, #PB_UTF8)
      Debug "size  : " + Str(buf(12))
      Debug FormatDate("atime: %yyyy/%mm/%dd %hh:%ii:%ss", buf(4))
      Debug FormatDate("mtime: %yyyy/%mm/%dd %hh:%ii:%ss", buf(6))
      Debug FormatDate("ctime : %yyyy/%mm/%dd %hh:%ii:%ss", buf(10))
      
    EndIf
    *ep = readdir_(dp)
  Wend
  closedir_(dp)
EndIf
Windows (x64)
Raspberry Pi OS (Arm64)
Lebostein
Addict
Addict
Posts: 807
Joined: Fri Jun 11, 2004 7:07 am

Re: Get size and dates of a file with one call

Post by Lebostein »

Is there an equivalent for stat64 on Windows?
Post Reply