[VXCMD] Offset not being applied in Binary_ReadData?
Rodney Tamblyn
rodneytamblyn at paradise.net.nz
Thu Feb 13 16:12:40 CST 2003
Ruslan,
Yes Valentina Binary_Read works fine now with large binary objects.
Some notes:
1) It's imperative to read from offset 0 otherwise you'll miss the
first char of the data. Metacard read/write commands are normally 1
relative (eg in Metacard: read from file myFile at 0 ... will return a
seek error)
2) You must check the size first and only read the right amount of
data. Valentina will return data if you read more (junk) ... ie it
won't just evaluate to empty.
Here's an example script. I use wrappers around the various Valentina
calls to ensure they are appropriately formatted (eg DB_GetDataSize)
etc...
Rodney
--Example MC function which given a cursor and a field name and an
(optional) file , will write a large binary file from Blob to file or
new temporary file.
#saves a blob file to an external file
function DB_ExportFile pCurs,pFldNm,pFile
local tData,tFldRef,tRead,tLength
#chk Valentina version is greater than 1.9.7b10
if not DB_SupportRead() then
answer "ExportFile - Sorry, only supported in 1.9.6b10 and later..."
exit DB_ExportFile
end if
#chk file to write to
if pFile is empty then put tempName() into pFile
#open file
open file pFile for binary write
get the result
if it <> empty then
devErr the params && it
exit DB_ExportFile
end if
#Note - read is 0 relative, unlike MC which is 1 relative
put 0 into tOffset
#get field ref
put DB_CursGetFldRef(pCurs,pFldNm) into tFldRef
if tFldRef is not a number then
breakpoint
end if
#read data from db and write to file.
#Make sure doesn't go wild and eat hard disk...
put DB_GetDataSize(tFldRef) into tLength
put false into tExit
#I use a constant for default read size, but this can't be written
to, so...
put kRead into tRead
#val read is 0 relative. You must read precisely the right amount of
data
#otherwise any extra read will include junk you don't want (ie won't
just return empty)
repeat until tExit
#read 1/2Mb
#if file is less than read chunk, ie 500k by default...
if kRead > tLength then put tLength into tRead
#last chunk?
if tOffset + kRead >= tLength then
put tLength- tOffset into tRead
put true into tExit
end if
#assertion in case something went wrong...
if tOffset >= tLength then
#already got it all
breakpoint
exit repeat
end if
get
DBChk("Binary_ReadData",Valentina("Binary_ReadData",tFldRef,"tData",tRea
d,tOffset))
write tData to file pFile at end
add tRead to tOffset
end repeat
put tOffset
close file pFile
end DB_ExportFile
More information about the Valentina
mailing list