mmap从文件中读取过时的整数数组

时间:2013-06-14 09:08:35

标签: c++ linux mmap

我正在尝试使用mmap从文件中读取整数矩阵。如果我从mmap函数接收它作为char指针,我看到一切正确,但如果我使用int指针,它会给我陈旧的数据。 使用char指针的问题是我需要使用strtok或其他东西解析整个字符串并逐个获取整数。我的矩阵大小将是4k * 4k因此调用sscanf和strtok效率不高。请查看程序和输出

#define INTS 3 * 3

int main()
{

    FILE* in = fopen("int_file", "rb");
    int* ints = (int*)mmap(0, INTS * sizeof(int),
                      PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
    fclose(in);
    for(int i = 0; i < INTS; ++i) { 
        std::cout << ints[i] << std::endl;
    }
    munmap(ints, INTS * sizeof(int));
    return 0;
}

int_file的内容是

510 20 30 40 50 60 100 200 10000

输出

540029237 857747506 808716848 540030240 822751286 84097028

2 个答案:

答案 0 :(得分:2)

正在打印文本的ACSII值。

您的文字似乎是:

510 20 30...

从ASCII表(解释我想说的):

No.       ASCII (hex)

Space ->   20
0     ->   30
1     ->   31
2     ->   32
3     ->   33
5     ->   35

int的大小为4个字节,因此,首先占用4个字节:

转换为ASCII,"510 "在内存中为"35 31 30 20"提供0x20303135540029237为十进制),用于小端机器。 同样,下一个4字节"20 3"会将0x33203032857747506作为十进制数)。 这就是你得到的。

在这种情况下,您需要使用atoi()或类似的方法将每个ACSII转换为整数。

但是您可以将整数存储为二进制值本身,而不是将其保存为ASCII。该文件不是人类可读的,但它可以达到您的目的。

答案 1 :(得分:0)

如果文件中的数据是通过calloc从int数组或连续内存中存储的,则可以将其作为int *读取。 作家应该看起来像,

#include <iostream>
#include <sys/mman.h>
#include <stdio.h>

using namespace std;

int inst[] = {510, 20, 30, 40, 50, 60, 100, 200, 10000 };

#define INTS 3 * 3

int main()
{
        FILE* out = fopen("int_file", "wb");  // Error checks are needed
        char *ptr = (char *) inst;
        fwrite( ptr, sizeof( int ), INTS, out );
        fclose( out);
        return 0;
}

然后读者可以使用mmap阅读,就像在您的代码中一样,

#include <iostream>
#include <sys/mman.h>
#include <stdio.h>

using namespace std;

#define INTS 3 * 3

int main()
{

    FILE* in = fopen("int_file", "rb");    // Error checks are needed
    int* ints = (int*)mmap(0, INTS * sizeof(int),
                    PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
    fclose(in);
    for(int i = 0; i < INTS; ++i) {
            std::cout << ints[i] << std::endl;
    }
    munmap(ints, INTS * sizeof(int));
    return 0;
}

如果没有从数组或连续内存中存储,那么使用char *strtok以及atoi是最佳解决方案..