Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 393
  • Last Modified:

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;
////////////////////////////////////////////////////////////
0
Amaresh080997
Asked:
Amaresh080997
  • 6
  • 5
1 Solution
 
nietodCommented:
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.
0
 
nietodCommented:
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?  


0
 
Amaresh080997Author Commented:
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
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
nietodCommented:
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...
0
 
Amaresh080997Author Commented:
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???
0
 
nietodCommented:
I don't see problem in the code you've shown.  It may be in the construction/opening of the fstream.
0
 
The_BrainCommented:
close the file and reopen it, that worked for me.
0
 
Amaresh080997Author Commented:
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
}
0
 
Amaresh080997Author Commented:
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????
0
 
nietodCommented:
That should be fine.  I would not recommend fooling around with or closing the stream's file buffers though.
0
 
Amaresh080997Author Commented:
Even I don't want to do that way...But I am yet to figure out as to why it is not working :-( :-(
0
 
Amaresh080997Author Commented:
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
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now