简体   繁体   English

格式化为循环缓冲区并刷新到文件的正确方法是什么

[英]What is the right way to format to a circular buffer and flush to a file

I made a file class that has its own fixed length internal buffer as a drop-in replacement for the CRT file.我制作了一个文件 class,它有自己固定长度的内部缓冲区作为 CRT 文件的替代品。 I want to add a format method to the file class which will use fmt to format to the internal buffer.我想向文件 class 添加格式化方法,它将使用 fmt 格式化为内部缓冲区。 When the buffer is full, it needs to flush it to the file and continue formatting from the beginning of the buffer.当缓冲区已满时,需要将其刷新到文件中,并从缓冲区的开头继续格式化。 The goal is an improvement in performance by reducing allocations, copying, and branches ( push_back ) but still being just as easy to use as a call to fmt::format .目标是通过减少分配、复制和分支 ( push_back ) 来提高性能,但仍然像调用fmt::format一样易于使用。

I was able to do this in a hacky way as a proof of idea by modifying the grow method and capacity value in iterator_buffer :通过修改iterator_buffer中的grow方法和capacity值,我能够以一种 hacky 的方式作为想法的证明来做到这一点:

Modifications:修改:

template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
 protected:
     FMT_CONSTEXPR20 void grow(size_t) override
     {
        std::cout << "FLUSH: " << std::string_view{&*this->begin(), &*this->end()} << '\n';
        buffer<T>::set(&*this->begin(), 32); buffer<T>::clear();
     }

 public:
  explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, 32) {}

  auto out() -> T* { return &*this->end(); }
};

Main code:主要代码:

std::array<char, 32> buffer; // the actual buffer is much larger

auto out = fmt::format_to(buffer.data(), "example format string 0x{:016X}. {} {} {} {} ", 0x99, "this could have some", "somewhat", "very long", "data in reality");

std::cout << "CLOSE: " << std::string_view{ buffer.data(), out } << '\n';

Output: Output:

FLUSH: example format string 0x00000000
FLUSH: 00000099. this could have some
FLUSH: somewhat very long
CLOSE: data in reality

What is the right way to do this?这样做的正确方法是什么?

You can use std::ofstream 's buffer mechanism directly, it also provide a way to let you specify the buffer you want .你可以直接使用std::ofstream的缓冲机制,它也提供了一种方法让你指定你想要的缓冲区

void foo(){
    std::array<char, 32> buffer;
    std::ofstream file;
    file.rdbuf()->pubsetbuf(buffer.data(), buffer.size()); // set the buffer
    file.open("file.txt");
    
    std::format_to(
        std::ostreambuf_iterator(file), // use the buffer as iterator
        "example format string 0x{:016X}. {} {} {} {} ", 
        0x99, 
        "this could have some", "somewhat", 
        "very long", "data in reality"
    );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM