tags:

views:

426

answers:

3

Requirement :


I must read until EOF (16 bytes a time) from a particular file , and then say sleep for 5 seconds. Now, after 5 seconds, when I try to read from the file (whose contents would have been appended by that time), the intended design must be in such a way that it reads from the point where it left previously and again scan the contents (16 bytes a time) until EOF is reached.

I have written (basic) code to read from the given file (until EOF - 16 bytes a time) using ifstream as follows :

#include <stdio.h> 
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;


int main() 
{ 

    int fd, i, j, length, pos;
    char buffer[100][16];
    ifstream Read;
    std::ostringstream oss;
    int current_position = 0;
    Read.open("from4to5", ios::binary);

    //Get the size of the file
    Read.seekg(0, ios::end);
    length = Read.tellg();
    Read.seekg(0, ios::beg);


    for(i=0; i<length; i++)
    {

         buffer[i][16] = '\0';
    }

    //Read the file in 16byte segments or eof(), whichever comes first
    //Testing the return condition of the function is preferred, as opposed to testing eof()

    while(Read.get(buffer[i], 17))
    {
     for(j=0; j<=16; j++)
      oss << buffer[i][j];
     cout << "Contents : " << oss.str() << endl;
     oss.seekp(0);
        i++;
    }



    // Output is :
    // Contents : BD8d3700indiaC#E
    // Contents : BD6d4700godgeD3E
    // Contents : BD9d1311badge3TE


    return 0;
}

I need to modify this to suit my requirement. I tried using the seekg() call, but somehow failed. I was wondering if, when the first time I accessed and read from the file into filestream, somehow the program would have placed an exclusive lock on the file, which would mean that I'll not be able to read from it the next time around.

Can anyone show me how it's to be done?

Filename : "from4to5" Contents:

BD8d3700indiaC#EBD6d4700godgeD3EBD9d1311badge3TE

Within 5 seconds, some other process writes(appends) to the same file "from4to5" Now,

File Contents:

BD8d3700indiaC#EBD6d4700godgeD3EBD9d1311badge3TEBD6d1210clerk41EBD2d1100mayor47EBD4d2810bread6YE

Now, when the program reads from the file "from4to5", it must read from the point where it left previously, 16 bytes a time until it encounters EOF.

Intention for output this time around is :

// Output is :
// Contents : BD6d1210clerk41E
// Contents : BD2d1100mayor47E
// Contents : BD4d2810bread6YE
+4  A: 

You'll have to:
save your position
close the file
reopen the file
seek to your saved postion and resume reading until EOF

KevinDTimm
Solved - Thanks for all the help.Code here : http://clipboard.it/v/Y1b/Mirror : http://pastebin.com/f649ab552
halluc1nati0n
+1  A: 

You should be able to clear the EOF flag on the input stream and continue reading.

while (true)
{
    while(Read.get(buffer[i], 17))
    {
        for(j=0; j<=16; j++)
                oss << buffer[i][j];
        cout << "Contents : " << oss.str() << endl;
        oss.seekp(0);
        i++;
    }
    Read.clear();
    sleep(5);
}

You could run into problems if you are reading at the same time that the file is being written, where you are not able to read all 16 bytes. This can lead to some intermittent, hard to track down bugs. At the very least, you should add in some error checking.

KeithB
I have to ask, doesn't this method (Read.clear()) do the trick? If so, this is a better answer than mine :)
KevinDTimm
Yes, Read.clear() does the trick.
Jagannath
A: 

To clarify, if the stream encounters the end of the file, the stream will change the status of the stream. Any reads after the EOF is encountered will not be valid (or perhaps the term is "will be undefined").

I would recommend clearing the stream after you have read the last chunk of data. Also, during debugging, check the stream status before reading.

Thomas Matthews