【问题标题】:Reading a file in chunks and appending the incomplete line to the next read分块读取文件并将不完整的行附加到下一次读取
【发布时间】:2016-03-26 13:26:09
【问题描述】:

我正在尝试从以下文件中读取:

abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
12345abcdefghijklmnopqrstu
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz

代码如下:

#include <iostream>
#include <fstream>
#include <sstream>
#include <thread>
#include <mutex>
#include <vector>
#include <array>
#include <algorithm>
#include <iterator>

#define CHUNK_SIZE 55

std::mutex queueDumpMutex;

void getLinesFromChunk(std::vector<char>& chunk, std::vector<std::string>& container)
{
    static std::string str;
    unsigned int i = 0;
    while(i < chunk.size())
    {   
        str.clear();
        size_t chunk_sz = chunk.size();

        while(chunk[i] != '\n' && i < chunk_sz )
        {
            str.push_back(chunk[i++]);
        }
        std::cout<<"\nStr = "<<str;

        if (i < chunk_sz)
        {
            std::lock_guard<std::mutex> lock(queueDumpMutex);
            container.push_back(str);
        }
        ++i;
    }
    chunk.clear();
    std::copy(str.begin(), str.end(), std::back_inserter(chunk));
    std::cout << "\nPrinting the chunk out ....." << std::endl;
    std::copy(chunk.begin(), chunk.end(), std::ostream_iterator<char>(std::cout, " "));
}

void ReadFileAndPopulateDump(std::ifstream& in)
{
    std::vector<char> chunk;
    chunk.reserve(CHUNK_SIZE*2);
    std::vector<std::string> queueDump; 
    in.unsetf(std::ios::skipws);
    std::cout << "Chunk capacity: " << chunk.capacity() << std::endl;

    do{
        in.read(&chunk[chunk.size()], CHUNK_SIZE);
        std::cout << "Chunk size before getLines: " << chunk.size() << std::endl;
        getLinesFromChunk(chunk, queueDump);
        std::cout << "Chunk size after getLines: " << chunk.size() << std::endl;
    }while(!in.eof());
}

int main()
{
    std::ifstream in("/home/ankit/codes/more_practice/sample.txt", std::ifstream::binary);
    ReadFileAndPopulateDump(in);
    return 0;
}

我希望实现的是容器是完整的。

我的意思是假设我的 CHUNK_SIZE 只读:

abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
12

容器应如下所示:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

代替:

abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz12

现在我知道 chunk.reserve(CHUNK_SIZE) 保留给定的内存并且实际上并没有分配 SIZE。因为如果我无法从 in.read() 中读取。

如果我使用 chunk.resize(CHUNK_SIZE) 并将其附加到末尾,因为我希望将剩余的字符 '12' 附加到完整的行中。

现在的问题是代码的重复次数超出了应有的程度。在我看来,条件似乎很好。

任何帮助将不胜感激。

【问题讨论】:

    标签: parsing c++11 vector ifstream


    【解决方案1】:

    对不起,我不明白你为什么这样做:

    • 以二进制模式而非文本模式读取文件
    • 不要使用getline()
    • 使用vector&lt;char&gt; 而不是string

    对于我理解你提出的问题,我会这样做

    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    
    int main()
     {
       std::ifstream  f("sample.txt");  // text mode!
    
       std::size_t const  chunkSizeMax = 55U;
    
       std::string  str;
       std::string  chunk;
    
       while ( std::getline(f, str) )
        {
          if ( chunkSizeMax <= (chunk.size() + str.size()) )
           {
             std::cout << "chunk: [" << chunk << "]\n";
    
             chunk.clear();
           }
    
          chunk += str;
        }
    
       std::cout << "last chunk: [" << chunk << "]\n";
    
       return EXIT_SUCCESS;
     }
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-08-26
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多