【问题标题】:How do you read n bytes from a file and put them into a vector<uint8_t> using iterators?如何从文件中读取 n 个字节并使用迭代器将它们放入 vector<uint8_t> 中?
【发布时间】:2018-11-02 15:32:36
【问题描述】:

基于这个问题:

How to read a binary file into a vector of unsigned chars

他们的答案是:

std::vector<BYTE> readFile(const char* filename)
{
    // open the file:
    std::basic_ifstream<BYTE> file(filename, std::ios::binary);

    // read the data:
    return std::vector<BYTE>((std::istreambuf_iterator<BYTE>(file)),
                              std::istreambuf_iterator<BYTE>());
}

将整个文件读入向量中。

我想要做的是一次读取(例如)向量中的 100 个字节,然后做一些事情,然后将接下来的 100 个字节读入向量中(清除中间的向量)。我看不到如何指定要读取多少文件(即如何设置迭代器)。这可能吗?

我试图避免编写自己的代码循环来一次复制每个字节。

【问题讨论】:

  • 即使你想处理 100 字节的块,你也应该一次读取整个文件(除非它是一些 Gbs 大小)
  • @user463035818 嗯......文件长度可以是任何东西,所以为了保存在 ram 上,我想把它分成 10k 块。我怀疑它会是 Gb,但它可能是大量的 Mbs.... 这也需要缩小到内存有限的平台上,所以我只是想保持谨慎 :)
  • 嗯。好的,需要考虑低内存,但通常我会尝试限制对文件的读取/写入次数,而不是每个单独的读取/写入量
  • @user463035818 我明白你的意思,非常有效:) ...对于我系统的另一部分,我只是阅读小文本文件,我会按照你的建议去做(让生活更轻松!)
  • @user463035818:我不同意。 C++ 标准库足够聪明,可以在内部使用缓冲区来限制物理 io 操作的数量。所以你永远不应该做显式缓冲,除非你正在编写一个库模块,因为优化原因需要一个特定的缓冲。对于任何其他用例,只需依赖标准库。

标签: c++ vector readfile ifstream


【解决方案1】:

您可以为此使用ifstream::read

std::vector<BYTE> v(100);
while ( file.read(reinterpret_cast<char*>(v.data()), 100) )
{
   // Find out how many characters were actually read.
   auto count = file.gcount();

   // Use v up to count BTYEs.
}

【讨论】:

    【解决方案2】:

    你可以写一个函数来:

    void readFile( const std::string &fileName, size_t chunk, std::function<void(const std::vector<BYTE>&)> proc )
    {
        std::ifstream f( fileName );
        std::vector<BYTE> v(chunk);
        while( f.read( v.data(), v.size() ) ) {
            v.resize( f.gcount() );
            proc( v );
            v.resize( chunk );
        }
    }
    

    那么用法很简单:

    void process( const std::vector<BYTE> &v ) { ... }
    
    readFile( "foobar", 100, process ); // call process for every 100 bytes of data
    

    或者您可以使用 lambda 等进行回调。

    【讨论】:

    • 谢谢 - 这是我需要为循环编写的最少代码的一个很好的例子:)
    【解决方案3】:

    或者您可以为此编写自己的函数:

    template<typename Data>
    std::istreambuf_iterator<Data> readChunk(std::istreambuf_iterator<Data>& curr, std::vector<Data>& vec, size_t chunk = 100) {
        for (int i = 0; curr != std::istreambuf_iterator<Data>() && i < chunk; ++i, ++curr) {
            vec.emplace_back(*curr);
        }
        return curr;
    }
    

    并将其用作:

    std::ifstream file("test.cpp");
    std::vector<BYTE> v;
    std::istreambuf_iterator<BYTE> curr(file);
    readChunk<BYTE>(curr, v);
    

    你可以再次调用这个函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 2020-06-12
      相关资源
      最近更新 更多