Function FSize() Foundation

Determines and optionally sets the size of a file.

Syntax
FSize( <cFileName>|<nFileHandle> [, <nNewSize>] ) --> nBytes
Parameters
<cFileName>
<cFilename> is a character string containing the name of a file including the drive and path if necessary.
<nFileHandle>
Alternatively, the numeric <nFileHandle> of an open file can be passed to the function. A file handle is returned from FOpen() or FCreate() when a file is opened.
<nNewSize>
With the optional parameter <nNewSize> a new size (in bytes) can be specified for the file. If the new file size is less than the original file size, the file will be truncated at the specified length. If the new file size is larger than the current file size, the file will be extended to the specified length.
Return

The function returns a numeric value indicating the current size of the file in bytes, after the optionally provided new file size was set.

Description

The low level file function FSize() returns the current size of a file, either by passing the file handle or the file name. If the optional parameter<nNewSize> is specified, the file will be truncated or extended to the new size and the final size will be returned. Files opened by other processes can also be processed.

When the file size is changed, the returned file size value should be identical to the requested file size. If <nNewSize> was specified and the return value of FSize() isn't the same as <nNewSize>, an error has occurred that can be diagnosed using the function FError().

Using FSize(<nFileHandle>) will not affect the position of the file pointer belonging to nFileHandle.

Examples
Changing the size of a file with FSize()

// In this example, a file is created and some text is written to it. 
// It then is truncated, using the low level file function FSize(). 

#include "FileIO.ch" 

PROCEDURE Main() 
   LOCAL cText := "James Bond's BMW is new." 
   LOCAL nHandle, nResult 

   // Delete a possibly already existing file 
   IF FExists("NEWFILE.TXT") 
      FErase("NEWFILE.TXT") 
   ENDIF 

   // Create a new, empty file 
   nHandle := FCreate("NEWFILE.TXT", FC_NORMAL) 
   IF nHandle == -1 
      DisplayError("Error creating the file:") 
   ELSE 
      // Write 100 characters to file 
      nResult := FWrite(nHandle, PadR(cText, 100)) 
      IF nResult <> 100 
         DisplayError("Error writing to file:") 
      ELSE 
         ? "Writing 100 characters to the file:" 
         ? "New File Size:  ", FSize(nHandle) 
         ? "File Pointer:   ", FSeek(nHandle, 0, FS_RELATIVE) 
         ? "New End of File:", FSeek(nHandle, 0, FS_END) 
         ? 
      ENDIF 

      // Reduce the file size to 24 bytes, file pointer stays at 100! 
      nResult := FSize(nHandle, len(cText)) 
      IF nResult <> len(cText) 
         DisplayError("Error reducing the size of the file:") 
      ELSE 
         ? "Reducing the size of the file to 24 characters:" 
         ? "New File Size:  ", FSize(nHandle) 
         ? "File Pointer:   ", FSeek(nHandle, 0, FS_RELATIVE) 
         ? "New End of File:", FSeek(nHandle, 0, FS_END) 
      ENDIF 

      FClose(nHandle) 
   ENDIF 
RETURN 

PROCEDURE DisplayError(cNote) 
   ? cNote, FError(), DosErrorMessage(FError()) 
RETURN 
Writing to a large extended file

// In this example, a file is created and some text is written to it. 
// It then is extended to 200 MB, using the low level file functions 
// FCreate(), FWrite(), FRead(), FSeek(), and FSize(). The example also 
// shows that writing to the end of a file that has been extended with 
// FSize() will require some time to fill in the zeros between the 
// previous end of the file and the new file pointer position. 

#include "FileIO.ch" 

PROCEDURE Main() 
   LOCAL cText   := "James Bond's BMW is new." 
   LOCAL cBuffer := Space(50) 
   LOCAL n200MB  := (200 * 1024 * 1024) 
   LOCAL nHandle, nResult, nStart, nEnd 

   // Delete a possibly already existing file 
   IF FExists("NEWFILE.TXT") 
      FErase("NEWFILE.TXT") 
   ENDIF 

   // Create a new, empty file 
   nHandle := FCreate("NEWFILE.TXT", FC_NORMAL) 
   IF nHandle == -1 
      DisplayError("Error creating the file:") 
   ELSE 
      // Extend the file to 200MB, file pointer stays at 0! 
      // This will be very fast, as no actual data is written to disk. 
      nStart  := MicroSeconds() 
      nResult := FSize(nHandle, n200MB) 
      nEnd    := MicroSeconds() 
      IF nResult <> n200MB 
         DisplayError("Error increasing the size of the file:") 
      ELSE 
         // The return values will be 209715200, 0, and 209715200: 
         DisplayResult("File extended to 200MB:", nHandle, nStart, nEnd) 

         // Reading the last 50 bytes at the end of the extended file 
         // will return 50 zero bytes, as the contents is undefined 
         nStart  := MicroSeconds() 
         nResult := FSeek(nHandle, -50, FS_END) 
         nResult := FRead(nHandle, @cBuffer, 50) 
         nEnd    := MicroSeconds() 
         IF nResult <> 50 
            DisplayError("Error reading from file:") 
         ELSEIF cBuffer == replicate(chr(0), 50) 
            DisplayResult("Reading the last 50 bytes (all Zeros)!", ; 
                          nHandle, nStart, nEnd) 
         ELSE 
            DisplayResult("This should never happen!", ; 
                          nHandle, nStart, nEnd) 
         ENDIF 

         // Moving the file pointer to the beginning of the file and 
         // writing 24 characters will be very fast. 
         nResult := FSeek(nHandle, 0, FS_SET) 
         nStart  := MicroSeconds() 
         nResult := FWrite(nHandle, cText) 
         nEnd    := MicroSeconds() 
         IF nResult <> 24 
            DisplayError("Error writing to file:") 
         ELSE 
            DisplayResult("Writing 24 bytes at the start of the file:", ; 
                          nHandle, nStart, nEnd) 
         ENDIF 

         // Writing the same amount of data to the end of the file will 
         // take much more time, as the file system will first have to 
         // fill the 200 MB gap with Zeros, before writing the actual 
         // 24 bytes of text at the end! 
         nResult := FSeek(nHandle, 0 - len(cText), FS_END) 
         nStart  := MicroSeconds() 
         nResult := FWrite(nHandle, cText) 
         nEnd    := MicroSeconds() 
         IF nResult <> len(cText) 
            DisplayError("Error writing to file:") 
         ELSE 
            DisplayResult("Writing 24 bytes at the end of the file:", ; 
                          nHandle, nStart, nEnd) 
         ENDIF 
      ENDIF 

      FClose(nHandle) 
   ENDIF 
RETURN 

PROCEDURE DisplayResult(cNote, nHandle, nStart, nEnd) 
   ? cNote 
   ? "New File Size:  ", FSize(nHandle) 
   ? "File Pointer:   ", FSeek(nHandle, 0, FS_RELATIVE) 
   ? "New End of File:", FSeek(nHandle, 0, FS_END) 
   ? "Time elapsed:   ", nEnd - nStart, "(Microseconds)" 
   ? 
   wait 
   ? 
RETURN 

PROCEDURE DisplayError(cNote) 
   ? cNote, FError(), DosErrorMessage(FError()) 
RETURN 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.