uc_day04

一,文件讀寫
write.c


#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int main(){


   int fd = open("a.txt",O_WRONLY|O_CREAT,0666);
   if(fd == -1){}
   int id = 1000;
   char* name = "DanielGuo";
   int age = 30;
   double salary = 120000;
   
   write(fd,&id,sizeof(id));
   write(fd,name,strlen(name)+1);
   write(fd,&age ,sizeof(age));
   write(fd,&salary ,sizeof(salary));
   close(fd);
   return 0;
}


vi打開的是字符文件
注:write是把內存中的內容寫到文件中






read.c


#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>


int main(){
   int fd = open("a.txt",O_RDONLY);
   if(fd == -1){}
   int id;
   char name[30] = {};//char* name;這樣會得不到結果,因爲name是野指針
   int age;
   double salary;
   read(fd,&id,sizeof(id));
   read(fd,name,10);
   read(fd,&age,sizeof(age));
   read(fd,&salary,sizeof(salary));
   prinf("%d,%s,%d,%g\n",id,name,age,salary);
   close(fd);
   return 0;
}
注:結構體的寫,讀取的時候按照結構體讀


二,lseek函數
每個打開的文件都有一個與其相關的“當前文件偏移量”


lseek可以移動文件偏移量
off_t lseek(int fildes, off_t offset,int whence);


偏移量過大,可能形成文件空洞
lseek.c


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>


int main(){
  int fd = open("a.txt",O_RDWR);
  if(fd == -1){}


  char ch;
  read(fd,&ch,1);
  printf("%c\n",ch);
  read(fd,&ch,1);
  printf("%c\n",ch);
  
  lseek(fd,3,SEEK_CUR);
  read(fd,&ch,1);
  printf("%c\n",ch);
  return 0;
}


三,打開文件的內核數據結構
文件表
文件狀態標誌,當前文件偏移量,v節點指針


V節點表
V節點信息,i節點信息,文件長度


四,dup,dup2函數---複製當前文件描述符


int main(){
  int fd = open("a.txt",O_RDWR);
  if(fd == -1){}
  int fd2 = dup(fd);//複製文件描述符
  printf("fd=%d,fd2=%d\n",fd,fd2);


  int fd3 = dup2(fd,100);
  
  return 0;
}
注:dup僅僅複製文件描述符,不會複製文件表
dup2如果指定的文件描述符已經存在,則關閉已經存在的 
五,fcntl函數-----複製文件描述符,設置和獲得文件狀態標誌
複製文件描述符,和dup2不同的是fcntl如果發現5已經被使用,
會返回一個比5大的未使用過的最小的文件描述符


還可以設置和獲取文件描述符,還可對文件進行加鎖


#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>


int main(){


  int fd = open("a.txt",O_RDWR);
  if(fd == -1){}
  int fd2 = fcntl(fd,F_DUPFD,5);
  printf("fd=%d,fd2=%d\n",fd,fd2);


  //獲取文件的狀態標誌
  int flags = fcntl(fd,F_GETFL);
  printf("flags=%d\n",flags);
  switch(flags & 3){
   case O_RDONLY:
   case O_RDWR:
   case O_WRONLY:


  }


  if(flags & O_APPEND){printf("append\n");}
  //創建文件的標誌不會保存在文件狀態中,一下3個是錯誤的用法
  if(flags & O_CREAT)
  if(flags & O_TRUNC)
  if(flags & O_EXCL)


  //修改文件狀態標誌
  fcntl(fd,F_SETFL,O_RDWR | O_APPEND);
  flags = fcntl(fd,F_GETFL);
  //修改文件狀態標誌也不是全部能修改,只是部分
  //文件訪問權限O_RDONLY,O_WRONLY,O_RDWR不能修改
 //創建也不能
  return 0;
}


-----------------------------------------------------
文件鎖:
鎖的結構
struct flock{
short l_type;//鎖的類型 FRDLOCK 讀鎖(共享鎖),F_WRLOCK 寫鎖(排他鎖)
short l_whence;//鎖的起始計算位置
off_t l_start;//加鎖的位置,文件的偏移量
int l_len;//鎖的長度
pid_t l_pid;//加鎖的進程ID
};
對於同一個文件中的某區域,如果A進程加了讀鎖,B進程也可以加
讀鎖。但是不能加寫鎖
如A進程加了寫鎖,B進程不能加寫鎖,也不能加讀鎖


short l_whence,off_t l_start這倆參數一起決定鎖加的位置




int main(){


  int fd = open("a.txt",O_RDWR);
  
  //準備一把鎖
  struct flock lock;
  lock.l_type = F_RDLOCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 10;
  lock.l_len = 20;
  lick.l_pid = -1;
  //加鎖
  int res = fcntl(fd,F_SETLK,&lock);
  if(res == -1){
    加鎖失敗
  }else{
    加鎖成功
  }
  return 0;
}























發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章