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

Reply via email to