Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Fopen, fseek, fwrite for large files
Message
From
14/08/2007 14:19:06
 
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Environment versions
Visual FoxPro:
VFP 9 SP1
OS:
Windows XP SP2
Miscellaneous
Thread ID:
01247944
Message ID:
01248112
Views:
22
>Hi Carlos,
>
>>The problem is that I want to use SetFilePointerEx, I understand that I have to "split" the liDistanceToMove LARGE_INTEGER parameter into two 4 byte numbers
>
>VFP doesn't work with 64 bit integers very well. It uses 64 bit floating points internally, which have a different value range. Why do you have to split the numbers? If it's possible you should work with two 32 bit integer values all the time.

Hi Christof, thanks for your reply.

I want to use the SetFilePointerEx API function:


BOOL WINAPI SetFilePointerEx(
HANDLE hFile,
LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer,
DWORD dwMoveMethod
);


liDistanceToMove is a LARGE_INTEGER, defined as:


typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
lpNewFilePointer LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER,
*PLARGE_INTEGER;


The only thing I understand is that a large Integer uses 8 bytes, while an integer uses 4 bytes. Now the only way I found to pass liDistanceToMove to the API function is explained by Calvin Hsia:


DECLARE long SetFilePointerEx IN kernel32;
long hnd,;
long lDistanceToMoveL,;
long lDistanceToMoveH,;
string @lpNewFilePointer,;
long dwMoveMethod


The large integer is split into 2 integers, using:


lDistanceToMoveH = INT(lDistanceToMove/2^32)
lDistanceToMoveL = lDistanceToMove - lDistanceToMoveH * 2^32


But It seems that SET DECIMALS affect how lDistanceToMoveH is calculated for values near 4GB, so I used:


lDistanceToMoveL = lDistanceToMove % 2^32
lDistanceToMoveH = (lDistanceToMove - lDistanceToMoveL) / 2^32


That seems to work no matter what the value of SET DECIMALS is.

By the way, lpNewFilePointer is initialized as:


lpNewFilePointer = Replicate(Chr(0),8)


And I get the new file pointer position by doing:


m.lnLow = CToBin(Left(m.tcLargeInt, 4), "4rs")
m.lnHigh = CToBin(Right(m.tcLargeInt, 4), "4rs")

If m.lnLow < 0 Then
m.tnLow = m.tnLow + 2^32
Endif

If m.lnHigh < 0 Then
m.lnHigh = m.lnHigh + 2^32
Endif

m.lnLargeInt = m.lnLow + m.lnHigh * 2^32


I am pretty shure that m.lnLow has to be converted to unsigned, not so shure about m.lnHigh

Regarding the 64 bit floating point vs 64 bit integers, I understand value ranges are not the same, but it seems to work for what I need, I have only tested with files around 8GB

Carlos
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform