> Good Day !
>
> In recovering corrupted tables and indexes you can use the low level command like FOPEN(),FWRITE(),FREAD(),FGET() with this command you can recover the corrupted tables.
I just want to add the file structure as it now.
http://msdn2.microsoft.com/en-us/library/st4a0s68(VS.80).aspx (the link is up to .aspx) or "Table File Structure (.dbc, .dbf, .frx, .lbx, .mnx, .pjx, .scx, .vcx)" for the help.
The file consists of three main parts, said in simple words:
1) Static header - 32 bytes in which are described the main properties of the file -type, last modification, number of records, size of one record, the position of the first record and so on.
2) Dynamic part of the header - here are described the fields of the table - each field is discribed in 32 bytes, so the more fields you have the biggher header you get.
3) records - all the rest is the data
Knowing the exact possitions of each of these things we can get them with low level functions like FOPEN(),FWRITE(),FREAD(),FGET(), FSEEK() and replace the wrong ones.
Example:
lnHandle = FOPEN(pcFile) && Open file
IF lnHandle > 0
oErr = On("ERROR")
ON ERROR nErr=Error()
FSEEK(lnHandle,4,0) && Record Count is bytes 4-7 in dbf header (0 offset)
lcRecCnt = FREAD(lnHandle,4)
FSEEK(lnHandle,8,0) && First Record Pos is bytes 8-9 in dbf header (0 offset)
lcFirstRec = FREAD(lnHandle,2)
FSEEK(lnHandle,10,0) && Record Size is bytes 10-11 in dbf header (0 offset)
lcRecSize = FREAD(lnHandle,2)
FCLOSE(lnHandle)
ON ERROR &oErr
if nErr=0
lnRecCnt = BinStrToInt( lcRecCnt )
?'lnRecCnt ' + TRANSFORM(m.lnRecCnt)
lnFirstRec = BinStrToInt( lcFirstRec )
?'lnFirstRec '+ TRANSFORM(m.lnFirstRec)
lnRecSize = BinStrToInt( lcRecSize )
?'lnRecSize ' + TRANSFORM(m.lnRecSize )
lnActRecCnt = (lnFileSize-lnFirstRec-1)/lnRecSize
?'lnActRecCnt '+ TRANSFORM(m.lnActRecCnt)
endif
endif
FUNCTION BinStrToInt( pcStr )
LOCAL lnTot, lnI
lnTot = 0
for lnI = 1 to len(pcStr)
lnTot = lnTot + ASC(substr(pcStr,lnI)) * 256^(lnI-1)
endfor
RETURN lnTot
*!* lnTot = ASC(substr(lcRecCnt,1))
*!* lnTot = ASC(substr(lcRecCnt,2)) * 256 + lnTot
*!* lnTot = ASC(substr(lcRecCnt,3)) * 256^2 + lnTot
*!* lnTot = ASC(substr(lcRecCnt,4)) * 256^3 + lnTot
FUNCTION num2dword( lnValue )
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
LOCAL b0, b1, b2, b3
b3 = Int(lnValue/m2)
b2 = Int((lnValue - b3*m2)/m1)
b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)
ENDFUNC
*I found the code above on
http://fox.wikis.com/wc.dll?Wiki~UDFFixRecCount~VFP and changed the function for my specific needs.*
Most of the corruptions of the DBFs are becouse the header shows one number for the records in the table, while the size of the record part of the file devided by the size of one record shows another number. This usually is becouse the header number is 1 off the real count. All you need to do in this case is to corect it.
The worse scenario is when you calculate the actual count of the records and it is not integer.
Example - your record part of the file is 1000 bytes and each record is 100 bytes - gread! You have exactly 10 records. But if your record part is 1035 bytes with 100 bytes per record it means something had happened while writing the data.
You can truncate the file down to 1000 bytes and put the right numbers in the header and it should be ok, but I don't recommend this. Is the data, that was lost, important? IMHO this is not quite a question, neither it has correct answer. Keep the dammaged files, restore from backup and only if you don't have good one try to get data from the corrupted files.
But.....
as Ken Murphy said - THE BACKUP IS THE BEST ACTION AGAINS CURRUPTED DATA. The ups, the good network, the surge protectors, the good servers etc. - all of them just minimise the chanses, but some chance remain.
Do you want to ask my friends whose 4 HDD RAID blew up? All of the 4 HDDs blew up at the same time, which made the use of RAID zero. They have big hosting company and I know they keep their hardware well protected - with all possible gadgets, but ... sh1t happens.
I believe trying to repair or get data from corrupted files should be the last and desperate effort one should do.
There's nothing better than a good lie.
What we accept as order is only the overwhelming form of the chaos.