Opening and Reading from a File

Let's say that you want to write a program that performs the simplest possible file operation: you want to open a file, read from it, and write its contents to the screen. First, however, you need to determine what type of text file you have. The file could contain single-byte characters using the ANSI character set. Alternatively, the file could contain text using Unicode characters, where two bytes are used to store each character. Further, Unicode characters can be stored with the most significant byte either first or last. It is important to determine which byte-ordering scheme is being used before the file is read.

In Unicode text files, the first two characters have the value 0xfeff if the file is a Unicode file, or 0xfffe if the file is Unicode with reversed byte order. In ANSI files, the first two bytes store regular characters.

Listing 2.1 shows code that opens a text file and determines the character set being used.

Listing 2.1. Determines the content type of a text file (ANSI or Unicode)
void Listing2_1()
{
   HANDLE hFile;
   WORD wLeadin;
   DWORD dwNumRead;
   TCHAR szFilename[MAX_PATH + 1];
   if(!GetFilename(_T("Enter filename:"),
         szFilename, MAX_PATH))
     return;
   hFile = CreateFile(szFilename,
     GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
   if(hFile == INVALID_HANDLE_VALUE)
   {
     cout ≪ _T("Could not open file. Error:")
          ≪ GetLastError();
     return;
   }
   if(ReadFile(hFile, &wLeadin, 2, &dwNumRead, 0))
   {
      // Is this a Unicode file?
      // Determine byte order sequence
      if(wLeadin == 0xFEFF)
         cout ≪ _T("Unicode File") ≪ endl;
      else if(wLeadin == 0xFFFE)
        cout ≪ _T("Byte reversed Unicode file") ≪ endl;
      else
         cout ≪ _T("Text file") ≪ endl;
   }
   else
   {
         cout ≪ _T("Could not read file. Error: ")
            ≪ GetLastError();
   }
   CloseHandle(hFile);
}

In this program, the code requests a file name from the user, opens the file using CreateFile, reads the first two characters from the file using ReadFile, and then closes the file using CloseHandle. Listing 2.2 modifies the code in Listing 2.1 so that the contents of the file are listed if the file contains Unicode text.

Listing 2.2. Displays the contents of a Unicode text file
void Listing2_2()
{
   HANDLE hFile;
   WORD wLeadin;
   DWORD dwNumRead;
   TCHAR szFilename[MAX_PATH + 1], szChar[2];
   if(!GetFilename(_T("Enter filename:"),
         szFilename, MAX_PATH))
      return;
   hFile = CreateFile(szFilename, GENERIC_READ,
         0, 0, OPEN_EXISTING, 0, 0);
   if(hFile == INVALID_HANDLE_VALUE)
   {
      cout ≪ _T("Could not open file. Error:")
           ≪ GetLastError();
      return;
   }
   if(ReadFile(hFile, &wLeadin, 2, &dwNumRead, 0))
   {
       if(wLeadin == 0xFEFF)
          // read file character by character
          while(ReadFile(hFile, szChar,
            sizeof(TCHAR), &dwNumRead, 0)
              && dwNumRead > 0)
          {
            szChar[1] = '';
            cout ≪ szChar;
          }
       else
          cout ≪ _T("File is not Unicode!") ≪ endl;
   }
   else
      cout ≪ _T("Could not read file. Error: ")
           ≪ GetLastError();
   CloseHandle(hFile);
}

The CreateFile function opens a file for read and/or write access. We will see in Chapter 9 that this same function also opens serial communications ports. It is also dealt with in more detail later in this chapter.

Table 2.1. CreateFile—Opens or creates a file
CreateFile 
LPCTSTR nameName of the file to open
DWORD accessModeHow the file should be accessed
DWORD shareModeThe way the file should be shared
LPSECURITY_ATTRIBUTES securityAttributesAddress of a security structure (not supported, should be NULL)
DWORD createThe way the file should be created
DWORD attributesSettings for file attribute bits and flags
HANDLE templateFileFile containing extended attributes (not supported, should be NULL)
HANDLE Return ValueReturns a handle on success, or INVALID_HANDLE_VALUE

In Listing 2.2, the CreateFile function accepts the name of the file, a GENERIC_READ access mode that stipulates that the file will be used in a read-only mode, a share mode that prevents any other process from opening the file, and an OPEN_EXISTING creation mode that specifies that the file already exists. Windows CE does not support security attributes or a template file. The function returns either a handle to the file object that it opened, or returns INVALID_HANDLE_VALUE if an error is detected. If an error occurs, you can use the GetLastError function to retrieve an error code. A very common mistake is to test the returned handle for NULL rather than INVALID_HANDLE_VALUE, and so failures in CreateFile remain undetected.

Once the file is open, the ReadFile function reads two bytes of data that are used to determine the text file type. Then, ReadFile is used to read data from the file one character at a time. ReadFile is a generic block-reading function. You pass it a buffer and the number of bytes for it to read, and the function retrieves the specified number of bytes from the file starting at the current offset.

Table 2.2. ReadFile—Reads bytes from the specified file
ReadFile 
HANDLE fileFile handle created with CreateFile
LPVOID bufferBuffer to hold the read bytes
DWORD requestedBytesThe number of bytes desired
LPDWORD actualBytesThe number of bytes actually placed in the buffer
LPOVERLAPPED overlappedOverlapped pointer to overlapped structure (not supported)
BOOL Return ValueTRUE on success, otherwise FALSE

In Listing 2.2 the code reads the file one character at a time until ReadFile indicates end-of-file. The CloseHandle function closes the file once the operations on it are complete.

Table 2.3. CloseHandle—Closes an open handle
CloseHandle 
HANDLE objectThe handle to close
BOOL Return ValueTRUE on success, otherwise FALSE

In this section the goal has been to show that file access using the Windows CE API functions is not much different from normal file access techniques that you already understand.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.182.45