10.2 Rules for Handling Files in Windows

In Windows, multitasking imposes some special restrictions on file access that you do not encounter in the standard C environment. Since there may be several applications working with files at the same time, you must follow some simple rules to avoid conflicts and potential overwriting of files.

Keep a file open only while you have execution control.

You should close the file before calling the GetMessage function, or any other function that may yield execution control. Closing the file prevents it from being affected by changes in the disk environment that may be caused by other applications. For example, suppose your application is writing to a floppy disk and temporarily relinquishes control to another application, and the other application tells the user to remove the floppy disk and replace it with another. When your application gets control back and attempts to write to the disk as before, without having closed and reopened the file, it could destroy data on the new disk.

Another reason to keep files closed is the MS-DOS open-file limit. MS-DOS sets a limit on the number of open files that can exist at one time. If many applications attempt to open and use files, they can quickly exhaust the available files.

To prevent open-file problems, the OpenFile function provides an OF_REOPEN option that you can use to close and reopen files. Whenever you open or create a file, OpenFile automatically copies the relevant facts about the file, including the path and filename and the current position of the file pointer, in an OFSTRUCT structure. This means you can close the file, then reopen it by supplying nothing more than the structure.

If the user changes disks while working in another application, when your application calls the OpenFile function, the function will fail to reopen your file. If your application specifies the OF_PROMPT option when reopening a file, OpenFile automatically displays a message box asking the user to insert the correct disk.

Follow MS-DOS conventions when carrying out file operations.

Ultimately, Windows depends on the MS-DOS file-handling functions to carry out all file input and output. This means that you must follow MS-DOS conventions when carrying out file operations. For example, in MS-DOS, a filename can have from one to eight characters and a filename extension can have from zero to three characters. The name must not contain spaces. Furthermore, filenames must be specified in the OEM character set, not the Windows character set.

The OpenFile function translates filenames from the Windows character set to the OEM set, using the AnsiToOem function. If a filename contains lowercase extended characters, however, an application should call the AnsiUpper function before calling OpenFile; otherwise, the extended characters are converted incorrectly. (All filenames that contain lowercase extended characters must be converted by calling AnsiUpper and then AnsiToOem.)

Note:

All edit controls and list boxes use the Windows character set by default, so if you plan to display MS-DOS filenames or allow users to enter filenames, they may see unexpected characters wherever an OEM character is not identical to a Windows character. If your application processes international filenames, it must be prepared to handle filenames that do not contain conventional single-byte character values. For such filenames, use the AnsiNext and AnsiPrev functions to move forward and backward in a string. These functions correctly handle strings that contain characters that are not one byte in length, such as strings in computers that are using Japanese characters.

Use unique filenames for each instance of your application.

Since more than one instance of an application can run at a time, one instance can end up overwriting the temporary file of another instance. You can prevent this by using unique filenames for each instance of your application.

To create unique filenames, use the GetTempFileName function. This function creates a unique name by combining a unique integer with a prefix and filename extension that you supply. GetTempFileName creates names that follow MS-DOS filename requirements.

Note:

The GetTempFileName function uses the TEMP environment variable to create the path and filename of the temporary file. If the user has not set the variable, the temporary file will be placed in the root directory of the current drive. If the variable does not specify a valid directory, you will not be able to create the temporary file.

Close files before displaying a message box, or use system-modal error message boxes.

As mentioned previously, your application should not relinquish control while it has open files on floppy disks. If your application uses a message box that is not system-modal, the user can move to another application while the message box is on display. If your application still has open files, switching applications like this can cause file I/O problems.

To avoid such problems, whenever your application displays an alert or error message by using the MessageBox function, it should either close any open files before displaying the message box, or if closing files is not feasible, make the message box system-modal.