如何使用mmap映射空文件 [英] How to map an empty file using mmap

查看:636
本文介绍了如何使用mmap映射空文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个不存在的空文件.而不是使用mmap()映射它,这样我就可以将其传递给其他程序进行编写.我不确定mmap的哪些参数适用于空文件.我的代码适用于非空文件,但如果文件为空,则会给出错误无效参数"

I am trying to create an empty file if it does not exists. And than map it using mmap() so, that i can pass it to my other program for writing. I am not sure which arguments for mmap are suitable for an empty file. My code works for non empty files but gives error "Invalid argument" if file is empty

代码program1(仅在不存在的情况下创建一个空文件)

Code program1 (only creates an empty file if not exists)

int i;
int fd = open("/home/sungmin/dummy_programs/dummy.txt", O_RDONLY | O_CREAT, 0777);
char *pmap;
pid_t child;

if (fd == -1)
{
    perror("Error opening file for writing");
    exit(EXIT_FAILURE);
}        

struct stat fileInfo = {0};

if (fstat(fd, &fileInfo) == -1)
{
    perror("Error getting the file size");
    exit(EXIT_FAILURE);
}

/*if (fileInfo.st_size == 0)
{
    fprintf(stderr, "Error: File is empty, nothing to do\n");
    exit(EXIT_FAILURE);
}*/

pmap = mmap(0, fileInfo.st_size, PROT_READ | PROT_EXEC  , MAP_ANONYMOUS, fd, 0);
if (pmap == MAP_FAILED)
{
    close(fd);
    perror("Error mmapping the file");
    exit(EXIT_FAILURE);
}

/* Calling fork function */
if((child=fork())==0){

printf("Iam Child process\n\n");
static char *argv[]={"This is some sample text. I need to write this text in my dummy file.","/home/sungmin/dummy_programs/dummy.txt",NULL};
execv("/home/sungmin/dummy_programs/pro2",argv);
    exit(127); 
}
else { 
    printf("Iam parent, waiting for child process to exit\n\n");        
    waitpid(child,0,0); 
    printf("Existing parent\n\n");
}

/* Don't forget to free the mmapped memory*/
if (munmap(pmap, fileInfo.st_size) == -1)
{
    close(fd);
    perror("Error un-mmapping the file");
    exit(EXIT_FAILURE);
}

/* Un-mmaping doesn't close the file, so we still need to do that.*/
close(fd);

代码program2(打开与program1相同的文件,并写入由program1传递的文本)

Code program2 (opens same file as program1 and writes text passed by program1)

 size_t i;
int fd;
char *pmap;
pid_t child;
struct stat fileInfo = {0};
const char *text = argv[0];

fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);

if (fd == -1)
{
    perror("Error opening file for writing");
    exit(EXIT_FAILURE);
}  

size_t textsize = strlen(text) + 1; // + \0 null character

if (lseek(fd, textsize-1, SEEK_SET) == -1)
{
    close(fd);
    perror("Error calling lseek() to 'stretch' the file");
    exit(EXIT_FAILURE);
}

if (write(fd, "", 1) == -1)
{
    close(fd);
    perror("Error writing last byte of the file");
    exit(EXIT_FAILURE);
}

pmap = mmap(0, textsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (pmap == MAP_FAILED)
{
    close(fd);
    perror("Error mmapping the file");
    exit(EXIT_FAILURE);
}

/* Writting users text to file */
for (i = 0; i < textsize; i++)
{
    pmap[i] = text[i];  
}   

// Write it now to disk
if (msync(pmap, textsize, MS_SYNC) == -1)
{
    perror("Could not sync the file to disk");
}

/* Don't forget to free the mmapped memory*/
if (munmap(pmap, textsize) == -1)
{
    close(fd);
    perror("Error un-mmapping the file");
    exit(EXIT_FAILURE);
}

/* Un-mmaping doesn't close the file, so we still need to do that.*/
close(fd);  

推荐答案

在创建文件之前,需要先使用truncate来扩展文件长度,然后再进行映射.

You need to use truncate to extend the file length after creating it before mapping it.

是的,函数名称听起来不对,但是truncate实际上可以将文件长度设置为任何数字.确保使用4K的倍数以获得最佳效果.

Yes, the function name sounds wrong, but truncate can actually set the file length to any number. Be sure to use a multiple of 4K for best results.

然后,如果要保持映射打开状态以查看程序1和2之间的数据,则需要摆脱ANONYMOUS并在程序1中使用MAP_SHARED进行映射.未共享的映射将不会显示由进行的更改其他程序.或者,如果必须从磁盘重新加载,则可能会.很奇怪,不要混合使用SHARED和NOT-SHARED映射.

Then, if you want to keep the mapping open to see data between Program 1 and 2, you need to get rid of ANONYMOUS and map with MAP_SHARED in Program 1. A mapping that isn't shared will not show changes made by other programs. Or it might, if it has to reload from disk. It's weird, don't mix SHARED and not-SHARED mappings.

将程序1更改为使用truncate后,将lseekwrite代码从程序2中删除.文件将已经由程序1创建并扩展.

Once you've changed Program 1 to use truncate, take that lseek and write code out of Program 2. The file will already have been created and extended by Program 1.

这篇关于如何使用mmap映射空文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆