在C中使用mmap写入内存。

在C中使用mmap写入内存。,c,mmap,C,Mmap,我想使用mmap()创建一个包含一些整数的文件。我想通过写入内存来写入此文件。我知道内存中的数据是二进制格式的,因此文件中的数据也是二进制格式的。 我可以为此使用mmap吗?在哪里可以找到有关如何使用mmap的好资源?我没有找到一本好的手册 以下是一个示例: #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> /* mmap() is defined in this header

我想使用
mmap()
创建一个包含一些整数的文件。我想通过写入内存来写入此文件。我知道内存中的数据是二进制格式的,因此文件中的数据也是二进制格式的。 我可以为此使用
mmap
吗?在哪里可以找到有关如何使用
mmap
的好资源?我没有找到一本好的手册

以下是一个示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h> /* mmap() is defined in this header */
#include <fcntl.h>

void err_quit(char *msg)
{
    printf(msg);
    return 0;
}

int main (int argc, char *argv[])
{
 int fdin, fdout;
 char *src, *dst;
 struct stat statbuf;
 int mode = 0x0777;

 if (argc != 3)
   err_quit ("usage: a.out <fromfile> <tofile>");

 /* open the input file */
 if ((fdin = open (argv[1], O_RDONLY)) < 0)
   {printf("can't open %s for reading", argv[1]);
    return 0;
   }

 /* open/create the output file */
 if ((fdout = open (argv[2], O_RDWR | O_CREAT | O_TRUNC, mode )) < 0)//edited here
   {printf ("can't create %s for writing", argv[2]);
    return 0;
   }

 /* find size of input file */
 if (fstat (fdin,&statbuf) < 0)
   {printf ("fstat error");
    return 0;
   }

 /* go to the location corresponding to the last byte */
 if (lseek (fdout, statbuf.st_size - 1, SEEK_SET) == -1)
   {printf ("lseek error");
    return 0;
   }

 /* write a dummy byte at the last location */
 if (write (fdout, "", 1) != 1)
   {printf ("write error");
     return 0;
   }

 /* mmap the input file */
 if ((src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0))
   == (caddr_t) -1)
   {printf ("mmap error for input");
    return 0;
   }

 /* mmap the output file */
 if ((dst = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE,
   MAP_SHARED, fdout, 0)) == (caddr_t) -1)
   {printf ("mmap error for output");
    return 0;
   }

 /* this copies the input file to the output file */
 memcpy (dst, src, statbuf.st_size);
 return 0;

} /* main */  
#包括
#包括
#include/*mmap()在此标头中定义*/
#包括
无效错误退出(char*msg)
{
printf(msg);
返回0;
}
int main(int argc,char*argv[])
{
int-fdin,fdout;
字符*src,*dst;
结构stat statbuf;
int模式=0x0777;
如果(argc!=3)
err_quit(“用法:a.out”);
/*打开输入文件*/
如果((fdin=open(argv[1],orduonly))<0)
{printf(“无法打开%s进行读取”,argv[1]);
返回0;
}
/*打开/创建输出文件*/
if((fdout=open(argv[2],O|RDWR | O|u CREAT | O|u TRUNC,mode))<0)//在此处编辑
{printf(“无法创建%s进行写入”,argv[2]);
返回0;
}
/*查找输入文件的大小*/
如果(fstat(fdin和statbuf)<0)
{printf(“fstat错误”);
返回0;
}
/*转到与最后一个字节对应的位置*/
if(lseek(fdout,statbuf.st_size-1,SEEK_SET)=-1)
{printf(“lseek错误”);
返回0;
}
/*在最后一个位置写入虚拟字节*/
如果(写入(fdout,“,1)!=1)
{printf(“写入错误”);
返回0;
}
/*mmap输入文件*/
if((src=mmap(0,statbuf.st_size,PROT_READ,MAP_SHARED,fdin,0))
==(caddr_t)-1)
{printf(“输入的mmap错误”);
返回0;
}
/*mmap输出文件*/
如果((dst=mmap(0,statbuf.st_大小,PROT_读取,PROT_写入,
映射共享,fdout,0))==(caddr\u t)-1)
{printf(“输出的mmap错误”);
返回0;
}
/*这会将输入文件复制到输出文件*/
memcpy(dst、src、statbuf、st_尺寸);
返回0;
}/*主*/


内存映射。

资源->

示例: 法赫米

 if ((dst = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE,
   MAP_SHARED, fdout, 0)) == (caddr_t) -1)
   err_sys ("mmap error for output");

 /* this copies the input file to the output file */
 memcpy (dst, src, statbuf.st_size);

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*无法在OS X上工作,因为您无法在/dev/zero上映射mmap*/
内部主(空)
{
常量字符str1[]=“字符串1”;
常量字符str2[]=“字符串2”;
int parpid=getpid(),childpid;
int-fd=-1;
char*anon,*zero;
如果((fd=open(“/dev/zero”,O_RDWR,0))=-1)
错误(1,“开放”);
anon=(char*)mmap(NULL,4096,PROT|u READ | PROT|u WRITE,MAP|anon | MAP|u SHARED,-1,0);
零=(char*)mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_FILE | MAP_SHARED,fd,0);
if(anon==MAP|u失败| zero==MAP_失败)
errx(1,“任一mmap”);
strcpy(anon,str1);
strcpy(零,str1);
printf(“PID%d:\t匿名%s,零备份%s\n”,parpid,anon,zero);
开关((childpid=fork()){
案例1:
错误(1,“叉”);
/*未到达*/
案例0:
childpid=getpid();
printf(“PID%d:\t匿名%s,零备份%s\n”,childpid,anon,zero);
睡眠(3);
printf(“PID%d:\t匿名%s,零备份%s\n”,childpid,anon,zero);
munmap(anon,4096);
munmap(0,4096);
关闭(fd);
返回(退出成功);
}
睡眠(2);
strcpy(anon,str2);
strcpy(零,str2);
printf(“PID%d:\t匿名%s,零备份%s\n”,parpid,anon,zero);
munmap(anon,4096);
munmap(0,4096);
关闭(fd);
返回(退出成功);
}

尝试使用这两种方法,并根据你的目标调整它们。

man 2 mmap
将告诉你你需要知道的一切。反过来说。创建一个文件,然后映射它。然后,对该文件占用的内存的任何访问都将自动写入磁盘上的文件。请注意,如果使用mmap将内存整数写入文件,则不同平台上的字节顺序可能会阻止这些文件在运行程序的不同架构之间交换。如果这对你很重要,@MarcB:自动,但不是立即。只有当系统需要释放一些物理内存并且需要将该内存交换到磁盘时,系统才会将其写入磁盘。在此之前,内存中的更改在文件中不会自动可见,并且不会以任何方式影响文件(见鬼,如果使用
MAP\u PRIVATE
!),它可能根本不会影响文件)。数据将保存在
munmap
上的磁盘上,或者当您使用
msync
特别请求时保存。谢谢。当我想编译它时,我得到了这样一个错误:“error:'FILE_MODE'undeclared(首次在此函数中使用)”。我应该在哪里指定输入文件是,从输入:“usage:a.out”FILE_MODE应该包含权限,例如,将其设置为FILE_MODE=0x0777。FILE_MODE应该是一个int。请参阅代码中的编辑,我已经做了。虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,只有链接的答案可能会变得无效。@Verdolino嗨,我按照你的建议修改了我的答案。谢谢你的意见!
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Does not work on OS X, as you can't mmap over /dev/zero */
int main(void)
{
        const char str1[] = "string 1";
        const char str2[] = "string 2";
        int parpid = getpid(), childpid;
        int fd = -1;
        char *anon, *zero;

        if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
                err(1, "open");

        anon = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
        zero = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);

        if (anon == MAP_FAILED || zero == MAP_FAILED)
                errx(1, "either mmap");

        strcpy(anon, str1);
        strcpy(zero, str1);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        switch ((childpid = fork())) {
        case -1:
                err(1, "fork");
                /* NOTREACHED */
        case 0:
                childpid = getpid();
                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                sleep(3);

                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                munmap(anon, 4096);
                munmap(zero, 4096);
                close(fd);
                return (EXIT_SUCCESS);
        }

        sleep(2);
        strcpy(anon, str2);
        strcpy(zero, str2);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        munmap(anon, 4096);
        munmap(zero, 4096);
        close(fd);
        return (EXIT_SUCCESS);
}