Link to home
Start Free TrialLog in
Avatar of visual032798
visual032798

asked on

Reading from a file

I am doing some DirectX programming with Visual C++ 5.0.  I am currently trying to load in a bitmap file, and have a reference book with an example.  The code they use for opening a file and reading from it is as follows:

HFILE hfile = _lopen(filename, OF_READ);

if( _lread( hfile, &m_bmFileHeader, sizeof(m_bmFileHeader)) == sizeof(m_bmFileHeader))
{
     other code is here
}

The m_bmFileHeader is a structure of type BITMAPFILEHEADER which contains the following members:

WORD      bfType;
DWORD   bfStyle;
WORD      bfReserved1;
WORD      bfReserved2;
DWORD   bf0ffBits;

Now, I know that _lopen and _lread are older 16-bit commands, and would like to replace them with a newer 32 bit command.  I have looked at the fstream commands and also the CreateFile and ReadFile commands in VC++, but found that they do not work the same (and CreateFile seems like extreme overkill).  What commands can I use as the equivalent.  I really need to read in a block of bytes into this structure like they do in the _lread command above.  Please help!

Thanks a lot... let me know if this question is harder than it seems...
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

If you don't like the functions, you can write your own simpler functions that use these funnctions.  Then you can use your simpler functions.  For example you could write a function that returns false to indicate a problem when ReadFile() was not able to read the reqeusted length (meaning you hit the end of the file.).

I can help you with these functions if you have more specific questions.  At the moment your question is should I use them?  and the answer is yes.
Avatar of visual032798

ASKER

I notice with the _lopen command, they are able to read directly into that BITMAPFILEHEADER structure, but with ReadFile, it said I couldn't do that because it couldn't translate it to char*.  Am I doing something wrong?  How do you recommend using the CreateFile and ReadFile commands (could you show me an example) on how to do this?  Thanks again.

The following sample is an "interface" for the ReadFile() function.  It returns one of two values.  One indicates no error.  The second indicates the end of the file was reached during the read.  Any other error is handled by displaying an error message and invoking the debugger.  

The nice thing about this function is you don't have to pass a pointer to a varaible to receive the read length.  ReadFile requires this variable, but it is inconvenient.  This function passes one for you so you don't have to.  It also examines the value returned in the variable and determines how to handle it.

//      This procedure reads the data of a specified length from a file specified by a file       //
// object.  The data is read starting at the current file pointer position.  It is an error to    //
// specify a file object that is not open.  This procedure is similar to the Red() procedure,     //
// except, the read procedure logs an error when the end of file is reached.                      //
//                                                                                                //
//      If the file is not open or any other read error occurs (except for reaching the end of    //
// the file), a terminal error will be logged.                                                    //
//                                                                                                //
// +--------------------------------------------------------------------------------------------+ //
// ¦Error Codes                                                                                 ¦ //
// +--------------------------------------------------------------------------------------------¦ //
// ¦Error Code¦Description                                                                      ¦ //
// +----------+---------------------------------------------------------------------------------¦ //
// ¦QFilErrNon¦No error occurred.                                                               ¦ //
// ¦QFilErrEnd¦Attempt to read past end of file occured.  Only portion up to end of file will   ¦ //
// ¦          ¦have been read.                                                                  ¦ //
// +--------------------------------------------------------------------------------------------+ //
int                                              // Error code.                                   //
QFil::FilRedAvl(QMemPtr  DatPtr,                 // -> buffer to receive data that is read.       //
                                                 // Buffer must be long enough to store the       //
                                                 // specified data.                               //
                QFilOff  RedLen,                 // Length to be read.                            //
                QFilOff &LenRed) const           // Returns length read from the file.            //
{
   QFilChk(*this,true,false);                    // Check this file object.                       //

   int ErrCod = QFilErrNon;                      // Error code to be returned.                    //

   if (!ReadFile(FilHnd,DatPtr,RedLen,&LenRed,NULL)) // If file can't be read from, then          //
      WndErr(__LINE__,"File",true);              // Display an error.                             //
   else if (RedLen != LenRed)                    // Otherwise if requested length wasn't read,    //
      ErrCod = QFilErrEnd;                       // Indicate that end of file was reached.        //

   return ErrCod;                                // Return the error code.                        //
}



If you still have code that the compiler can't compile, post it for me to see.
Opps.  I'm wrong.  I didn't read my own code carefully.  For that function you DO need to pass a variable to receive the length read.

But I have a second function, built on the first one, where you don't have to pass a varaible to receive the length read.  The code is below  This way I can choose a function that suits my needs.  One is for the case when I want to know exacly how much is read.  The other is for the case when I require that the entire length be read.

//      This procedure reads the data of a specified length from a file specified by a file       //
// object.  The data is read starting at the current file pointer position.  It is an error to    //
// specify a file object that is not open.  This procedure is similar to the Red() procedure,     //
// except, the read procedure logs an error when the end of file is reached.                      //
//                                                                                                //
//      If the file is not open or any other read error occurs (except for reaching the end of    //
// the file), a terminal error will be logged.                                                    //
//                                                                                                //
// +--------------------------------------------------------------------------------------------+ //
// ¦Error Codes                                                                                 ¦ //
// +--------------------------------------------------------------------------------------------¦ //
// ¦Error Code¦Description                                                                      ¦ //
// +----------+---------------------------------------------------------------------------------¦ //
// ¦QFilErrNon¦No error occurred.                                                               ¦ //
// ¦QFilErrEnd¦Attempt to read past end of file occured.  Only portion up to end of file will   ¦ //
// ¦          ¦have been read.                                                                  ¦ //
// +--------------------------------------------------------------------------------------------+ //
int                                              // Error code.                                   //
QFil::FilRedAvl(QMemPtr DatPtr,                  // -> buffer to receive data that is read.       //
                                                 // Buffer must be long enough to store the       //
                                                 // specified data.                               //
                QFilOff RedLen) const            // Length to be read.                            //
{
   QFilOff LenRed;                               // Length read from the file.                    //

   return FilRedAvl(DatPtr,RedLen,LenRed);       // Try to read from the file.                    //
}