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