get size info from a std::ofstream instance

W

William Xu

I try to write a Logger class, using std::eek:fstream. One of the
requirements is that the log file size could be limited to some bytes.
So I'm thinking that I should check its size before writing new
contents. I wrote something like:

,----
| std::eek:fstream log("foo.txt");
|
| log << "hello" << std::endl;
|
| // How much characters in `log' now?
`----

How can I get the size info from `log' ? I failed to find a sufficient
api from the c++ std.
 
J

James Kanze

I try to write a Logger class, using std::eek:fstream. One of the
requirements is that the log file size could be limited to some bytes.
So I'm thinking that I should check its size before writing new
contents. I wrote something like:
,----
| std::eek:fstream log("foo.txt");
|
| log << "hello" << std::endl;
|
| // How much characters in `log' now?
`----
How can I get the size info from `log' ? I failed to find a sufficient
api from the c++ std.

You can't. The usual solution here is to use a custom
streambuf, which keeps track of how many characters have been
written, and rotates the files when they get too big.
 
W

William Xu

James Kanze said:
You can't. The usual solution here is to use a custom
streambuf, which keeps track of how many characters have been
written, and rotates the files when they get too big.

That means defining a custom class inherited from streambuf?

I find fstream has a pointer member to streambuf, namely, rdbuf(). It
seems I can always refer to it, seek end, get size info:

,----
| int sz = log.rdbuf()->pubseekoff(0, std::ios_base::end);
`----

Only I don't know how well its performance could be. Performance is also
a requirement for me.
 
J

James Kanze

That means defining a custom class inherited from streambuf?

Yep. In theory, you could probably inherit directly from
filebuf, calling close() and open() at appropriate times. But
the standard doesn't really specify how a derived streambuf
co-ordinates the various virtual functions (sync() and
overflow(), for example), so you're probably better off having
the filebuf as a member, and forwarding to it.
I find fstream has a pointer member to streambuf, namely,
rdbuf(). It seems I can always refer to it, seek end, get size
info:
,----
| int sz = log.rdbuf()->pubseekoff(0, std::ios_base::end);
`----
Only I don't know how well its performance could be.
Performance is also a requirement for me.

Not only performance. Formally, the above is not even
guaranteed to compile, although in practice, it would be a very
exotic system on which you had problems. And on which it didn't
actually return the value you're looking for, although that too
is definitely not guaranteed. But it's doing things the hard
way. Since all output does have to go through the streambuf,
it's trivial to write an implementation which counts what's been
output on the fly, and bases its decision on that. (Or maybe
I'm just biased with regards to what is the "hard way". I've
never had a case where I didn't need a custom streambuf for
logging anyway, and of course, once you've got that, adding the
code to count is trivial.)
 
W

William Xu

James Kanze said:
Not only performance. Formally, the above is not even
guaranteed to compile, although in practice, it would be a very
exotic system on which you had problems. And on which it didn't
actually return the value you're looking for, although that too
is definitely not guaranteed. But it's doing things the hard
way. Since all output does have to go through the streambuf,
it's trivial to write an implementation which counts what's been
output on the fly, and bases its decision on that. (Or maybe
I'm just biased with regards to what is the "hard way". I've
never had a case where I didn't need a custom streambuf for
logging anyway, and of course, once you've got that, adding the
code to count is trivial.)

Thanks. I'm starting to implement my own streambuf.
 

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

Forum statistics

Threads
473,996
Messages
2,570,237
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top