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

int main() 
{ 

  int fd, i, oflag;
  char buf[100];

  oflag = (O_RDONLY);
  fd = open("from4to5", oflag, 0x1c0);
  if (fd < 0 ) {printf("Error opening\n"); exit(1);}
	 
  while ( (i = read(fd, buf, 16)) != 0 ) {

       cout << "child: # bytes read which were: " <<  buf <<endl;   
   };

  close(fd);
  return 0;
}

Say I have a file called 'from4to5' with contents like this.

BD8d3700indiaC#EBD6d4700godgeD3EBD9d1311badge3TE

I have to read 16 bytes using the low-level function call read() (in C). After I read the first 16 bytes, the next time I need to read from the same file, I'll only have to read it from until the point it was read before..

How do I accomplish that ? The code snippet, by the way, reads until EOF occurs, 16 bytes a time.

Recommended Answers

All 15 Replies

then invoke the read() method before the loop to read the 1st 16 byte.
If u dont want to read the remaining till the end remove the while loop.
But I suppose U want to read the remaining also, then just keep them or make necessary change as u like to read.

then invoke the read() method before the loop to read the 1st 16 byte.
If u dont want to read the remaining till the end remove the while loop.
But I suppose U want to read the remaining also, then just keep them or make necessary change as u like to read.

Ahm, I guess I didn't phrase my question properly.
Suppose the whole main() function is called every 5 seconds..

I read until EOF (16 bytes a time) from that particular file , and then say sleep for 5 seconds. Now, after 5 seconds, when I try to read from the file, 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.

How'd I do this?

I have to read 16 bytes using the low-level function call read() (in C). After I read the first 16 bytes, the next time I need to read from the same file, I'll only have to read it from until the point it was read before..

Since you only require to read in a certain amount of the file (as opposed to reading in the entire file at once) I think readsome() function may be a more appropriate choice:

istream::readsome

public member function

streamsize readsome ( char* s, streamsize n );

Read block of data available in the buffer
Reads a block of data of up to n characters and stores it in the array pointed by s, but unlike member function read, readsome stops reading if the memory buffer associated with the stream runs out of characters, even if the End-Of-File has not yet been reached.

Return Value
The number of characters extracted.

Errors are signaled by modifying the internal state flags.

With this in mind, I would propose using the readsome() function and reading the file into a char[16] buffers (or char[17] if you would like to provide null termination which will allow you to use <cstring> functions safely)

Since you would probably need to use several char[16] buffers, let's create a bunch of them:

char buffer[100][16];

A more optimal alternative of course, would be to dynamically create an array of specific size based on the number of characters in your file:

//Writen in c++, since this is a c++ forum

//Get size of file (char count)
infile.seekg(0, ios::end);
length = infile.tellg();
infile.seekg(0, ios::beg);

int leftover = length;

//Find out how many 16byte segments we have available
length /= 16;

//If you want, find out how much (if any) is leftover
//Although readsome() can handle this situation by testing for eof()
leftover %= 16;

//Now create the 16 byte (or 17 if you want null termination) buffers dynamically
char* buffer = new char*[length];
for(int i=0; i<length; i++)
     buffer[i] = new char[16];  //or [17] if you want space for null termination

Now you have the ability to read in little chunks of file on demand. You mentioned that you would like to keep track of where abouts you are in the file as you read stuff in. This can be done by calling the tellg() function which returns the current character position in the file:

//Be sure your file is opened in binary mode, or else tellg() return a position different than what you would expect
infile.open(C:\\Documents\\myfile.txt, ios::binary);

int current_position = 0;

//Read a block of data from file
infile.readsome(buffer[i], 16);

//Save current position in file
current_position = infile.tellg();
commented: Good ideas.. +1

It does show me the way I have to go. Thanks about it.
Question:
Assume I have the position now from tellg. How do I now read from that (offset) point?

I am glad you asked. Use the seekg() function to move about in your file as ye' wish:

istream::seekg

public member functionistream& seekg ( streampos pos );
istream& seekg ( streamoff off, ios_base::seekdir dir );
Set position of the get pointer

Sets the position of the get pointer.
The get pointer determines the next location to be read in the source associated to the stream.


Parameters

pos
The new position in the stream buffer. This parameter is an integral value of type streampos.

off
Integral value of type streamoff representing the offset to be applied relative to an absolute position specified in the dir parameter.

dir
Seeking direction. It is an object of type ios_base::seekdir that specifies an absolute position from where the offset parameter off is applied. It can take any of the following member constant values:
value offset is relative to...

ios_base::beg beginning of the stream buffer
ios_base::cur current position in the stream buffer
ios_base::end end of the stream buffer

Return Value
The function returns *this.

So just call a seekg(position) whenever you want to set the 'get pointer' to a position where ye' would like to start reading from the file. Then I would call the readsome() function to read in a chunk of the file.

Keep in mind, if you are reading the file in a contiguous manor, the 'get pointer' will be at the position where you left it, in which case there is no need to make any extra effort to record and set it's position.

@ Clinton Portis :

I tried using seekg(), but my intended output was much different. Could you look into this?

http://pastebin.com/f6bc14999

without even looking, I will guess that your file has not been opened in binary mode; in which case, I would highly recommend doing so whilst messing about with file pointers.

[Edit]
Ok.. you opened in binary.. I'll look into this a bit and see if I see anything.

Line#19: You are reading the file based on the current condition of the eof() fail bit flag, not recommended.

Lines#27 thru #33: You are attempting to seekg() to your current position....... which, you are already at :rollseyes:

I am going to make a few assumptions here and attempt to help you out.

1. You are attempting to read in the file in a contiguous manner.
2. You would like to break up the file into 16byte chunks.

With this in mind, we can focus strictly on the task at hand:

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

//Create a buffer to meet our needs
char* buffer = new char*[length];
for(int i=0; i<length; i++)
{
     buffer[i] = new char[17];
     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()
int i=0;
while(Read.get(buffer[i], 16))
{
     i++;
}

There you have it... simple, straight forward, no unecessary file pointer manipulation.

But if you still desire the ability to move about in your file, check out this recent post.

http://www.daniweb.com/forums/thread242275.html

@ Clinton Portis :

By the way, I assume, from your first post on this topic, that you've gotten my intention wrong.

This is what I need :

I read until EOF (16 bytes a time) from that particular file , and then say sleep for 5 seconds. Now, after 5 seconds, when I try to read from the file, 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.

Just add a sleep function of some sort in the file reading loop (after line#19 perhaps).. otherwise, the above code will meet your stringent requirements, reading the file contiguously from the point it left off.

Just add a sleep function of some sort in the file reading loop (after line#19 perhaps).. otherwise, the above code will meet your stringent requirements, reading the file contiguously from the point it left off.

I'll have a look at it.. Thanks.
Will report back if I find more issues :D

without even looking, I will guess that your file has not been opened in binary mode; in which case, I would highly recommend doing so whilst messing about with file pointers.

[Edit]
Ok.. you opened in binary.. I'll look into this a bit and see if I see anything.

Line#19: You are reading the file based on the current condition of the eof() fail bit flag, not recommended.

Lines#27 thru #33: You are attempting to seekg() to your current position....... which, you are already at :rollseyes:

I am going to make a few assumptions here and attempt to help you out.

1. You are attempting to read in the file in a contiguous manner.
2. You would like to break up the file into 16byte chunks.

With this in mind, we can focus strictly on the task at hand:

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

//Create a buffer to meet our needs
char* buffer = new char*[length];
for(int i=0; i<length; i++)
{
     buffer[i] = new char[17];
     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()
int i=0;
while(Read.get(buffer[i], 16))
{
     i++;
}

There you have it... simple, straight forward, no unecessary file pointer manipulation.

But if you still desire the ability to move about in your file, check out this recent post.

http://www.daniweb.com/forums/thread242275.html

Well, for starters, the code didn't compile. I made some modifications and got it to run, still I'm not sure I've gotten what I'd desired..

EDIT:
First try : http://clipboard.it/v/lZb/

Well, this works, but lets assume, now I read until EOF, and then my program sleeps and someone else modifies that particular file. Now, I need to read from that point ..

Second try : http://clipboard.it/v/yVb/

Doesn't work as desired - Coz' I assume the program acquires an exclusive lock for the file (for the program??). Eventhough, I can change and save the file, my program cannot read the file from that point on..

Any solutions?

Although I am not an <sstream> expert (don't use it that much) I am kinda skeptical about this code:

while(Read.get(buffer[i], 17))
{
     for(j=0; j<=16; j++)
     oss << buffer[i][j];

It seems to me like you are continually just overwritting the value inserted into your 'oss' object... to me, this would seem a more viable method:

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

Check this out and see if you have any questions about this working program:

#include<iostream>
#include<string>
#include<fstream>
#include<windows.h>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    //var declarations
    int length = 0;
    char buffer[17];
    vector<char*> cstrings;

    //create ifstream object for reading from a file
    ifstream infile;

    //attempt to open a file 
    //in this case, since we are dealing primarily with ascii chars
    //it is better to open in regular default ascii mode.
    infile.open("C:\\Users\\Dave\\Documents\\test.txt");

    //perform error checking
    if(!infile.is_open())
    {
        cout << "\aError opening file!";
        cin.get();
        exit(EXIT_FAILURE);
    }

    int i=1;
    buffer[16] = '\0';
    //read in file in 16 byte segments, or as much is left until end of file
    while(infile.readsome(buffer, 16))
    {        
        //take out '\n' newlines for console formatting purposes
        replace(&buffer[0], &buffer[16], '\n', ' ');
        //display exciting information to the user
        cout << "\n\nBock #" << i << ": " << buffer;
        cout << "\nChar count: " << infile.gcount();
        //save our buffer in an 'array type' STL container
        cstrings.push_back(buffer);
        //perform sleep operation
        Sleep(500);
        //step up the block number
        i++;
    }

    //close the ifstream object since we no longer need to read from a file
    infile.close();

    return 0;
}

New and improved version:

#include<iostream>
#include<string>
#include<fstream>
#include<windows.h>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    //var declarations
    int length = 0;
    char* buffer = new char[17];
    buffer[16] = '\0';
    vector<char*> cstrings;

    //create ifstream object for reading from a file
    ifstream infile;

    //attempt to open a file
    //in this case, since we are dealing mostly with ascii chars
    //it is better to open in regular default ascii mode.
    infile.open("C:\\Users\\Dave\\Documents\\test.txt");

    //perform error checking
    if(!infile.is_open())
    {
        cout << "\aError opening file!";
        cin.get();
        exit(EXIT_FAILURE);
    }

    int i=1;
    //read in file in 16 byte segments, or as much is left until end of file
    while(infile.readsome(buffer, 16))
    {
        //take out '\n' newlines for console formatting purposes
        replace(&buffer[0], &buffer[16], '\n', ' ');
        //display exciting information to the user
        cout << "\n\nBock #" << i << ": " << buffer;
        cout << "\nChar count: " << infile.gcount();
        //save our buffer in an 'array type' STL container
        cstrings.push_back(buffer);
        //create new buffer
        buffer = new char[17];
        //ensure 'cstring style' null termination
        buffer[16] = '\0';
        //perform sleep operation
        Sleep(500);
        //step up the block number
        i++;
    }

    //close the ifstream object since we no longer need to read from a file
    infile.close();

    return 0;
}

New and improved version:

Well, I solved it too ...

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

 
int main() 
{ 

	int fd, i, j, length, pos;
	int k, bytes_read;
	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);
			bytes_read = bytes_read + 16;
		    i++;
		}
		Read.clear();
		Read.close();
		
		
		sleep(15);
		
		Read.open("from4to5", ios::binary);
		Read.seekg(bytes_read);	

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


	return 0;
}

http://clipboard.it/v/Y1b/
http://pastebin.com/f32344783


Cheers! :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.