Reading and Writing Files Directly
Although using MFC's built-in serialization capabilities is a handy way to save andload data, sometimes you need more control over the file-handling process. For
example, you might need to deal with your files nonsequentially, something the
Serialize() function and its associated CArchive object can't handle because they
do stream I/O. In this case, you can handle files almost exactly as they're handled
by non-Windows programmers: creating, reading, and writing files directly. Even
when you need to dig down to this level of file handling, MFC offers help.
Specifically, you can use the CFile class and its derived classes to handle files
directly.
The CFile Class
MFC's CFile class encapsulates all the functions you need to handle any type of
file. Whether you want to perform common sequential data saving and loading or
construct a random access file, the CFile class gets you there. Using the CFile
class is a lot like handling files the old-fashioned C-style way, except that the
class hides some of the busy-work details from you so that you can get the job
done quickly and easily. For example, you can create a file for reading with only a
single line of code. Table 7.1 shows the CFile class's member functions and their
descriptions.
Table 7.1 Member Functions of the CFile Class
Function Description
CFile Creates the CFile object. If passed a filename, it opens the file.
Destructor Cleans up a CFile object that's going out of scope. If the file is
open, it closes that file.
Abort() Immediately closes the file with no regard for errors.
Close() Closes the file.
Duplicate() Creates a duplicate file object.
Flush() Flushes data from the stream.
GetFileName() Gets the file's filename.
GetFilePath() Gets the file's full path.
GetFileTitle() Gets the file's title (the filename without the extension).
GetLength() Gets the file's length.
GetPosition() Gets the current position within the file.
GetStatus() Gets the file's status.
LockRange() Locks a portion of the file.
Open() Opens the file.
Read() Reads data from the file.
Remove() Deletes a file.
Rename() Renames the file.
Seek() Sets the position within the file.
SeekToBegin() Sets the position to the beginning of the file.
SeekToEnd() Sets the position to the end of the file.
SetFilePath() Sets the file's path.
SetLength() Sets the file's length.
SetStatus() Sets the file's status.
UnlockRange() Unlocks a portion of the file.
Write() Writes data to the file.
As you can see from Table 7.1, the CFile class offers plenty of file-handling power.
This section demonstrates how to call a few of the CFile class's member functions.
However, most of the other functions are just as easy to use.
Here's a sample snippet of code that creates and opens a file, writes a string to it,
and then gathers some information about the file:
// Create the file.
CFile file("TESTFILE.TXT", CFile::modeCreate | CFile::modeWrite);
// Write data to the file.
CString message("Hello file!");
int length = message.GetLength();
file.Write((LPCTSTR)message, length);
// Obtain information about the file.
CString filePath = file.GetFilePath();
Int fileLength = file.GetLength();
Notice that you don't have to explicitly open the file when you pass a filename to
the constructor, whose arguments are the name of the file and the file access
mode flags. You can use several flags at a time simply by ORing their values
together, as in the little snippet above. These flags, which describe how to open
the file and which specify the types of valid operations, are defined as part of the
CFile class and are described in Table 7.2.
Table 7.2 The File Mode Flags
Flag Description
CFile::modeCreate Creates a new file or truncates an existing file to
length 0
CFile::modeNoInherit Disallows inheritance by a child process
CFile::modeNoTruncate When creating the file, does not truncate the file if
it already exists
CFile::modeRead Allows read operations only
CFile::modeReadWrite Allows both read and write operations
CFile::modeWrite Allows write operations only
CFile::shareCompat Allows other processes to open the file
CFile::shareDenyNone Allows other processes read or write operations on
the file
CFile::shareDenyRead Disallows read operations by other processes
CFile::shareDenyWrite Disallows write operations by other processes
CFile::shareExclusive Denies all access to other processes
CFile::typeBinary Sets binary mode for the file
CFile::typeText Sets text mode for the file
CFile::Write() takes a pointer to the buffer containing the data to write and the
number of bytes to write. Notice the LPCTSTR casting operator in the call to
Write(). This operator is defined by the CString class and extracts the string from
the class.
One other thing about the code snippet: There is no call to Close()--the CFile
destructor closes the file automatically when file goes out of scope.
Reading from a file isn't much different from writing to one:
// Open the file.
CFile file("TESTFILE.TXT", CFile::modeRead);
// Read data from the file.
char s[81];
int bytesRead = file.Read(s, 80);
s[bytesRead] = 0;
CString message = s;
This time the file is opened by the CFile::modeRead flag, which opens the file for
read operations only, after which the code creates a character buffer and calls
the file object's Read() member function to read data into the buffer. The Read()
function's two arguments are the buffer's address and the number of bytes to
read. The function returns the number of bytes actually read, which in this case is
almost always less than the 80 requested. By using the number of bytes read, the
program can add a 0 to the end of the character data, thus creating a standard Cstyle
string that can be used to set a CString variable.
The code snippets you've just seen use a hard-coded filename. To get filenames
from your user with little effort, be sure to look up the MFC class CFileDialog
in the online help. It's simple to use and adds a very nice touch to your programs.
No comments:
Post a Comment