0
votes

I've opened a file with CreateFile and passed that handle into both GetFileSizeEx and SetFilePointerEx which can both be used to get the file size. I then need to use ReadFile or ReadFileEx to read in the data from the whole file into a buffer.

The problem I'm having is that GetFileSizeEx and SetFilePointerEx both provide the file size as a LARGE_INTEGER type but ReadFile takes a DWORD for the number of bytes to read. Is there some workaround for this?

1
Rather than read the file into a user allocated buffer, consider using CreateFileMapping() and MapViewOfFile() to map a memory pointer to the file data. CreateFileMapping() supports files more than 4GB, and on 64bit Windows MapViewOfFile() can access more than 4GB of data at a time. Though, you really shouldn't be using that much sequential memory at one time to begin with, even with a user allocated buffer. There are better ways to work with large amounts of data using smaller amounts of memory.Remy Lebeau
@remy consider transforming your comment into an answer. I would like to see file mapping under windows.machine_1

1 Answers

4
votes

Yes. Both ReadFile and ReadFileEx take a DWORD as parameter. I guess that's because Microsoft considered it to be unlikely to read more than 4GB at once.

The common approach is using the LowPart of the LARGE_INTEGER union which is of type DWORD.

Of course you have to check manually that the size of the file is less than 4GB that means that HighPart is zero. If it's not then you have to perform multiple calls to ReadFile.

For example:

LARGE_INTEGER li;
DWORD actuallyRead;
LPVOID lpBuf;
... (fills li and lpBuf) ...
result = ReadFileEx(
           hFile,
           lpBuf,
           li.LowPart,
           &actuallyRead,
           NULL
         );