【问题标题】:iterating through memory to reading values遍历内存以读取值
【发布时间】:2012-01-22 19:51:17
【问题描述】:

我有将文本文件读入内存的当前代码:

std::streampos fsize = 0;
std::ifstream file(fileName, std::ios::binary); // open file

if(!file.good()) {
    std::cout << "Error opening file";
    return 0;
}

// get length of file
file.seekg(0, ios::end);
fsize = file.tellg();

// allocate memory
char *memory = new char[fsize];

// read data as a block
file.seekg (0, ios::beg);
file.read (memory, fsize);

file.close(); // close file

return fsize;

现在我有了迭代它的代码。如果该行以 'v' 开头,则它读取前面的 3 个浮点值,如果它以 'n' 开头,则读取相同的值,但进入不同的数组。

char* p = memory;       // pointer to start of memory
char* e = memory + fsize;   // pointer to end of memory

while (p != e) {
    if (memcmp(p, "v", 1) == 0) { 
        sscanf(p, "v %f %f %f", &a[vI], &b[vI], &c[vI]);
        vI++;
    } else if (memcmp(p, "n",  1) == 0) {
        sscanf(p, "v %f %f %f", &d[nI], &e[nI], &f[nI]);
        nI++;           
    while (*p++ != (char) 0x0A);
}

我知道必须有更好/更安全的方法来做到这一点。

【问题讨论】:

  • 您以二进制模式打开文件,但它似乎是一个文本文件。这是故意的吗?
  • 嗯,std::ios::in 会更合适吗?
  • 如果你有一个文本文件,你不需要指定任何东西,默认就可以了。

标签: c++ memory input io


【解决方案1】:

我假设您在那里有一个文本文件。这可以简单得多。首先,不要以二进制模式打开文件,而只是逐行读取。下面是一个可能的实现:

template<class output_iterator>
void read_file(std::istream &input, output_iterator v1, output_iterator v2,
               output_iterator v1) {
    std::string line_buffer;

    while(std::getline(input, line_buffer)) { // read each line of text
        if(line_buffer[0] == 'v') {
            std::stringstream line_stream(line_buffer.substr(1)); // drop the 'v'
            // read three consecutive floats
            line_stream >> *v1++ >> *v2++ >> *v3++; 
        }
    }
}

此代码假定以'v' 开头的行格式正确。你可以这样使用它:

std::vector<float> values1, values2, values3;
std::fstream input_file(fileName);

read_file(input_file, std::back_inserter(values1), std::back_inserter(values2),
          std::back_inserter(values3));

【讨论】:

    【解决方案2】:

    如果您的系统支持mmap(即任何类似 *nix 的系统),请使用它。这将(很快)为您提供文件内容的char*。如果您的文件很大,这非常有用,因为它使用虚拟内存系统为您缓存所有内容 - 即您不必等待所有数据都被复制。 mmap 函数立即返回,并且虚拟内存的相关部分已经映射到您的文件。

    int fd = open(binaryRAWFileName, O_RDONLY);
    ... should do some error check to ensure fd != -1
    
    // get the size of the file
    struct stat sb;
    if (fstat(fd, &sb) == -1) {
            ... there was an error with fstat
    }
    
    char * memory = mmap(NULL  // we don't care where the memory is
            , sb.st_size      // length of the file
            , PROT_READ   
            , MAP_PRIVATE
            , fd            // the file descriptor of course
            , 0);
    

    最后,memcmp 的长度为 1 似乎有点无意义。为什么不直接使用 if(*p=='v') 而不是 if(memcmp(p, "v", 1) == 0)

    【讨论】:

      猜你喜欢
      • 2015-03-22
      • 2012-01-18
      • 1970-01-01
      • 2013-11-09
      • 2018-11-29
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多