INF: File Input/Output Under Windows

ID Number: Q72237

3.00

WINDOWS

Summary:

Applications written to work in a cooperative multitasking

environment, such as that of Windows, must be designed to work within

specified constraints. This article discusses these constraints and

the methods used to access files in Windows applications.

More Information:

The cardinal rule for file I/O in Windows is to not keep files open

for long periods of time. Specifically, files should not be kept open

during the processing of more than one message. A file should be

opened, read or written, and closed during the processing of one

message.

There are two options that can be used to access files that have been

opened with the OpenFile() function:

1. Use the C run-time library file I/O instructions.

2. Use the file I/O instructions provided by Windows.

The file handle returned from OpenFile() can be used directly with the

C run-time library "low-level" file I/O functions such as open(),

read(), lseek(), write(), tell(), and close(). One problem with these

functions is that FAR and HUGE pointers to parameters cannot be used

unless the program is developed using the compact or large model.

These two memory models are not recommended for use by Windows

programs because the data segments must be fixed in memory. To work

around this restriction, data must be read from the file into local

memory and then copied to global memory.

The C run-time library buffered I/O functions [fopen(), fread(),

fwrite(), and fclose()] can also be used. The fdopen() function

converts the file handle returned by OpenFile() to a FILE structure.

Buffered I/O is not very useful in Windows because files should be

read and written in large pieces. Buffering is most helpful when files

are processed in small pieces.

The file I/O functions provided by Windows are: _lopen(), _lclose(),

_lcreate(), _llseek(), _lread(), and _lwrite(). The "l" prefix

indicates that these functions accept FAR pointers to buffers,

allowing information to be transferred from files directly to global

memory and back. (These functions have been part of each Windows

release; however, they were first documented in Windows 3.00.)

Using Windows file I/O calls is the easier method when the data

buffers are in global memory. Do not write assembly-language code to

interface directly with the DOS file I/O functions. If an application

uses stream I/O instead of the low-level I/O functions, after some

time the performance of the application may slow down. This is caused

by the buffering system used by the stream I/O functions. When the

fopen() function is used to open a file, a file record is created that

contains pointers into a stream buffer. This buffer is allocated from

global memory when the first I/O operation is performed. If there is

not enough room in the heap for this buffer allocation, the file

operation continues with a one-character buffer.

There are two ways to work around this problem. One method is to

reduce the amount of data stored in the heap. The other method is to

switch to the compact or large memory model (neither of which is

recommended for use with Windows programs). If the second method is

adopted, it might be necessary to use the /Gt switch for the C

compiler to remove static data from DGROUP (the default data segment).