当我使用mmap和memcpy写一个文件,然后我用fread来读取数据。 以下是我的代码,问题是我第一次阅读 a ,但第二次我无法阅读。 我猜有点像fread函数中的搜索位置,当我使用memcpy写文件时,它可能会改变搜索位置。
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
int main()
{
int fd = open("./aa", O_CREAT | O_RDWR | O_TRUNC, 0644);
FILE* f = fopen("./aa", "r");
if (ftruncate(fd, 1024) < 0) {
printf("ftruncate error\n");
}
void* base;
if ((base = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
printf("mmap error\n");
}
char* file_ptr = (char *)base;
char buffer[256];
char scratch[256];
buffer[0] = 'a';
memcpy(file_ptr, buffer, 1);
file_ptr += 1;
size_t n = fread(scratch, 1, 1, f);
printf("size n %zu\n", n); // this output size n 1
printf("scratch %c\n", scratch[0]); // this output scratch a
memcpy(file_ptr, buffer, 1);
file_ptr += 1;
n = fread(scratch, 1, 1, f);
printf("size n %zu\n", n); // this output size n 1
printf("scratch %c\n", scratch[0]); // but this output scratch
return 0;
}
输出是: 大小n 1 划伤一个 大小n 1 刮
答案 0 :(得分:2)
首先,@ wildplasser是对的,你的程序可能有效,但是如果你继续混合mmap和stdio,你需要确保通过mmap
完成的写入被提交(使用{{1函数)并且fread没有缓冲过时的数据(msync()
到当前位置应该这样做。)
来到你的问题:你的程序没有打印“scratch”,它打印“scratch \ 0”:)
说真的,你要做的是通过fseek()
初始化“aa”文件的大小,这与填充缺失的字节最多为1024'\ 0';你写一个'a',并阅读它;然后你读了另一个角色,你得到了一个NUL。
尝试打印scratch [0]的ascii字符,你会看到它为零;如果您仍然不相信,请尝试添加类似
的内容ftruncate()
在第一个memcpy之前,看看会发生什么。