Using fstream tellg to read a portion of the stream till the end

I

IlyaK

Hello:

I have this simple code that needs to get a chunk of a large log file
that is being written into. At some point it stores the current
location returned from
streampos start = istream::tellg();
method.
Later on the code has to read from the stream a buffer from the start
till the end. The code is approximately like this:

streampos start = my_stream.tellg();

... // do some stuff with logging

streampos end = my_stream.tellg();
const streamsize size_to_read = (end - start);
char *buf = new char[size_to_read];

lock (m_logReadLock);
{
my_stream.flush();
my_stream.seekg(start);
my_stream.read(buf, size_to_read);
size_read = my_stream->gcount();
}
unlock (m_logReadLock);

The effect that I'm observing is that **size_read** is *smaller* than
**size_to_read** and the stream has its eof flag set. Shouldn't the
end pointer specify exactly where the stream ends and read() method
return that exact amount of data?
It is fine, I can work round it by checking the eof flag.
However, can anyone provide the explanation for this effect?

Thanks.
 
J

John H.

I have this simple code that needs to get a chunk of a large log file
that is being written into. At some point it stores the current
location returned from
streampos start = istream::tellg();
method.
Later on the code has to read from the stream a buffer from the start
till the end. The code is approximately like this:
The effect that I'm observing is that **size_read** is *smaller* than
**size_to_read**

What you are seeing may be an effect of the "mode" of the fstream. If
I recall correctly, it will default to "text" mode. In this mode,
newlines are converted upon writing to carriagereturn linefeed, and
reconverted when reading. Thus every newline takes up two bytes on
the disk file (one for cr, one for lf), but only one byte in memory
(\n), so you write two bytes but read back only one.
The other mode is "binary", and here a newline will just be written as
a newline. So one byte out, one byte in.
To see if this is the problem you are facing, try setting the fstream
mode to binary. Here is an example program:

#include <iostream>
#include <fstream>

int main()
{
std::fstream text_file;
text_file.open("text", std::fstream::in | std::fstream::eek:ut |
std::fstream::trunc);
std::streampos const text_start = text_file.tellg();
text_file << "hi\n";
std::streampos const text_end = text_file.tellg();
std::streamsize const text_written = text_end - text_start;

char * const text_buf = new char[text_written+1];
memset(text_buf, 0, text_written+1);

text_file.flush();
text_file.seekg(text_start);
text_file.read(text_buf, text_written);
size_t text_read = text_file.gcount();

std::cout << "Text size written = " << text_written << std::endl;
std::cout << "Text size read = " << text_read << std::endl;
std::cout << text_buf << std::endl;
delete[] text_buf;


std::fstream binary_file;
binary_file.open("text", std::fstream::in | std::fstream::eek:ut |
std::fstream::trunc | std::fstream::binary);
std::streampos const binary_start = binary_file.tellg();
binary_file << "hi\n";
std::streampos const binary_end = binary_file.tellg();
std::streamsize const binary_written = binary_end - binary_start;

char * const binary_buf = new char[binary_written+1];
memset(binary_buf, 0, binary_written+1);

binary_file.flush();
binary_file.seekg(binary_start);
binary_file.read(binary_buf, binary_written);
size_t binary_read = binary_file.gcount();

std::cout << "Binary size written = " << binary_written <<
std::endl;
std::cout << "Binary size read = " << binary_read << std::endl;
std::cout << binary_buf << std::endl;
delete[] binary_buf;

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top