你要找的是班级成员。它不是全局的,每个对象实例都有自己的副本。
因为它也不是函数本地的,所以它会在同一个对象上的成员函数调用中保持不变。
我认为您不需要标志,因为您可以询问流是否已经打开:
if (!m_outfile.is_open())
m_outfile.open(filename, std::ios::binary);
由于您希望出现错误异常,请考虑在文件流上启用它们:
m_outfile.exceptions(std::ios::failbit | std::ios::badbit);
考虑使用val 的实际大小,而不是复制假定的类型(int)。
for (auto val : number_container) {
m_outfile.write(reinterpret_cast<const char*>(&val),
sizeof(val));
}
(旁白:如果number_container 是连续的,您可以更有效地将其写为:
auto span = as_bytes(std::span(number_container));
m_outfile.write(reinterpret_cast<char const*>(span.data()), span.size());
/aside)
这是一个现场演示On Coliru
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <fstream>
#include <iostream>
#include <span>
using namespace std::chrono_literals;
static constexpr auto DUMP_INTERVAL = 1s;
struct Data_dump {
Data_dump() { //
m_outfile.exceptions(std::ios::failbit | std::ios::badbit);
}
void foo() {
try {
if (!m_outfile.is_open())
m_outfile.open(m_filename, std::ios::binary);
//for (auto val : number_container) {
//m_outfile.write(reinterpret_cast<const char*>(&val),
//sizeof(val));
//}
auto span = as_bytes(std::span(number_container));
m_outfile.write(reinterpret_cast<char const*>(span.data()), span.size());
m_outfile.flush();
m_timer.expires_at(m_timer.expiry() + DUMP_INTERVAL);
m_timer.async_wait(boost::bind(&Data_dump::dump, this, boost::placeholders::_1));
std::cerr << "Expiry: " << (m_timer.expiry() - std::chrono::steady_clock::now())/1ms << "ms
";
} catch (std::exception const& e) {
throw std::runtime_error("Error in writing to " + m_filename);
}
}
void run() {
ioc.run_for(10s); // for COLIRU
}
private:
void dump(boost::system::error_code ec) {
// don't use rand in production code!
std::cerr << "Dump (" << ec.message() << ")" << std::endl;
generate(begin(number_container), end(number_container), std::rand);
foo();
}
std::string const m_filename = "numbers.bin";
boost::asio::io_context ioc;
boost::asio::steady_timer m_timer{ioc, 1s};
std::ofstream m_outfile;
std::vector<int> number_container{1, 2, 3};
};
int main() {
boost::asio::io_context ioc;
Data_dump dd;
dd.foo();
dd.run();
}
显示时间:
奖金
在您的情况下,看起来您实际上可能不需要异步 IO(您没有在显示的代码中使用它),所以也许只是这样写:
void foo(std::string const& filename) {
std::ofstream ofs;
ofs.exceptions(std::ios::failbit | std::ios::badbit);
ofs.open(filename, std::ios::binary);
auto start = std::chrono::steady_clock::now();
for (auto now = start; now <= start + 10s; now += DUMP_INTERVAL) {
/*
*for (auto val : data)
* ofs.write(reinterpret_cast<const char*>(&val), sizeof(val));
*/
auto span = as_bytes(std::span(data));
ofs.write(reinterpret_cast<char const*>(span.data()), span.size());
ofs.flush();
std::this_thread::sleep_until(now + 1s);
}
}
现在,也许添加一个线程来更新数字容器(确保添加同步,例如使用锁或原子交换等)