asked on
Why is the VFP FWRITE() Function not working in this code?
I need to write code which appends a SALT to arbitrary files, including non text files and very large files. So I'm trying to avoid using strtofile and filetostr and using low level file functions instead. It is not intended that the salted file will ever need direct functional access so it doesn't matter if the append makes the file unreadable or unfunctional.
Don't do low level stuff that often but have done it a few times without hassle in the past but today its resisting my efforts. Your mission, should you choose to accept it, is to figure out why the code below isn't working:
(the failure line is the one above the comment:
*THIS IS WHERE IT FAILS')
Apologies for mixed case management and lack of hungarian notation but this is just a quickly cobbled script to test the basic expected functionality
You should, if you wish, be able to copy and paste the code into your own vfp prog and run it to replicate the failure.
*********************
LOCAL FILENAME,FILESIZE,NOTHING,RESPONSE,MATCHES,CURRDEFAULT,FILEFOLDER,EXTENSION,FULLFILE,FILEPATH,NEWPATH,newfile,fhandle,teststring,bytcnt,startpos
RESPONSE=MESSAGEBOX('Select any file and this routine will attempt to append a 120 char string to it and report back whether the filesize has increased by the expected amount'+CHR(13);
+'Proceed?',260,'Test File Size after Append?')
IF response<>6
RETURN
endif
CURRDEFAULT=SYS(5)+SYS(2003)
IF EMPTY(FILEPATH)
FILEPATH=GETFILE()
ENDIF
IF EMPTY(FILEPATH)
WAIT WINDOW 'No File Selected' nowait
RETURN .f.
ENDIF
IF NOT FILE(filepath)
MESSAGEBOX('Selected file not found at location:'+CHR(13);
+filepath,16,'File not where expected')
RETURN .f.
endif
FILEFOLDER=ADDBS(JUSTPATH(FILEPATH))
SET DEFAULT TO (FILEFOLDER)
FILENAME=JUSTSTEM(FILEPATH)
EXTENSION=JUSTEXT(FILEPATH)
FULLFILE=JUSTFNAME(FILEPATH)
MATCHES=ADIR(aFiles,fullfile)
IF MATCHES<>1
MESSAGEBOX('ADIR cant see Selected file'+CHR(13);
+filepath,16,'File not where expected')
RETURN .f.
endif
*other errortraps removed
SET STEP ON && So we can see the effects, values and failure as they happen
*COPY FILE FOR SALTING
NEWPATH=FILEFOLDER+FILENAME+'_SALTED.'+EXTENSION
COPY FILE(FILEPATH) TO (NEWPATH)
IF NOT FILE(NEWPATH)
MESSAGEBOX=('Failed to copy:'+CHR(13);
+filepath+CHR(13);
+'to:'+CHR(13);
+newpath,16,'Failed Copy')
ELSE
newfile=JUSTFNAME(newpath)
fhandle=FOPEN(newpath)
IF fhandle<0
MESSAGEBOX('Failed to Open/Access '+newfile,16,'Failed to Open')
SET DEFAULT TO (currdefault)
RETURN
endif
teststring=REPLICATE('0123456789',12)
*also tried
* teststring='teststring'
startpos=fseek(fhandle,0,2) && to ensure append happens at end of file
bytcnt=FWRITE(fhandle,teststring)
*THIS IS WHERE IT FAILS. bytcnt is ALWAYS Zero, regardless of file selected
*also tried
* bytcnt=FWRITE(fhandle,teststring,LEN(teststring))
FCLOSE(fhandle)
IF bytcnt<>LEN(teststring)
*bytcnt consistently zero so failing every time
MESSAGEBOX('Failed to append all or part of test string to selected file')
ELSE
MATCHES=ADIR(aFiles,newfile)
IF matches=1
newfilesize=aFiles(1,2)
IF newfilesize-filesize<>LEN(testring)
MESSAGEBOX('Appended file wrong size'+CHR(13);
+CHR(13);
+'Expected: '+TRANSFORM(filesize+LEN(testring))+CHR(13);+
+'But result: '+TRANSFORM(newfilesize),16,'Wrong File Size')
ELSE
ELSE
MESSAGEBOX('Appending test string correctly altered file size')
ENDIF
ENDIF
ENDIF
SET DEFAULT TO (currdefault)
*******************
and, just for completeness, I have checked the actual file sizes of (filepath) and (newpath) and they are identical, so "bytcnt" is telling the truth, nothing is being written to the selected files.
Nor is there anything special about the files selected. Some are executables, some are plain text files, some are old .prg files etc. None has any protective attributes set and all reside in the same folder from which I'm running the code, so I obviously have full access rights.
I've also tried substituting FPUTS for FWRITE, which I didn't want to do because it adds a couple of extra bytes (carriage return and line feed) which I really don't want added to the file, but I could live with. But it behaved identically. Zero bytes written
Suggestions?
ASKER
having just discovered Pavel's comment from 2015
I tried inserting
=fchsize(fhandle,filesize) prior to the fseek above.
Didn't change result.
Thanks for refreshing the knowledge about the bug in FSEEK() !
ASKER
my pleasure
The problem is in the FOPEN() function call. You've used just one parameter and it means the file was open in Read only mode. You should add 2 or 12 as the 2nd parameter.
You may also use STRTOFILE() function which allows to append a string to the end of file without FOPEN() call necessity. It is easier than FWRITE() but a little bit slower (my guess).