File class is expanded to include methods to read data from the file and to determine whether the file was successfully opened.
Listing 1. The modified File class.
|
We’ve removed the getHandle method and added the isOpen and read methods.
The client of the File class no longer needs to know about the file handle at all. With this change we've fully encapsulated the file handle inside the File class. Any user of the class does not need to know about the file handle or the specifics of how the File class implements its behavior.
The isOpen method is also a step toward encapsulating knowledge about the Windows API in the File class. Up until now the sample function needed to know how the Windows API indicates that the requested file could not be opened. If we dig into the documentation for the CreateWindow function we learn that if the file is not opened CreateWindow returns a handle with a value equal to INVALID_HANDLE_VALUE. Every time a call to CreateWindow is coded, the programmer should refer to the documentation to determine what is returned by the function. More commonly we rely upon memory or assume what the return value might be. From the first example until now, the sample program contained an unintentional bug. Even though I referred frequently to the API documentation while writing this, I reflexively assumed that the handle returned by CreateWindow would be NULL in case of an error. When I focused more closely upon writing a method that would test whether the file was open I looked at the documentation and described in code what the documentation told me. The knowledge coded in that method is now available to any user of the class.
I’ve added a comment to the read method, documenting that it returns a true value if the read is successful. In order to keep the examples brief, I’ve avoided excessive commentary. This seemed too important to leave out. Does true mean success or failure? It could go either way. The underlying ReadFile function returns an integer value, but if you read the documentation it is actually returning either zero or a non-zero amount. Does zero indicate success or failure? The read method now encapsulates that knowledge.
The read method also uses a default value of NULL for the fifth argument to ReadFile. The fifth argument is used for overlapped file I/O. It is only used in specialized situations and only for some versions of Windows. Specific support for overlapped file I/O can be added to the File class if needed some time in the future. Leaving it out does not preclude later support and simplifies the requirements for making an ordinary read.
isOpen and read methods.
|
Note that the sample function no longer refers to a HANDLE at all. It creates a File object and uses methods of that object to verify that the file was opened and to read the file content. It does not need to know the special value stored in a handle if the file could not be opened. It also needs to pass less arguments to the read method than it had to pass to the ReadFile function.
We still need to test the return value of the read method in order to detect an unexpected problem reading the file. It is easy to neglect doing so. We also need to know whether read returns true or false in case of an error. It would be best to avoid that ambiguity. We will next add exception handling to resolve those problems.
The Code Untangler home page
Copyright © 2001, Randy McLaughlin