Day26_UC文件操作函数(读写)

回顾:
  Unix/Linux内存分配的函数和系统函数:
   malloc() free()
   sbrk() brk()
   mmap() munmap()
今天:
  文件描述符 - 对应一张文件表,文件信息存在文件表中,描述符只是文件表在进程文件总表中的编号,本质就是一个非负数
  open() read() write() close() ioctl()
/*  int open(const char *pathname, int flags);  函数原型
  int open(const char *pathname, int flags, mode_t mode); */
  int open(char* name,int flags,...)
  name 就是文件名(带路径)
  flags  常见值:(多个值用 | 连接)
  O_RDONLY  O_WRONLY  O_RDWR 设定权限,必选其一
  O_CREAT - 没有就新建,有就打开
    O_EXCL - 辅助O_CREAT 没有就新建,有返回-1
    O_TRUNC - 没有就新建,有就清空后打开
  O_APPEND - 追加方式打开,一般是追加写
  返回 可用的文件描述符 最小值,失败返回-1
  注: 如果新建文件,需要第三个参数 -- 文件权限
  常识:关于文件的操作,有两组信息
      1.硬盘上的文件信息,比如文件大小,文件权限,文件的最后修改时间...;
      2.内存中的文件描述符信息,比如:描述符权限(O_RDONLY等),文件偏移量...;
      
  read() 和 write()
  int read(int fd,void* buf,size_t count)
  int write(int fd,void* buf,size_t count)
  参数: fd - 文件描述符
         buf - 任意类型的首地址
         count - 对于read(),count是期望值
                 对于write(),count是实际值
  返回真实的字节数(读/写),失败返回-1
  read() 返回 0 代表读完
 
  vi用wq保存退出时,多加一个换行符
练习:
  1.员工管理系统 - 新增员工、查询员工信息
    新增: 输入员工的信息,把信息保存到文件中,员工信息包括:员工编号、姓名、工资
    查询: 把文件中的员工信息读出来并打印出有效信息
-----------------------------------------------------------
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5 struct Data
  6 {
  7     int id;
  8     char name[20];
  9     double salary;
 10 };
 11
 12 void add()
 13 {
 14     struct Data Data;
 15     int fd = open("data",O_RDWR|O_CREAT|O_APPEND,0666);
 16     if(fd == -1) perror("OPEN"),exit(-1);
 17     printf("请输入ID:\n");
 18     scanf("%d",&Data.id);
 19     printf("请输入姓名:\n");
 20     scanf("%s",Data.name);
 21     printf("请输入工资:\n");
 22     scanf("%lf",&Data.salary);
 23     write(fd,&Data,sizeof(Data));
 24     close(fd);
 25 }
 26
 27 void query(int id)
 28 {
 29     struct Data Data;
 30     int fd = open("data",O_RDONLY);
 31     if(fd == -1) perror("OPEN"),exit(-1);
 32     while(read(fd,&Data,sizeof(Data)))
 33     {
 34         if(Data.id == id)
 35             break;
 36     }
 37     printf("ID:%d\n姓名:%s\n工资:%lg\n",Data.id,Data.name,    Data.salary);
 38     close(fd);
 39 }
 40 int main()
 41 {
 42     int x;
 43     printf("输入 1 新增, 2 查询:\n");
 44     scanf("%d",&x);
 45     if(x==1)
 46     {
 47         while(x)
 48         {
 49             add();
 50             printf("是否继续输入?(1/0)");
 51             scanf("%d",&x);
 52         }
 53     }
 54     else if(x==2)
 55     {
 56         printf("请输入查询ID:\n");
 57         scanf("%d",&x);
 58         query(x);
 59     }
 60 }
-----------------------------------------------------------
  2.修改写文件的代码,实现 用cat命令查看时,能显示 可以看懂的信息。比如:
    1,zhangfei,12000.000000
    思路:sprintf() 只有字符串写入才能看懂  
-----------------------------------------------------------
  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <fcntl.h>
  5 #include <string.h>
  6 struct Emp
  7 {
  8     int id;
  9     char name[20];
 10     double sal;
 11 };
 12 int main()
 13 {
 14     struct Emp em = {1,"zhangfei",12000.0};
 15     int fd = open("data",O_RDWR|O_TRUNC);
 16     if(fd == -1) perror("OPEN"),exit(-1);
 17     char buf[100] = {};
 18     sprintf(buf,"%d,%s,%lf",em.id,em.name,em.sal);
 19     write(fd,buf,strlen(buf));
 20     close(fd);
 21 }
-----------------------------------------------------------
time a.out 可以测试程序运行时间,包括总时间,用户层时间和内核层时间

uc的文件读写函数在用户层是没有缓冲区的,如果频繁读写,需要程序员自定义缓冲区,而标C自身有缓冲区;

  在系统中,文件描述符对应一张文件表,文件表中记录了描述符的信息和硬盘上文件的信息,定位硬盘上的文件/目录用i节点。ls -i 可以查看i节点,每张文件表 都有自己的偏移量
   函数lseek()可以设定文件的偏移量
-----------------------------------------------------------
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5
  6 int main()
  7 {
  8     int fd = open("a.txt",O_RDWR);
  9     if(fd == -1) perror("OPEN"),exit(-1);
 10     char ch;
 11     read(fd,&ch,1); printf("%c\n",ch);//a
 12     read(fd,&ch,1); printf("%c\n",ch);//b
 13     lseek(fd,3,SEEK_CUR);
 14     read(fd,&ch,1); printf("%c\n",ch);//f
 15     lseek(fd,0,SEEK_SET);//回到开始
 16     write(fd,"1",1);//a -> 1
 17     lseek(fd,3,SEEK_SET);   write(fd,"2",1);//d -> 2
 18     lseek(fd,2,SEEK_CUR);   write(fd,"3",1);//g -> 3
 19     lseek(fd,-2,SEEK_CUR);  write(fd,"4",1);//f -> 4
 20     lseek(fd,-2,SEEK_END);  write(fd,"5",1);//t -> 5
 21     close(fd);
 22 }
 
a.txt = abcdefghijklmnopqrst
   经验: lseek()的 whence参数使用SEEK_SET
-----------------------------------------------------------
作业:
   实现真实版的用户登陆和注册(文件版)
     定义一个用户的结构,包括:用户名、密码、邮箱。读写基本单位是结构
     用户注册模块 - 用户输入用户名、密码和邮箱,用追加方式写入文件,打印注册成功或失败
   增强版:
     1 加入密码确认,输入两次密码,两个字符串相等才能继续输入邮箱
     2 加入用户名重复的过滤:如果用户名已经存在,那么告知用户,用户名已经被使用
   思路: 写之前先读文件,读入一个数组,数组长度 文件大小/sizeof(结构)
   用户登陆 - 读文件  ,读入一个数组,数组长度 文件大小/sizeof(结构)。再让用户输入用户名和密码,比较 用户名和密码都相等,登陆成功,否则登陆失败



uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,uc进程的函数详解,v
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值