Link to home
Start Free TrialLog in
Avatar of Mike Jacobs
Mike JacobsFlag for United Kingdom of Great Britain and Northern Ireland

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?




Avatar of Pavel Celba
Pavel Celba
Flag of Czechia image

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).

Avatar of Mike Jacobs

ASKER

having just discovered Pavel's comment from 2015

I tried inserting 

=fchsize(fhandle,filesize) prior to the fseek above. 

Didn't change result.


ASKER CERTIFIED SOLUTION
Avatar of Mike Jacobs
Mike Jacobs
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

Thanks for refreshing the knowledge about the bug in FSEEK() !

my pleasure