Link to home
Start Free TrialLog in
Avatar of Amaresh080997
Amaresh080997

asked on

Stream...

I am unable to read from a stream(fstream) more than once. To be precise, the following piece of code works fine when it is called first, but doesn't work when it is called for the second time..
Can any of you give me some hints??? Thanks, ----Amaresh
////////////////////// Code ///////////////////////////////
      CDetails* pDetails = new CDetails;
        int nRetVal = pDetails->fStream.is_open();
      if (nRetVal == 0)
            return NULL;
      int nSize = 0;
      // Seek the beginning of the file
      pDetails->fStream.seekg(0,std::ios::beg);
      // Get the file size
      struct _stat FileStatus;
      _stat("C:\\MyProject\\Details.txt",&FileStatus);
      nSize = FileStatus.st_size;
      // Format the buffer and read the file
      m_pszBuffer = new char[nSize];
      memset(m_pszBuffer,'\0',nSize);
      pDetails->fStream.read(m_pszBuffer,nSize);
      return m_pszBuffer;
////////////////////////////////////////////////////////////
Avatar of nietod
nietod

You are opening the file exclusively, meaning that until you close it, it can't be opened again (this is often a bad idea, but not always), the reason this causes problems is that you never close the file, so when your reppeat the code, you try to open it again, and fail.
You could close the file by useing the close() function, but you may have left that out because you know that the file will automatically be closed when the stream object is destroyed, which is a good way to handle things, but the problem is that the stream object is never destroyed.  That is another problem. You allocate a CDetails (with a stream object inside), but never destroy it.  If you delete it the problem should go away.  But why allocate it dynamically?  Can't you just declare it locally?  


Avatar of Amaresh080997

ASKER

Hello Nietod,
         Thankyou very much for taking your time to reply. I give some clarifications...First thing, "PDetails" is not a local member. It is a class member ..(I could have made it clear in my question itself..I could have also used the notation "m_pDetails" to denote that it is a class member..Any way, sorry abt that). So, it gets deleted in the destructor of the class. Don't worry abt that part.
Another thing is, if you see the above function,you may find that I am not opening the stream at all. It is already opened some where else. All that I am doing in the above function is, just checking if it is open. See that, I am calling "is_open()" and not "open". So,I think there is no question of opening it twice or any such thing.  All that I do here is, I just check if the stream is open and if not, I return immediately. If it is open, I do further processing.
I doubt the first parameter of the "seekg" function in my code. What do you think? When I called "tellg" after that "seekg", in the first time it returned 0, but the second time the "tellg" function returned -1, which is wrong. That means the  file pointer is not positioned at the beginning of the file. Does that mean seekg fails the second time I call it? If so, what is the reason? Am I passing the right parameters in side seekg? Is the first parameter (streamoffset) correct?
Please let me know your thoughts on this.
Thanks and Regards,
Amaresh
I guess the deciding factor on my first thought was on the 2nd time through, is the stream open or not?  If not, then it is a problem where the stream is reopened. If so, it is elsewhere.  Check what is happening on this before we continue.

>> I doubt the first parameter of the "seekg" function in my code
That is fine if you want to seek to the start.  But it won't work if the file is not open...
The stream is very much open. The "is_open" function on the first time as well as second time returns "1" . This means the file is open..right???
I don't see problem in the code you've shown.  It may be in the construction/opening of the fstream.
ASKER CERTIFIED SOLUTION
Avatar of The_Brain
The_Brain

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
Brain,
    Thanks for your answer. But in my machine, the close and reopening method also doesnt work. There are a series of strange things happen:
1) When I close and open it again, it sucecssfully opens
2) After I do seekg and once again tellg. The tellg returns -1.
I don't understand why tellg should return -1 when I closed and opened the file again.
So, I tried to open the file using MFC's CFile in the second time. The CFile's open function succeeds, but when I try to read that, it throws an exception with the error code being "CFileException::accessDenied". I am sure I closed the stream and the return value is also okay. The surprising thing is, CFile opened it, but doesn't read it.
So, I called "rdbuf" of the 'fstream" and got the filebuf. Then I closed the filebuf (because I thought it doesn't get closed atomatically). The filebuf's close function returned NULL, which means, there is some error. I am yet to figure that out as to why..
This is the stage where things stand..Any help????
My code snippet for stream closing is as follows: (The return value I get from this following function is 0, which is correct)
////////////////////////////////////////////////////////////////////////////////////////////////////////
int CMyStreamClass::CloseStream()
{
    if (CMyStreamClass::fStream.is_open() ) // First check if the stream is open
     {
        CMyStreamClass::fStream.close();      // If so, close the stream
     }
    if ( DetailsLog::fStream.is_open() )           // Check again if the file is open
        cerr << "Error closing " << filename << endl;  // If yes, it means there is some error
    else                                                           // Else, if it is properly closed,
    {
        filebuf* pFileBuf = NULL;            
        pFileBuf = CMyStreamClass::fStream.rdbuf(); // Get the filebuf attached to file
        if(pFileBuf)
           filebuf* pFileBuffer = pFileBuf->close()  // Close the filebuf..
                  ASSERT(pFileBuffer != NULL) // Fails here!!! pFileBuffer is NULL
     }
     return CMyStreamClass::fStream.is_open(); // Return by checking if the file is open
}
One more thing, how do you open the stream in your program? I do it the following way:
CMyStreamClass::fStream.open("C:\\MyProjects\\Detail.txt",std::ios::in|std::ios::out);
Is that the same thing as you guys do?
I am using microsoft's VC++ 6.0 for my compilation. Any more hints????
That should be fine.  I would not recommend fooling around with or closing the stream's file buffers though.
Even I don't want to do that way...But I am yet to figure out as to why it is not working :-( :-(
Hi Guys,
I could get it to work long back. Sorry about not putting this solution immediately. The problem was, an error bit was set and hence I needed to call "clear" before the call to "seekg" the second time. The following is the sample code that works fine:
------------------------------------------------------------------------------------------------------
long pos = pDetails->fStream.tellg();
if (pos == -1)
{
    int nErrState = pDetails->fStream.rdstate();
    int nFail = pDetails->fStream.fail();
    int nBad = pDetails->fStream.bad();
    if ((nErrState != 0) && (nFail != 0) && (nBad == 0)) // Means something non fatal
       {
      pDetails->fStream.clear();
                // An extra check to see if the error bits are cleared..
      int nGood = pDetails->fStream.good();
      if (nGood == 0)     // Means error bits are not cleared due to some                                                              return NULL;     // abstruse reasons
       }
     pDetails->fStream.seekg(0,std::ios::beg);
}
------------------------------------------------------------------------------------------------------
Thanks for both of you to have taken some time to think through this problem. Now comes the difficult part for me..How do I give the points that I fixed for this Qn? Please help me with suggestion :-) :-)
Thanks,
Amaresh