Hart.gif (5380 bytes)Win32 System Programming

Return to Addison-Wesley Home Page  


Return to Top Page

Win32 vs. The C Run-Time Library for File I/O


This information augments the discussion on Pages 65-66 regarding the choice between Win32 and the Standard C Library (SCL) and the more comprehensive C Run-Time Library (CRTL) when performing file I/O. The SCL are those functions defined by the standard and described in Plauger's book, The Standard C Library. The CRTL includes the CRTL but also includes all the non-standard extensions, such as the generic string functions, extended FILE functions, _beginthreadex(), and many more.

The SCL library advantages cited in the book are: portability, line- and character-oriented functions, and ease of use. Disadvantages include the inability to traverse directories, manage files or deal with file attributes, and the inability to use security, memory mapping, file locking, or asynchronous I/O.

Here is some supplementary information, written in terms of the advantages of using Win32 rather than the Standard C Library. This discussion was prompted by some postings on comp.os.ms-windows.programmer.win32 and some email in response to those postings.

This discussion is confined to the Standard C Library as documented, for instance, in Plauger's book. You will find that Visual C++ CRTL provides an extensive set of extensions that allow you, for example, to lock a file. Using these extensions provides no real advantages over the Win32 calls, other than allowing you to use a FILE pointer rather than a HANDLE. There is, in fact, a _get_osfhandle() function that obtains the HANDLE associated with a FILE.

  1. Direct Access to "Large Files". A "large file" is a file longer than 4GB (the limit for a 32-bit file pointer). A "small file" is shorter than 4GB. Many applications require large files, but, on the other hand, many programmers are not concerned with this issue and can use fseek(). Win32 can perform direct access, using SetFilePointer or the offset fields in the OVERLAPPED structure, to position anywhere in a file. One email correspondent pointed out that the library functions fgetpos and fsetpos use a 64-bit file position and therefore overcome the limitation. The file position parameter, however, is opaque and, in the standard, is not to be manipulated by the programmer. You can only obtain the current position with fgetpos, store it, and use it later with fsetpos. This will be adequate for some applications, but not for those that compute a file position (consider a file management function that computes a file position with a hash function). It turns out that fgetpos and fsetpos do, in fact, ultimately call the _lseeki64() function using the position parameter, so you actually could get away with computing a file position for fsetpos. Such a non-standard use is, however, dangerous and provides little advantage.
  2. Memory-Mapped Files. MMF provide the convenience of in-memory algorithms without I/O concerns. Chapter 6 has several examples, such as in-memory sorting and using the C Library character and string processing functions on a mapped file. This argument is most appropriate for files that are small enough to be mapped (2GB is the strict upper bound). The memory-mapped file performance advantages noted in Appendix C require file mapping, but, as discussed below, only apply to relatively short files; see atou for more data on memory-mapped file performance.
  3. File Locking. File locking is not a part of the Standard C library. The VC++ CRTL does provide a _locking() function, but it is limited to "small" files.
  4. File and Directory Management. The SCL does not allow control (either getting or setting) file attributes (length, time stamp, etc.) nor can you scan a directory.
  5. Handle Inheritance and Redirection. A HANDLE can be inheritable and copied to a new child process, whereas a FILE pointer cannot. Likewise, standard I/O can be redirected to a handle. This is illustrated in Chapter 9 with anonymous pipes.
  6. Device Independence. A program written to use a HANDLE for I/O can be device independent; the HANDLE can be associated with a file or a pipe, for instance.
  7. Asynchronous I/O. Asynchronous I/O requires a Win32 HANDLE.

Nonetheless, if you are performing simple processing of a moderate-sized file, the STL is hard to beat for simplicity, convenience, and even performance.

The extended C Library provided with Visual C++ is quite rich with any number of functions that are not a part of the standard. Some, such as _popen(), allow you to perform many tasks that the book performs with Win32 functions. However, while these functions are stylistically similar to the C library, they do not appear to be any easier to use and are neither Win32 nor standard C. Furthermore, some functions, such as _umask(), appear to be useful, but, after examining the library source code, are found to be very limited.