Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

78 views
Skip to first unread message

IlyaK

unread,
Jan 19, 2010, 12:21:07 PM1/19/10
to
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.

John H.

unread,
Jan 20, 2010, 12:58:00 PM1/20/10
to
On Jan 19, 12:21 pm, IlyaK <katsnel...@gmail.com> wrote:
> 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::out |
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::out |
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;
}

IlyaK

unread,
Jan 20, 2010, 9:34:52 PM1/20/10
to
Thanks, John, for the explanation.
0 new messages