Low-Level File Functions

Low-level file functions (LLFFs) are cool. They can be a hacker's best friends, and are certainly essential tools in our toolbox. With LLFFs, you can open and read all those nasty binary files that the operating system and manufacturers would prefer you didn't take apart. With LLFFs, it's possible to translate a Windows Cardfile into a .DBF, read and rewrite a FoxPro macro file, translate the Screen memory variable stored in a .MEM file, or study and perhaps rearrange the FoxPro codepage sort logic (FOXPRO.INT).See the disk for the result of a few hours of taking apart the .FKY keyboard macro function file and analyzing the results: PeekFKY.PRG dumps the contents of a macro file to the screen. Check out the topics SAVE MACROS and RESTORE MACROS, and think about what you could do with keyboard macros being updated programmatically.Low-level file functions follow a logic that will be familiar to users of other languages, but may be a little different for FoxPro devotees. Rather than referring to a file by its alias, a file "handle" number is created using FOPEN() or FCREATE(). A file pointer, like a record number, determines where the next bytes are read or written to. The FSEEK() function allows us to move this file, repositioning the pointer relative to the current position or to the top or bottom of the file. FREAD() or FGETS() reads data from the file, either byte-by-byte or by lines, and FWRITE() or FPUTS() matches the reading functions with their equivalent outputs. Finally, a few miscellaneous functions allow flushing (FFLUSH()), end-of-file testing (FEOF()) and error checking (FERROR()).Low-level file functions were the most common ways to manipulate files that were not in DBF format, but there are several other techniques, some new to Visual FoxPro. These techniques may have advantages over LLFFs for your task, and bear consideration. If you are working with ASCII text, consider sticking the file in a memo field with APPEND MEMO and using the memo field functions MLINE() and MEMLINES() to hack it apart, or an APPEND FROM TYPE SDF to pull it into multiple records. If the text files are in the Windows INI format, consider the WinAPI calls described in "INI Files." New to VFP 6 are the StrToFile() and FileToStr() functions to load an entire file into one character variable in one swoop.If you'll be writing out a text file, consider SET ALTERNATE and SET TEXTMERGE as well as using LLFFs.But for hacking binary formatted data, there's nothing better than the low-level file functions. Let's see what they can do.

FChSize()

FCHSIZE() modifies the size of a file on disk. This command can increase, decrease or zero-out the size of a file.

Usage

nNewSize = FCHSIZE( nFileHandle, nSize )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

nSize

Numeric

Final desired size.

nNewSize

–1

An error has occurred; see FERROR() for more information. Check for disk space, file opened with write access, or network rights issues.

Numeric

The new size of the file.


Example

lnRetVal = FCHSIZE(8, 0)
The above example zeroes out the length of the file opened with file handle 8.

FClose()

FClose() closes a file opened with low-level file functions.

Usage

lSuccess = FCLOSE( nFileHandle )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

lSuccess

.F.

An error has occurred; see FERROR() for more information. Check for the correct file handle, network rights.

.T.

File successfully closed.


Note that issuing the CLOSE ALL command closes all files opened with the low-level file functions.

Example

* Close the file opened with file handle 8.
llRetVal = FCLOSE(8)

FCreate()

FCREATE() creates a file on disk, and returns a "handle"—a numeric value that other low-level file functions must have to refer to the same file.

Usage

nHandle = FOPEN( cFilename [, nAttribute ] )

Parameter

Value

Meaning

cFilename

Character string

The full path and filename of the file to be opened.

nAttribute

0 or omitted

Read-Write. Any option other than the default 0 parameter prevents FoxPro from writing to the file.

1

Read-only.

2

Hidden.

3

Read-only and hidden.

4

System.

5

Read-only and System.

6

System and Hidden.

7

Read-only, Hidden and System.

nHandle

–1

An error has occurred; see FERROR() for more information.

Positive integer

File successfully opened.


Example

* Create the AUTOEXEC.BAT files to be read/write. 
lnHandle = FCREATE("C:\AUTOEXEC.BAT", 0)
If you create a file and forget the handle number, such as by issuing the command =FCREATE("test",0), you can determine the file handle of all open files with the DISPLAY STATUS command.No warning is given to overwriting an existing file, even if SAFETY is SET ON!

FEOF()

FEOF() tests for end-of-file on a file opened with low-level file functions.

Usage

lAtEof = FEOF( nFileHandle )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

lAtEof

.F.

Not at end-of-file.

.T.

At end-of-file.


Example

* Check for end-of-file for the file opened with file handle 8.
llRetVal = FEOF(8)

FEOF() returns .T. if passed an invalid file handle. Neither a FoxPro error condition (like error 1113: "no file is opened in that area, stupid") nor a low-level file error (see FERROR(), for example 6: "Invalid file handle") is generated.


FError ()

Low-Level File Functions error-handling is funny but useful. Rather than use FoxPro's built-in error generation and the language's error-handling capability, LLFFs set an error condition detectable by FERROR(). This allows local testing of the success or failure of LLFF execution, where a global error-handling method may not be appropriate. No arguments are accepted.

Usage

nErrNum = FERROR()

Error Number

Meaning

2

File not found.

4

Too many files open (limited by file handles).

5

Access denied.

6

Invalid file handle given.

8

Out of memory.

25

Seek error (usually top of file).

29

Disk full.

31

Error opening file.


Example

nFileHand = FOPEN("NUL:")
if nFileHand < 0  && negative means error
do case
  case FERROR() = 2  && File Not Found...

FFlush ()

FFLUSH() flushes data to disk.

Usage

lSuccess = FFLUSH( nFilehandle )

Parameter

Value

Meaning

nFilehandle

Integer

The file handle created with FOPEN() or FCREATE().

lSuccess

.T.

FLUSH successful.

.F.

Error.


Example

llRetVal = FFLUSH(8)
The above example flushes all data to disk for the file opened with file handle 8.

FGetS()

FGETS() reads data from a low-level file. FGETS reads characters until it reaches the first of these three limits: the number of characters specified in the second parameter, the first (next) occurrence of a carriage return, or the end of the file.

Usage

cString = FGETS( nFileHandle [, nBytes ] )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

nBytes

Numeric

Maximum number of bytes to read; defaults to 254 if not specified.

cString

Character string

Characters read.


Example

lcRetVal = FGETS(8,400)
The above example reads characters from file handle 8, starting at the current file position, and ending at the first occurrence of a carriage return, the specified number of bytes, or the end-of-file (hint: test FEOF()).

FOpen ()

FOPEN() opens a file on disk for reading and/or writing, and returns a "handle"—a numeric value that other low-level file functions (LLFFs) must have to refer to the same file. While it may be theoretically possible to open other DOS devices, such as "LPT1:" or "COM1:" with this command, results under Windows are less than 100 percent predictable (and get less predictable under Win98 and NT!). A far better solution to serial port manipulation is to use the Win API function calls (i.e., OpenComm()) or a third-party library specially designed for serial-port work.

Usage

nHandle = FOPEN( cFilename [, nMode ] )

Parameter

Value

Meaning

cFilename

Character string

The full path and filename of the file to be opened.

nMode

0 or omitted

Read-only, buffered.

1

Write-only, buffered.

2

Read/write, buffered.

10

Read-only, unbuffered.

11

Write-only, unbuffered.

12

Read/write, unbuffered.

nHandle

–1

An error has occurred; see FERROR() for more information.

Positive integer

File successfully opened.


Example

nHandle = FOPEN("C:\AUTOEXEC.BAT", 0)
The above example opens the AUTOEXEC.BAT files to be read, with buffering turned on. Buffering is normally the preferred method of access.

FPutS()

FPUTS() writes data to an opened low-level file. FPUTS writes characters until it reaches the smaller of these two limits: the number specified in the third parameter, or the total length of the string supplied.

Usage

nRetVal = FPUTS( nFileHandle, cString [, nBytes ] )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

cString

Character

Character string to be written to file.

nBytes

Numeric

Maximum number of bytes to write; defaults to the length of the string supplied plus an ending carriage return-line feed pair.

nRetVal

0

An error occurred. Test with FERROR(), check for correct file handle, file rights.

Integer

The number of bytes written.


Example

* Write characters to file handle 8,
* starting at the current file position,
* ending at the end of the string or 
* the specified number of bytes 
lnRetVal = FPUTS(8,MyTestStr,127)
The return, lnRetVal, reflects the number of characters written, including a final carriage return (CHR(13)) and line feed (CHR(10)).

FRead()

FREAD() reads data from a low-level file. Unlike FGETS(), FREAD() just reads the number of characters specified, ignoring the value of those characters. (FGETS() is sensitive to carriage returns and line feed characters.) FREAD() stops after reading the number specified in the second parameter, or encountering the end-of-file.

Usage

cString = FREAD( nFileHandle, nBytes )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

nBytes

Numeric

Maximum number of bytes to read.

cString

Character string

Characters read.


Example

* Read characters from file handle 8,
* starting at the current file position, 
* ending at the specified number of bytes, or the end-of-file 
*(hint: test FEOF())
lcRetVal = FREAD(8,400)

FSeek()

FSEEK() repositions the file pointer within a low-level file. This is sort of the low-level file function equivalent of the GO command for DBFs.

Usage

nPosition = FSEEK( nFileHandle, nLocation [, nRelativeTo ] )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

nLocation

Numeric

Location at which to position the file pointer.

nRelativeTo

0 or omitted

Measure nLocation from the beginning of the file.

1

Measure nLocation from the current file pointer position.

2

Measure nLocation from the end of the file; that is, start at the end and move nLocation characters toward the beginning.

nPosition

Integer

The new position within the file, expressed as the number of bytes offset from the beginning.


Example

* Moves the file pointer to a position 400 characters 
* from the beginning of the file
lcRetVal = FSEEK(8,400)
=FSEEK(8,0,0)  && GO TOP
=FSEEK(8,0,2)  && GO BOTTOM
lnWhereAmI = FSEEK(8,0,1)  && return current file position

FWrite()

FWRITE() writes data to a low-level file. Unlike FPUTS(), FWRITE() writes exactly what you specify, without appending any characters (such as carriage returns or line feeds). Use FWRITE() when you are trying to write data out to a very specific file format, such as Windows CardFile, FOXPRO.INT or another binary format.

Usage

nRetVal = FWRITE( nFileHandle, cString [, nBytes ] )

Parameter

Value

Meaning

nFileHandle

Integer

The file handle created with FOPEN() or FCREATE().

cString

Character

The data to be written to the file.

numBytes

Numeric

Maximum number of bytes to write.

nRetVal

0

An error has occurred. Check for correct file handle, string, disk space and rights.

Integer

The number of characters actually written.


Example

nRetVal = FWRITE(8,REPLICATE("Fred",200),400)
The above example writes 400 characters to file handle 8, starting at the current file position.

See Also

Append Memo, Close All, FileToStr(), MemLines(), MLine(), Set Alternate, Set TextMerge, StrToFile()


Back to Table of Contents

Copyright © 2002-2018 by Tamar E. Granor, Ted Roche, Doug Hennig, and Della Martin. Click for license .