1,打开或创建文件,得到文件描述符,
2,将内存中的数据以一定的格式和顺序写入文件,或者将文件中的数据以一定的格式和顺序读入到内存;
3,关闭文件描述符;
下边是按照常规方式操作固定格式的文件的方法,包含读写两个示例;
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <unistd.h>
4. #include <fcntl.h>
5. #include <string.h>
6.
//写内存到文件
7. struct student{
8. char name[
20];
9. short
10. float
11. char
12.
};
13. int main()
14.
{
15. struct student stu[5];
16. mode_t
17. 000);
18. int fd=open(
"user.dat",O_RDWR|O_CREAT|O_EXCL,
00666);
19. if(fd==
-1){
20. printf(
"open:%m\n");
21.
umask(mode);
22. exit(
-1);
23.
}
24. printf(
"ok\n");
25. memset(stu,
0,
sizeof(stu));
26. int i=
0;
27. for(;i<
5;i++){
28. memcpy(stu[i].name,
"tom",
strlen(
"tom")+
1);
29.
stu[i].age=i;
30. 89.12f;
31. 'm';
32. sizeof(stu[i]));
33.
}
34.
close(fd);
35.
umask(mode);
36. return
0;
37.
}
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <unistd.h>
4. #include <fcntl.h>
5. #include <string.h>
6.
7. typedef
struct{
8. char name[
20];
9. short
10. float
11. char
12.
}Student;
13.
//读取文件到内存
14. int main()
15.
{
16. 5];
17. mode_t
18. 0000);
19. int fd=open(
"user.dat",O_RDWR,
0666);
20. if(fd==
-1){
21. printf(
"open:%m\n");
22.
umask(mode);
23. exit(
-1);
24.
}
25. printf(
"open ok! can read;\n");
26. int i=
0;
27. for(;i<
5;i++){
28. sizeof(stu[i]));
29.
}
30.
close(fd);
31. 0;
32. for(;i<
5;i++){
33. printf(
"stu[%d].name=%s\n",i,stu[i].name);
34. printf(
"stu[%d].age=%d\n",i,stu[i].age);
35. printf(
"stu[%d].sex=%c\n",i,stu[i].sex);
36. printf(
"stu[%d].score=%f\n",i,stu[i].score);
37.
}
38.
umask(mode);
39. return
0;
40.
}
以上操作文件的方式只能操作小文件,如果文件很大,就无法一次载入内存操作,我们就需要用到内存映射技术来操作;具体实现如下:
1,首先打开文件,使用的函数原型如下:
int open( //返回值:大于等于0代表操作成功,返回打开的文件描述符号,=-1,创建或者打开失败,失败可查阅errorno来获取具体错误信息
const char *pathname, //要打开的文明名
int flags, //打开的方式,打开方式包括:O_RDONLY 只读方式 O_WRONLY 只写,O_RDWR读写,O_CREAT创建,O_EXCL文件如果存在,使用此标记,会返回错误
mode_t mode); //指定创建文件的权限,只对创建文件有效,对于打开无效;
2,获取文件大小
int fstat(int fd,//文件描述符号
struct stat*buf);//返回文件属性结构体
返回值:成功返回0;失败返回-1
3,把文件映射成虚拟内存
void *mmap(void *addr, //从进程的那个地址开始映射,如果为NULL,由系统指定;
size_t length, //映射的地址空间的大小
int prot, //内存的保护模式
int flags,//映射模式 有匿名,私有,保护等标记 具体查询man手册;
int fd, //如果为文件映射,则此处为文件的描述符号
off_t offset);//如果为文件映射,则此处代表定位到文件的那个位置,然后开始向后映射。
返回值:映射成功,返回首地址;
4,通过对内存的读写来实现对文件的读写
通常使用:memset 和memcpy来实现操作;
5,卸载映射
int munmap(void *addr, //要卸载的内存的地址
size_t length);//内存的大小
6,关闭文件
int close(int fd); //要关闭的文件描述符号 ,成功返回0,错误返回-1,错误参照errorno;
下边是读取文件的操作:
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <unistd.h>
4. #include <fcntl.h>
5. #include <sys/mman.h>
6. #include <sys/stat.h>
7. typedef struct{
8. char name[20];
9. short
10. float
11. char
12. }student;
13. int main()
14. {
15. student *p,*pend;
16. //打开文件描述符号
17. int
18. /*打开文件*/
19. "user.dat",O_RDWR);
20. if(fd==-1){//文件不存在
21. "user.dat",O_RDWR|O_CREAT,0666);
22. if(fd==-1){
23. printf("打开或创建文件失败:%m\n");
24. exit(-1);
25. }
26. }
27. //打开文件ok,可以进行下一步操作
28. printf("open ok!\n");
29. //获取文件的大小,映射一块和文件大小一样的内存空间,如果文件比较大,可以分多次,一边处理一边映射;
30. struct stat st; //定义文件信息结构体
31. /*取得文件大小*/
32. int
33. if(r==-1){
34. printf("获取文件大小失败:%m\n");
35. close(fd);
36. exit(-1);
37. }
38. int
39. /*把文件映射成虚拟内存地址*/
40. NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
41. if(p==NULL || p==(void*)-1){
42. printf("映射失败:%m\n");
43. close(fd);
44. exit(-1);
45. }
46. /*定位到文件开始*/
47. pend=p;
48. /*通过内存读取记录*/
49. int i=0;
50. while(i<(len/sizeof(student)))
51. {
52. printf("第%d个条\n",i);
53. printf("name=%s\n",p[i].name);
54. printf("age=%d\n",p[i].age);
55. printf("score=%f\n",p[i].score);
56. printf("sex=%c\n",p[i].sex);
57. i++;
58. }
59. /*卸载映射*/
60. munmap(p,len);
61. /*关闭文件*/
62. close(fd);
63. }
标签:文件,映射,int,mmap,stu,fd,内存,linux,include
From: https://blog.51cto.com/u_16081664/6459713