Linux下的文件操作(2)——基於文件描述符的文件操作
概要:
- 打開、創建和關閉文件
- 讀寫文件
- 文件定位
- 獲取文件信息
打開、創建和關閉文件
函數原型:
#include <sys/types.h> //頭文件
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags); //文件名 打開方式
int open(const char *pathname, int flags, mode_t mode);//文件名 打開方式 權限
flags和mode都是一組掩碼的合成值,flags表示打開或創建的方式,mode表示文件的訪問權限。
flags 的選項:
- O_CREAT參數:
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDONLY|O_CREAT);
ERROR_CHECK(fd,-1,"open");
printf("fd=%d\n",fd);
return 0;
}
open()函數出錯時返回-1,創建成功時返回未使用的最小文件描述符
0 標準輸入符
1 標準輸出符
2 標準錯誤輸出符
故該代碼中open()返回值為3
- O_CREAT加自定義權限:
當輸入的文件名不存在時,自動創建文件,但該文件權限是有問題的,所以在open()函數後加上自定義權限參數
#include <func.h> int main(int argc,char* argv[]) { ARGS_CHECK(argc,2); int fd; fd=open(argv[1],O_RDONLY|O_CREAT,0600); ERROR_CHECK(fd,-1,"open"); printf("fd=%d\n",fd); return 0; }
若文件已存在則跳出,否則創建文件:
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDONLY|O_CREAT|O_EXCL,0600);
ERROR_CHECK(fd,-1,"open");
printf("fd=%d\n",fd);
return 0;
}
TRUNK參數:若文件已存在截斷內容為0
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDONLY|O_TRUNC,0600);
ERROR_CHECK(fd,-1,"open");
printf("fd=%d\n",fd);
return 0;
}
close用於文件的關閉:
int close(int fd);//fd表示文件描述詞,是先前由open或creat創建文件時的返回值。
文件使用完畢後,應該調用close關閉它,一旦調用close,則該進程對文件所加的鎖全都被釋放,並且使文件的打開引用計數減1,只有文件的打開引用計數變為0以後,文件才會被真正的關閉。
讀寫文件
函數原型:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);//文件描述詞 緩沖區 長度
ssize_t write(int fd, const void *buf, size_t count);
對於read和write函數,出錯返回-1,讀取完了之後,返回0, 其他情況返回讀寫的個數。
read.c
#include <func.h>
int main(int argc, char* argv[])
{
ARGS_CHECK(argc, 2);
int fd;
fd = open(argv[1], O_RDONLY);
ERROR_CHECK(fd, -1, "open");
printf("fd = %d\n", fd);
int ret;
ret = read(fd, buf, sizeof(buf));
ERROR_CHECK(ret, -1, "read");
printf("buf = %s\n", buf);
return 0;
}
write.c
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDWR);
ERROR_CHECK(fd,-1,"open");
printf("fd = %d\n",fd);
int arr[5]={1,2,3,4,5};
int ret;
ret=write(fd,arr,sizeof(arr));
ERROR_CHECK(fd,-1,"write");
lseek(fd,0,SEEK_SET); //從文件頭開始計算
memset(arr,0,sizeof(arr));
ret=read(fd,arr,sizeof(arr));
ERROR_CHECK(fd,-1,"read");
printf("ret = %d,arr[0] = %d,arr[3] = %d\n",ret,arr[0],arr[3]);
return 0;
}
文件定位
函數lseek將文件指針設定到相對於whence,偏移值為offset的位置
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);//fd文件描述詞
whence 可以是下面三個常量的一個
SEEK_SET 從文件頭開始計算
SEEK_CUR 從當前指針開始計算
SEEK_END 從文件尾開始計算
- 文件空洞——通常用於多進程間通信的時候的共享內存
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDWR);
ERROR_CHECK(fd,-1,"open");
printf("fd=%d\n",fd);
int ret;
ret=lseek(fd,1024,SEEK_SET);
printf("lseek ret=%d\n",ret);
char c='H';
write(fd,&c,sizeof(c));
close(fd);
return 0;
}
- 改變文件大小
#include <func.h>
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
int fd;
fd=open(argv[1],O_RDWR);
ERROR_CHECK(fd,-1,"open");
printf("fd=%d\n",fd);
int ret;
ret=ftruncate(fd,1024);
ERROR_CHECK(ret,-1,"ftruncate");
close(fd);
return 0;
}
獲取文件信息
fstat和stat函數獲取文件信息,調用完畢後,文件信息被填充到結構體struct stat變量中,函數原型為:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf); //文件名 stat結構體指針
int fstat(int fd, struct stat *buf); //文件描述詞 stat結構體指針
Linux下的文件操作(2)——基於文件描述符的文件操作