30.9.2 Class template basic_filebuf [filebuf]
namespace std {
template <class charT, class traits = char_traits<charT>>
class basic_filebuf : public basic_streambuf<charT, traits> {
public:
using char_type = charT;
using int_type = typename traits::int_type;
using pos_type = typename traits::pos_type;
using off_type = typename traits::off_type;
using traits_type = traits;
basic_filebuf();
basic_filebuf(const basic_filebuf& rhs) = delete;
basic_filebuf(basic_filebuf&& rhs);
virtual ~basic_filebuf();
basic_filebuf& operator=(const basic_filebuf& rhs) = delete;
basic_filebuf& operator=(basic_filebuf&& rhs);
void swap(basic_filebuf& rhs);
bool is_open() const;
basic_filebuf* open(const char* s, ios_base::openmode mode);
basic_filebuf* open(const filesystem::path::value_type* s,
ios_base::openmode mode); basic_filebuf* open(const string& s,
ios_base::openmode mode);
basic_filebuf* open(const filesystem::path& s,
ios_base::openmode mode);
basic_filebuf* close();
protected:
streamsize showmanyc() override;
int_type underflow() override;
int_type uflow() override;
int_type pbackfail(int_type c = traits::eof()) override;
int_type overflow (int_type c = traits::eof()) override;
basic_streambuf<charT, traits>* setbuf(char_type* s,
streamsize n) override;
pos_type seekoff(off_type off, ios_base::seekdir way,
ios_base::openmode which
= ios_base::in | ios_base::out) override;
pos_type seekpos(pos_type sp,
ios_base::openmode which
= ios_base::in | ios_base::out) override;
int sync() override;
void imbue(const locale& loc) override;
};
template <class charT, class traits>
void swap(basic_filebuf<charT, traits>& x,
basic_filebuf<charT, traits>& y);
}
The class
basic_filebuf<charT, traits>
associates both the input sequence and the output
sequence with a file
.The restrictions on reading and writing a sequence controlled by an
object of class
basic_filebuf<charT, traits>
are the same as for reading and writing with the C standard library
FILEs
.In particular:
If the file is not open for reading the input sequence
cannot be read
.If the file is not open for writing the output
sequence cannot be written
.A joint file position is maintained for both the input sequence and
the output sequence
.
An instance of
basic_filebuf
behaves as described in
[filebuf] provided
traits::pos_type
is
fpos<traits::state_type>. Otherwise the behavior is undefined
.In order to support file I/O and multibyte/wide character conversion,
conversions are performed using members of a facet, referred to as
a_codecvt in following sections, obtained as if by
const codecvt<charT, char, typename traits::state_type>& a_codecvt =
use_facet<codecvt<charT, char, typename traits::state_type>>(getloc());
basic_filebuf();
Effects:
Constructs an object of class
basic_filebuf<charT, traits>,
initializing the base class with
basic_streambuf<charT, traits>() (
[streambuf.cons])
. Postconditions:
is_open() == false. basic_filebuf(basic_filebuf&& rhs);
Effects: Move constructs from the rvalue
rhs. It
is
implementation-defined whether the sequence pointers in
*this
(
eback(),
gptr(),
egptr(),
pbase(),
pptr(),
epptr()) obtain
the values which
rhs had
. Whether they do or not,
*this
and
rhs reference separate buffers (if any at all) after the
construction
. Additionally
*this references the file
which
rhs did before the construction, and
rhs references no file after the construction
. The
openmode, locale and any other state of
rhs is also
copied
.Postconditions: Let
rhs_p refer to the state of
rhs just prior to this construction and let
rhs_a
refer to the state of
rhs just after this construction
. is_open() == rhs_p.is_open()
rhs_a.is_open() == false
gptr() - eback() == rhs_p.gptr() - rhs_p.eback()
egptr() - eback() == rhs_p.egptr() - rhs_p.eback()
pptr() - pbase() == rhs_p.pptr() - rhs_p.pbase()
epptr() - pbase() == rhs_p.epptr() - rhs_p.pbase()
if (eback()) eback() != rhs_a.eback()
if (gptr()) gptr() != rhs_a.gptr()
if (egptr()) egptr() != rhs_a.egptr()
if (pbase()) pbase() != rhs_a.pbase()
if (pptr()) pptr() != rhs_a.pptr()
if (epptr()) epptr() != rhs_a.epptr()
virtual ~basic_filebuf();
Effects:
Destroys an object of class
basic_filebuf<charT, traits>. If an exception occurs during the destruction of the object, including the call to
close(), the exception is caught but not rethrown (see
[res.on.exception.handling])
.basic_filebuf& operator=(basic_filebuf&& rhs);
Effects: Calls
close() then move assigns from
rhs. After the
move assignment
*this has the observable state it would have had if it
had been move constructed from
rhs (see
[filebuf.cons])
.void swap(basic_filebuf& rhs);
Effects: Exchanges the state of
*this
and
rhs. template <class charT, class traits>
void swap(basic_filebuf<charT, traits>& x,
basic_filebuf<charT, traits>& y);
Effects: As if by
x.swap(y). bool is_open() const;
Returns:
true
if a previous call to
open
succeeded (returned a non-null value) and there has been no intervening
call to close
. basic_filebuf* open(const char* s, ios_base::openmode mode);
basic_filebuf* open(const filesystem::path::value_type* s,
ios_base::openmode mode);
Effects:
If
is_open() != false,
returns a null pointer
. Otherwise,
initializes the
filebuf
as required
. It then opens a file, if possible, whose name is the
ntbs s
(as if by calling
fopen(s, modstr))
. The
ntbs modstr is determined from
mode & ~ios_base::ate
as indicated in Table
112. If
mode is not some combination of flags shown in the table then
the open fails
.Table
112 — File open modes
ios_base flag combination | stdio equivalent |
binary | in | out | trunc | app | |
| | + | | | "w" |
| | + | | + | "a" |
| | | | + | "a" |
| | + | + | | "w" |
| + | | | | "r" |
| + | + | | | "r+" |
| + | + | + | | "w+" |
| + | + | | + | "a+" |
| + | | | + | "a+" |
+ | | + | | | "wb" |
+ | | + | | + | "ab" |
+ | | | | + | "ab" |
+ | | + | + | | "wb" |
+ | + | | | | "rb" |
+ | + | + | | | "r+b" |
+ | + | + | + | | "w+b" |
+ | + | + | | + | "a+b" |
+ | + | | | + | "a+b" |
If the open operation succeeds and
(mode & ios_base::ate) != 0,
positions the file to the end
(as if by calling
fseek(file, 0, SEEK_END))
.If the repositioning operation fails, calls
close()
and returns a null pointer to indicate failure
.Returns:
this
if successful, a null pointer otherwise
. basic_filebuf* open(const string& s, ios_base::openmode mode);
basic_filebuf* open(const filesystem::path& s, ios_base::openmode mode);
Returns:
open(s.c_str(), mode);
basic_filebuf* close();
Effects:
If
is_open() == false,
returns a null pointer
. If a put area exists, calls
overflow(traits::eof())
to flush characters
. If the last virtual member function called on
*this
(between
underflow,
overflow,
seekoff,
and
seekpos)
was
overflow
then calls
a_codecvt.unshift
(possibly several times) to determine a termination sequence, inserts those
characters and calls
overflow(traits::eof())
again
. Finally, regardless of whether any of the preceding calls fails or throws an
exception, the function closes the file
(as if by calling
fclose(file))
. If any of the calls made by the function, including
fclose, fails,
close fails by returning a null pointer
. If one of these calls throws an
exception, the exception is caught and rethrown after closing the file
.Returns:
this
on success, a null pointer otherwise
. Postconditions:
is_open() == false. streamsize showmanyc() override;
Remarks:
An
implementation might well provide an overriding definition for this function
signature if it can determine that more characters can be read from the input
sequence
. int_type underflow() override;
Effects:
Behaves according to the description of
basic_streambuf<charT, traits>::underflow(),
with the specialization that a sequence of characters is read from the input
sequence as if by reading from the associated file
into an internal buffer (extern_buf)
and then as if by doing:
char extern_buf[XSIZE];
char* extern_end;
charT intern_buf[ISIZE];
charT* intern_end;
codecvt_base::result r =
a_codecvt.in(state, extern_buf, extern_buf+XSIZE, extern_end,
intern_buf, intern_buf+ISIZE, intern_end);
This shall be done in such a way that the class can recover the
position
(
fpos_t)
corresponding to each character between
intern_buf
and
intern_end. If the value of
r
indicates that
a_codecvt.in()
ran out of space in
intern_buf,
retry with a larger
intern_buf.int_type uflow() override;
Effects:
Behaves according to the description of
basic_streambuf<charT, traits>::uflow(),
with the specialization that a sequence of characters is read from the input
with the same method as used by
underflow. int_type pbackfail(int_type c = traits::eof()) override;
Effects:
Puts back the character designated by
c to the input
sequence, if possible, in one of three ways:
If
traits::eq_int_type(c, traits::eof())
returns
false
and
if the function makes a putback position available
and if
traits::eq(to_char_type(c), gptr()[-1])
returns
true,
decrements the next pointer for the input sequence,
gptr().If
traits::eq_int_type(c, traits::eof())
returns
false
and
if the function makes a putback position available
and if the function is permitted to assign to the putback position,
decrements the next pointer for the input sequence,
and stores
c there
.If
traits::eq_int_type(c, traits::eof())
returns
true,
and if either the input sequence has a putback position available or
the function makes a putback position available,
decrements the next pointer for the input sequence,
gptr().Returns:
traits::not_eof(c).
Returns:
traits::eof()
to indicate failure
. Remarks:
If
is_open() == false,
the function always fails
. The function does not put back a character directly to the input sequence
.If the function can succeed in more than one of these ways, it is
unspecified which way is chosen
. The function can alter the number of putback positions available as a result of any call
.int_type overflow(int_type c = traits::eof()) override;
Effects:
Behaves according to the description of
basic_streambuf<charT, traits>::overflow(c),
except that the behavior of “consuming characters” is performed by first
converting as if by:
charT* b = pbase();
charT* p = pptr();
charT* end;
char xbuf[XSIZE];
char* xbuf_end;
codecvt_base::result r =
a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end);
and then
If
r == codecvt_base::error then fail
.If
r == codecvt_base::noconv then output characters from
b up to (and not including)
p.If
r == codecvt_base::partial then output to the file characters from
xbuf up to
xbuf_end, and repeat using characters from
end to
p. If output fails, fail (without repeating)
.Otherwise output from
xbuf to
xbuf_end, and fail if output fails
. At this point if
b != p and
b == end (
xbuf isn't large
enough) then increase
XSIZE and repeat from the beginning
.
Returns:
traits::not_eof(c)
to indicate success, and
traits::eof()
to indicate failure
. If
is_open() == false,
the function always fails
.basic_streambuf* setbuf(char_type* s, streamsize n) override;
Effects:
If
setbuf(0, 0)
is called on a stream before any I/O has occurred on that stream, the
stream becomes unbuffered
. Otherwise the results are
implementation-defined
. “Unbuffered” means that
pbase()
and
pptr()
always return null
and output to the file should appear as soon as possible
.pos_type seekoff(off_type off, ios_base::seekdir way,
ios_base::openmode which
= ios_base::in | ios_base::out) override;
Effects:
Let
width
denote
a_codecvt.encoding(). If
is_open() == false,
or
off != 0 && width <= 0,
then the positioning operation fails
. Otherwise, if
way != basic_ios::cur
or
off != 0,
and if the last operation was output,
then update the output sequence and write any unshift sequence
. Next, seek to the new position: if
width > 0,
call
fseek(file, width * off, whence),
otherwise call
fseek(file, 0, whence).Remarks:
“The last operation was output” means either
the last virtual operation was overflow or
the put buffer is non-empty
. “Write any unshift sequence” means,
if
width
if less than zero then call
a_codecvt.unshift(state, xbuf, xbuf+XSIZE, xbuf_end)
and output the resulting unshift sequence
. The function determines one of three values for the
argument
whence, of type
int,
as indicated in Table
113.Table
113 —
seekoff effects
way Value | stdio Equivalent |
basic_ios::beg | SEEK_SET |
basic_ios::cur | SEEK_CUR |
basic_ios::end | SEEK_END |
Returns:
A newly constructed
pos_type
object that stores the resultant
stream position, if possible
. If the positioning operation fails, or
if the object cannot represent the resultant stream position,
returns
pos_type(off_type(-1)).pos_type seekpos(pos_type sp,
ios_base::openmode which
= ios_base::in | ios_base::out) override;
Alters the file position, if possible, to correspond to the position
stored in
sp (as described below)
. Altering the file position performs as follows:
- 1.
if
(om & ios_base::out) != 0,
then update the output sequence and
write any unshift sequence;
- 2.
set the file position to sp as if by a call to fsetpos;
- 3.
if
(om & ios_base::in) != 0,
then update the input sequence;
where
om is the open mode passed to the last call to
open(). The operation fails if
is_open()
returns
false.If
sp is an invalid stream position, or if the function positions
neither sequence, the positioning operation fails
. If
sp has not been obtained by a previous successful call to one of
the positioning functions
(
seekoff
or
seekpos)
on the same file the effects are undefined
. Otherwise returns
pos_type(off_type(-1)). int sync() override;
Effects:
If a put area exists, calls
filebuf::overflow
to write the characters to the file,
then flushes the file as if by calling
fflush(file). If a get area exists, the effect is
implementation-defined
.void imbue(const locale& loc) override;
Requires:
If the file is not positioned at its beginning and the encoding of the current
locale as determined by
a_codecvt.encoding()
is state-dependent (
[locale.codecvt.virtuals])
then that facet is the same as
the corresponding facet of
loc. Effects:
Causes characters inserted or extracted after this call
to be converted according to
loc until another call of
imbue. Remarks:
This may require reconversion of previously converted characters
. This in turn may require the implementation to be able to reconstruct
the original contents of the file
.