I'm trying to use the Win32::API module to access the native FindFirstFile() and FindNextFile() system calls. It's as a workaround to the File::Find module, because for some reason stat() is dreadfully slow on FAT32... Anyway, the Win32::API stuff works fine and returns all the file metadata I need, but there is one major problem: every time the program makes a Win32::API call, its memory footprint increases. This is bad, because the program needs to do lots of scans, and it needs to run for a very long time...
I'm not sure if this is a bug in the program, or in Win32::API. Hopefully somebody will be able to tell me if I'm doing anything wrong. A test program that exhibits the bad behavior is at the end of this message. You'll note that it uses Win32::API::Struct, which may or may not be the only way to make this work. I was thinking that a possible alternative would be to use pack() to manually create a buffer to pass to the win32 call. Not sure if that would work though... The FindNextFile() code is commented out, because just the initial FindFirstFile() is enough to cause the problem (when called multiple times, in a loop). Also, if it makes any difference, I'm using ActivePerl 5.8.4.810 on Win2000 Server. All included modules are the latest version available in PPM format. use strict; use warnings; use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; use Win32::API; #$Win32::API::DEBUG = 1; use constant ERROR_NO_MORE_FILES => 18; use constant INVALID_HANDLE_VALUE => -1; Win32::API::Struct->typedef('FILETIME', qw( DWORD dwLowDateTime; DWORD dwHighDateTime; )); Win32::API::Struct->typedef('WIN32_FIND_DATA', qw( DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; TCHAR cFileName[260]; TCHAR cAlternateFileName[14]; )); my $FindFirstFile = Win32::API->new('kernel32.dll', 'FindFirstFile', 'PS', 'N') or die $^E; my $FindNextFile = Win32::API->new('kernel32.dll', 'FindNextFile', 'NS', 'I') or die $^E; my $FindClose = Win32::API->new('kernel32.dll', 'FindClose', 'N', 'I') or die $^E; while (1) { DirList(@ARGV); print "\n----- Hit ENTER to continue -----\n"; <STDIN>; } sub DirList { my $searchDir = shift; my $FileInfo = Win32::API::Struct->new('WIN32_FIND_DATA'); my $searchHandle = $FindFirstFile->Call("$searchDir\\*", $FileInfo); die $^E if ($searchHandle == INVALID_HANDLE_VALUE); # do { print 'filename = ',$FileInfo->{cFileName},"\n"; # print Dumper($FileInfo); # } while (my $result = $FindNextFile->Call($searchHandle, $FileInfo)); # # if (Win32::GetLastError() != ERROR_NO_MORE_FILES) { # die $^E; # } $FindClose->Call($searchHandle) or die $^E; } _______________________________________________ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs