Запись и чтение в файл с использованием fstream

229
04 января 2019, 03:40

Нужно периодически писать в файл данные, и из другого потока считывать и обрабатывать.

Примерно так:

void write(std::fstream& fstr, char* bytes, std::size_t size)
{
    fstr.write(bytes, size);
    fstr.flush();
    if (fstr.fail())
    {
        std::cerr << "error" << std::endl;
        throw 1;
    }
    std::streampos p = fstr.tellp();
    std::streampos g = fstr.tellg();
    if (p == g)
        std::cout << "p == g" << std::endl;
}
void read(std::fstream& fstr, char* bytes, std::size_t size)
{
    fstr.read(bytes, size);
    if (fstr.fail())
    {
        std::cerr << "error" << std::endl;
        throw 1;
    }
    std::cout << "has been read " << fstr.gcount() << std::endl;
    std::streampos p = fstr.tellp();
    std::streampos g = fstr.tellg();
    if (p == g)
        std::cout << "p == g" << std::endl;
}
void seekp(std::fstream& fstr, int pos)
{
    fstr.seekp(pos);
    std::streampos p = fstr.tellp();
    std::streampos g = fstr.tellg();
    if (p == g)
        std::cout << "p == g" << std::endl;
}
void seekg(std::fstream& fstr, int pos)
{
    fstr.seekg(pos);
    std::streampos p = fstr.tellp();
    std::streampos g = fstr.tellg();
    if (p == g)
        std::cout << "p == g" << std::endl;
}
int main()
{
    std::fstream fstr;
    fstr.open("./file", std::ios::in | std::ios::out | std::ios::binary);
    {
        char bytes[] = { 0x01, 0x02, 0x03 };
        write(fstr, bytes, 3);
    }
    seekp(fstr, 0);
    {
        char bytes[16];
        read(fstr, bytes, 16);
    }
    seekg(fstr, fstr.end);
    {
        char bytes[] = { 0x04, 0x05, 0x06 };
        write(fstr, bytes, 3);
    }
    seekp(fstr, 0);
    {
        char bytes[16];
        read(fstr, bytes, 16);
    }
    fstr.close();
};

1) Не получается считать байты fstr.fail() возвращает true. В чем может быть причина, и есть ли какая либо функция возвращающая код ошибки

2) Почему после записи, чтения, вызова seekp(), seekg(), fstr.tellp() == fstr.tellg()? В чем смысл тогда разделения указателя на указатель чтения и указатель записи?

Answer 1
  1. При чтении данных в файле они иногда заканчиваются. Устанавливаются флаги ошибки failbit и eofbit. Узнать сколько же вы прочитали вы уже знаете : с помощью gcount(). После того, как дошли до конца файла нужно вручную обнулить флаги ошибок. Можно так :

fstr.clear(fstr.rdstate() bitand ~(fstr.failbit bitor fstr.eofbit));

Кода ошибок нет, но есть конкретные вопросы по ошибкам : .good() , .bad() , .fail() , .eof().

  1. Позиции чтения и записи разные, потому-что класс iostream слили из двух : istream и ostream. Очень проблематично было найти место под одну переменную для этого, так как потоки бывают очень разные. А при попытке чтения шестнадцати байтов у вас как раз и произошло изменение позиции чтения на -1. А позиция записи осталась та же.
READ ALSO
В чем ошибается мой алгоритм (частотный анализ)?

В чем ошибается мой алгоритм (частотный анализ)?

Сразу говорю, что мой алгоритм не претендует на лучшее решение, я просто не могу понять, почему он правильно узнает только пробел (в 100% случаев),...

209
Добавление в ArrayList Color

Добавление в ArrayList Color

Немного изменила

178
Игра в угадывание(Head First Java)

Игра в угадывание(Head First Java)

Новичок начал изучать Head First Java столкнулся с проблемой что код используемый в этой книге устарел, помогите довести задачу до рабочего состояния)

192
В чем отличие notify, notifyall?

В чем отличие notify, notifyall?

Я знаю, что notify() - пробуждает любой один поток, а notifyAll() - пробуждает все и даёт доступ одномуНо в чём отличие? в одних случаях работает notify(),...

253