用mmap()读取二进制文件

时间:2016-03-24 10:37:40

标签: mmap

你能解释为什么我的程序从文件中读取奇怪的值吗?我正在尝试使用mmap读取文件。我使用此功能的原因是了解它的工作原理。然后我将它与/ dev / mem一起使用,以便读取特定物理内存地址的二进制数据。

我使用以下python脚本创建了一个'hello1.raw'文件。

fd = open("hello1.raw", "w+b")
fd.write(b'01')

fd.close()

然后我尝试使用下面的c程序阅读它。

#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(){

int fd = open("hello1.raw",O_RDWR);

struct stat st;
fstat(fd, &st);
size_t size=st.st_size;

int * a = mmap(0, size, PROT_READ|PROT_EXEC ,MAP_SHARED , fd, 0);
printf("address of hello1.raw: %p\n",a); 
printf("data in hello1.raw: %d\n", *a);

int b = munmap(a, size);
close(fd);

return 0;
}

但是这个程序打印出奇怪的价值。

address of hello.raw: 0x10238d000
data in hello.raw: 12592

数据不是01但是12592.

1 个答案:

答案 0 :(得分:2)

#include <stdio.h>
#include <sys/stat.h>

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(){

int fd, rc , ii;
int *ptr;
struct stat st;
size_t size;

fd = open("hello1.raw", O_RDWR);

rc = fstat(fd, &st);
fprintf(stderr, "stat() = %d\n", rc);
size=st.st_size;
fprintf(stderr, "size=%zu\n", size);

ptr = mmap(0, size, PROT_READ|PROT_EXEC ,MAP_SHARED , fd, 0);
fprintf(stderr, "address of hello1.raw: %p\n", ptr);

for (ii=0; ii < size/sizeof *ptr; ii++) {
   printf("data in raw[%d]: %d\n", ii, ptr[ii]);
        }

rc = munmap(ptr, size);
fprintf(stderr, "unmap() = %d\n", rc);
close(fd);

return 0;
}
  • 首先:检查系统调用的返回值并向stderr报告。
  • 第二:mmap()适用于页面。如果st.st_size不是页面大小的倍数,则将其向上舍入。 (Linux用零填充其余部分)
  • 通过将“OMG \ n”放入hello1.raw文件(4个字节)并运行程序来测试。
  • 现在删除一个字符)例如 - &gt;&gt; “OM \ n”)结束重播程序。

结果1:

$ ./a.out
stat() = 0
size=4
address of hello1.raw: 0xa64000
data in raw[0]: 172445007
unmap() = 0

结果2:

$ ./a.out
stat() = 0
size=3
address of hello1.raw: 0xe37000
unmap() = 0

说明:在第一次运行时,文件的大小= 4,mmap成功,并打印int。 (sizeof int是4)。 在第二种情况下,mmap成功,但是没有打印int(我的循环版本拒绝引用超出eof的mmapped内存),如果你允许超过eof的引用高于大写字节(假设Big endian)这里的int值将显示为零,因为系统填充页面为零。

如果要查看nul-padding的效果,请将for循环更改为for (ii=0; ii <= size/sizeof *ptr; ii++) {并重复上述实验。