30 Input/output library [input.output]

30.9 File-based streams [file.streams]

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;

    // [filebuf.cons], constructors/destructor
    basic_filebuf();
    basic_filebuf(const basic_filebuf& rhs) = delete;
    basic_filebuf(basic_filebuf&& rhs);
    virtual ~basic_filebuf();

    // [filebuf.assign], assign and swap
    basic_filebuf& operator=(const basic_filebuf& rhs) = delete;
    basic_filebuf& operator=(basic_filebuf&& rhs);
    void swap(basic_filebuf& rhs);

    // [filebuf.members], members
    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);  // wide systems only; see [fstream.syn]
    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:
    // [filebuf.virtuals], overridden virtual functions
    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);
}

Класс basic_­filebuf<charT, traits> связывает как входную, так и выходную последовательность с файлом.

Ограничения на чтение и запись последовательности , управляемый объект класса basic_­filebuf<charT, traits> такие же , как для чтения и записи с помощью стандартной библиотеки C FILEс.

Особенно:

  • Если файл не открыт для чтения, входная последовательность не может быть прочитана.

  • Если файл не открыт для записи, выходная последовательность не может быть записана.

  • Позиция в совместном файле сохраняется как для входной, так и для выходной последовательности.

Экземпляр basic_­filebuf ведет себя , как описано в[filebuf] предусмотренных traits​::​pos_­type IS fpos<traits​::​​state_­type>. В противном случае поведение не определено.

Для поддержки файлового ввода-вывода и преобразования многобайтовых / широких символов преобразования выполняются с использованием элементов фасета, упомянутых a_­codecvt в следующих разделах, полученных, как если бы

const codecvt<charT, char, typename traits::state_type>& a_codecvt =
  use_facet<codecvt<charT, char, typename traits::state_type>>(getloc());

30.9.2.1 basic_­filebuf constructors [filebuf.cons]

basic_filebuf();

Effects: Создает объект класса basic_­filebuf<charT, traits>, инициализируя базовый класс с помощью basic_­streambuf<charT, traits>() ([streambuf.cons]).

Postconditions: is_­open() == false.

basic_filebuf(basic_filebuf&& rhs);

Effects: Переместите конструкции из rvaluerhs. Это определяется реализация ли указатели последовательности в*this (eback(),gptr(),egptr(), pbase(),pptr(),epptr()) получить значение , которыеrhs имели. Независимо от того, работают они или нет,*this иrhs ссылаются на отдельные буферы (если они вообще есть) после построения. Дополнительно*this ссылается на файл, которыйrhs был создан до построения, и не rhs ссылается на файл после построения. Также копируются режим openmode, locale и любое другое состояниеrhs .

Postconditions: Позвольтеrhs_­p ссылаться на состояние rhs непосредственно перед этой конструкцией и позвольтеrhs_­a ссылаться на состояниеrhs сразу после этой конструкции.

  • 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: Уничтожает объект класса basic_­filebuf<charT, traits>. Звонки close(). Если во время уничтожения объекта, включая вызовclose(), возникает исключение, исключение перехватывается, но не генерируется повторно (см[res.on.exception.handling]. Раздел "Ресурсы" ).

30.9.2.2 Assign and swap [filebuf.assign]

basic_filebuf& operator=(basic_filebuf&& rhs);

Effects: close() Затем вызовы перемещают назначенных изrhs. После того, как присвоение хода*this приобрело наблюдаемое состояние, оно было бы, если бы оно было построено изrhs (см.[filebuf.cons]).

Returns:*this.

void swap(basic_filebuf& rhs);

Effects: Меняет состояние*this иrhs.

template <class charT, class traits> void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);

Effects: Как будто мимоx.swap(y).

30.9.2.3 Member functions [filebuf.members]

bool is_open() const;

Returns: true если предыдущий вызов open завершился успешно (вернул ненулевое значение) и не было промежуточного вызова для закрытия.

basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path::value_type* s, ios_base::openmode mode); // wide systems only; see [fstream.syn]

Effects: Если is_­open() != false, возвращает нулевой указатель. В противном случае инициализирует при filebuf необходимости. Затем он открывает файл, если это возможно, с именем ntbss (как если бы при вызове fopen(s, modstr)). В НТБ определяется , как указано в табл . Если в таблице не указана комбинация флагов, то открытие не выполняется.modstr mode & ~ios_­base​::​ate117mode

Таблица117 - Режимы открытия файла
ios_­base комбинация флаговstdio эквивалент
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"

Если операция открытия завершается успешно и (mode & ios_­base​::​ate) != 0, помещает файл в конец (как если бы при вызове fseek(file, 0, SEEK_­END)).327

Если операция изменения положения завершается неудачно, вызывает close() и возвращает нулевой указатель, указывающий на сбой.

Returns: this в случае успеха - нулевой указатель.

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: Если is_­open() == false, возвращает нулевой указатель. Если область размещения существует, вызывает overflow(traits​::​​eof()) сброс символов. Если последняя функция виртуального члена призвала *this (между underflow, overflow, seekoffи seekpos) был overflow тогда вызовы a_­codecvt.unshift (возможно , несколько раз) , чтобы определить последовательность терминации, вставляет эти символы и вызовы overflow(traits​::​​eof()) снова. Наконец, независимо от того, завершается ли какой-либо из предыдущих вызовов сбоем или возникает исключение, функция закрывает файл (как если бы путем вызова fclose(file)). Если какой-либо из вызовов, выполненных функцией, в том числеfclose, завершается ошибкой, close завершается ошибкой, возвращая нулевой указатель. Если один из этих вызовов вызывает исключение, исключение перехватывается и генерируется повторно после закрытия файла.

Returns: this в случае успеха - нулевой указатель.

Postconditions: is_­open() == false.

Макрос SEEK_­END определен, а сигнатуры функций fopen(const char*, const char*) и объявлены в .fseek(FILE*, long, int) <cstdio>

30.9.2.4 Overridden virtual functions [filebuf.virtuals]

streamsize showmanyc() override;

Effects: Ведет себя так же, как basic_­streambuf​::​showmanyc() ([streambuf.virtuals]).

Remarks: Реализация могла бы предоставить переопределение для этой сигнатуры функции, если она может определить, что из входной последовательности можно прочитать больше символов.

int_type underflow() override;

Effects: Ведет себя в соответствии с описанием basic_­streambuf<charT, traits>​::​underflow()со специализацией, согласно которой последовательность символов считывается из входной последовательности, как если бы она считывала из связанного файла во внутренний буфер (extern_­buf), а затем как если бы выполнялась:

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);

Это должно быть сделано таким образом, чтобы класс мог восстановить позицию (fpos_­t), соответствующую каждому символу между intern_­buf и intern_­end. Если значение r указывает, что в нем не a_­codecvt.in() хватает места intern_­buf, повторите попытку с большим intern_­buf.

int_type uflow() override;

Effects: Ведет себя в соответствии с описаниемbasic_­streambuf<charT, traits>​::​uflow(), со специализацией, заключающейся в том , что последовательность символов считывается из ввода тем же методом, что и underflow.

int_type pbackfail(int_type c = traits::eof()) override;

Effects: Возвращает символ, обозначенный значком,c во входную последовательность, если это возможно, одним из трех способов:

  • Если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается false и , если функция делает позицию Putback доступную и если traits​::​eq(to_­char_­type(c), gptr()[-1]) возвращается true, вычитает следующий указатель для входной последовательности, gptr().

    Возвращает: c.

  • Если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается, false и если функция делает доступной позицию возврата и если функции разрешено назначать позицию возврата, уменьшает следующий указатель для входной последовательности и сохраняетc его.

    Возвращает: c.

  • Если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается true, и если либо входная последовательность имеет место Putback доступны или функция делает положение Putback доступна, вычитает следующий указатель для входной последовательности, gptr().

    Возвращает: traits​::​not_­eof(c).

Returns: traits​::​eof() для обозначения отказа.

Remarks: Если is_­open() == false, функция всегда терпит неудачу.

Функция не возвращает символ непосредственно во входную последовательность.

Если функция может быть успешной более чем одним из этих способов, не указано, какой путь будет выбран. Функция может изменить количество позиций возврата, доступных в результате любого вызова.

int_type overflow(int_type c = traits::eof()) override;

Effects: Ведет себя в соответствии с описанием basic_­streambuf<charT, traits>​::​overflow(c), за исключением того, что поведение «потребляющих символов» выполняется путем предварительного преобразования, как если бы:

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);

а потом

  • Еслиr == codecvt_­base​::​error тогда не получится.

  • Еслиr == codecvt_­base​::​noconv тогда вывести символы от b до (и не включая)p.

  • Еслиr == codecvt_­base​::​partial затем вывести в файл символы от xbuf доxbuf_­endи повторить, используя символы от end доp. Если вывести не удалось, завершитесь ошибкой (без повторения).

  • В противном случае вывести изxbuf вxbuf_­endи потерпеть неудачу, если вывести не удалось . На этом этапе, еслиb != p иb == end (xbuf недостаточно большое), увеличьтеXSIZE и повторите сначала.

Returns: traits​::​not_­eof(c) для обозначения успеха и traits​::​eof() для обозначения неудачи. Если is_­open() == false, функция всегда терпит неудачу.

basic_streambuf* setbuf(char_type* s, streamsize n) override;

Effects: Если setbuf(0, 0) вызывается в потоке до того, как в этом потоке произошел какой-либо ввод-вывод, поток становится небуферизованным. В противном случае результаты определяются реализацией. «Unbuffered» означает , что pbase() и pptr() всегда возвращают нуль и вывод в файл должен появиться как можно скорее.

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;

Effects: Пусть width обозначают a_­codecvt.encoding(). Если is_­open() == false, или off != 0 && width <= 0, то операция позиционирования не выполняется. В противном случае, если way != basic_­ios​::​cur или off != 0, и если была выведена последняя операция, обновите выходную последовательность и запишите любую несмещенную последовательность. Далее ищем новую позицию: если width > 0звоните fseek(file, width * off, whence), в противном случае звоните fseek(file, 0, whence).

Remarks: «Последняя операция была выведена» означает, что либо последняя виртуальная операция была переполнена, либо буфер размещения не пуст. «Записать любую последовательность без сдвига» означает, что width если меньше нуля, то вызвать a_­codecvt.unshift(state, xbuf, xbuf+XSIZE, xbuf_­end) и вывести результирующую последовательность без сдвига. Функция определяет одно из трех значений аргументаwhenceтипа int, как указано в таблице118.

Таблица118 -seekoff эффекты
way Ценитьstdio Эквивалент
basic_­ios​::​beg SEEK_­SET
basic_­ios​::​cur SEEK_­CUR
basic_­ios​::​end SEEK_­END

Returns: Недавно созданный pos_­type объект, который, если возможно, сохраняет позицию результирующего потока. Если операция позиционирования завершается неудачно или объект не может представлять позицию результирующего потока, возвращается pos_­type(off_­type(-1)).

pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override;

Если возможно, изменяет положение файла, чтобы оно соответствовало положению, сохраненному вsp (как описано ниже). Изменение положения файла происходит следующим образом:

  1. 1.если (om & ios_­base​::​out) != 0, то обновить выходную последовательность и записать любую несмещенную последовательность;

  2. 2.установить позицию файла,sp как если бы при вызовеfsetpos;

  3. 3.если (om & ios_­base​::​in) != 0, то обновить входную последовательность;

гдеom открытый режим передан последнему вызову open(). Приis_­open() возврате операция завершается ошибкой false.

Еслиsp это недопустимая позиция потока или функция не позиционирует ни одну последовательность, операция позиционирования завершается ошибкой. Еслиsp не был получен предыдущим успешным вызовом одной из функций позиционирования (seekoff или seekpos) в том же файле, эффекты не определены.

Returns: sp об успехе. В противном случае возвращается pos_­type(off_­type(-1)).

int sync() override;

Effects: Если область размещения существует, вызывает filebuf​::​overflow запись символов в файл, а затем сбрасывает файл, как если бы путем вызоваfflush(file). Если область получения существует, эффект определяется реализацией.

void imbue(const locale& loc) override;

Requires: Если файл не расположен в начале и кодировка текущей локали, определяемая с помощью, зависит от a_­codecvt.encoding() состояния ([locale.codecvt.virtuals]), то этот фасет совпадает с соответствующим фасетомloc.

Effects: Заставляет символы, вставленные или извлеченные после этого вызова, преобразовыватьсяloc до следующего вызова imbue.

Remarks: Это может потребовать повторного преобразования ранее преобразованных символов. Это, в свою очередь, может потребовать от реализации возможности восстановить исходное содержимое файла.