实例为将图片进行拷贝,在Linux系统下的运行程序如下:
setfile.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* 根据要拷贝文件大小开辟共享内存大小 */
int main(int argc, const char *argv[]){
if(argc != 2){
printf("Usage: %s filename\n", argv[0]);return -1;
}
key_t key;
int shmid;
char *addr = NULL;
if(-1 == (key=ftok("/home", 1))){
perror("ftok");return -1;
}
//获取目标文件的大小--根据stat函数获取属性
struct stat filebuf;
if(-1 == stat(argv[1], &filebuf)){
perror("stat");return -1;
}
printf("调整之前:file_size= %ld\n", filebuf.st_size);
off_t file_size = filebuf.st_size;
//将文件大小数值保存至指定文件中,以便于读进程能够访问同一ipc对象
FILE *fp_size = fopen("/home/wang/project/1", "w+");
fwrite(&file_size, 1, sizeof(file_size), fp_size);
fclose(fp_size);
//调整文件的大小为4096整数倍
while(file_size % 4096 != 0){
file_size++;
}
printf("调整之后:file_size= %ld\n", file_size);
//创建共享内存
if(-1 == (shmid = (shmget(key, file_size, IPC_CREAT|0666)))){
perror("shmget");return -1;
}
//映射
if((void *)-1 == (addr = shmat(shmid, NULL, 0))){
perror("shmat");return -1;
}
//打开源文件
FILE *fp = fopen(argv[1], "rb+");
char *tmp = addr; //临时指针
int readlen = 0;
//循环读取,将数据写入共享内存段,并且每次写入之后要偏移指针
while((readlen =fread(tmp, 1, 4096, fp))){
tmp += readlen;
}
fclose(fp);
//取消映射
shmdt(addr);
return 0;
}
getfile.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* 根据要拷贝文件大小开辟共享内存大小 */
int main(int argc, const char *argv[]){
if(argc != 2){
printf("Usage: %s filename", argv[0]);return -1;
}
key_t key;
int shmid;
char *addr = NULL;
long file_size = 0;
if(-1 == (key=ftok("/home", 1))){
perror("ftok");return -1;
}
//从指定文件中获取文件大小,以便于读进程能够访问同一ipc对象
FILE *fp_size = fopen("/home/wang/project/1", "rb+");
fread(&file_size, 1, sizeof(file_size), fp_size);
fclose(fp_size);
printf("文件真实大小:%ld\n", file_size);
int relsize = file_size;
//调整文件的大小为4096整数倍
while((file_size) % 4096 != 0){
file_size++;
}
printf("调整之后:file_size= %ld\n", file_size);
//创建共享内存
if(-1 == (shmid = (shmget(key, file_size, IPC_CREAT|0666)))){
perror("shmget");return -1;
}
//映射
if((void *)-1 == (addr = shmat(shmid, NULL, 0))){
perror("shmat");return -1;
}
//打开目标文件 [拷贝过后生成的文件]
FILE *fp = fopen(argv[1], "w+");
char *tmp = addr; //临时指针
int writelen = 0;
//循环从共享内存段读取数据放入文件
while( relsize ){
if(relsize < 4096){
writelen = fwrite(tmp, 1, relsize, fp);
break;
}
writelen = fwrite(tmp, 1, 4096, fp);
tmp += writelen; //写入之后偏移共享内存段的指针
relsize -= writelen; //文件大小减少对应的字节数
}
fclose(fp);
//取消映射
shmdt(addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}