Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Fopen, fseek, fwrite for large files
Message
De
14/08/2007 14:19:06
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Fonctions Windows API
Versions des environnements
Visual FoxPro:
VFP 9 SP1
OS:
Windows XP SP2
Divers
Thread ID:
01247944
Message ID:
01248112
Vues:
23
>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
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform