一、文件描述符
linux系统会为每一个打开的文件分配一个文件描述符(一个非负整数),我们可以使用文件描述符对文件进行一系列的操作。
二、文件操作
2.1、open
open函数既可以打开已经存在的文件,也可以创建一个新的文件并打开。
函数原型:int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
头文件:#include <sys/types.h>
#include<sys/stat.h>
#include <fcntl.h>
函数参数:pathname 文件路径
flags 打开文件的方式
mode 指定打开文件的权限
flags参数说明:
O_RDONLY 以只读的方式打开文件
O_WRONLY 以只写的方式打开文件
O_RDWR 以可读可写的方式打开文件
O_DIRECTORY 打开目录文件,可以用来判断一个文件是否为目录文件
O_APPEND 以追加的方式打开文件,以这种方式打开文件后,文件指针自动指向文件末尾,在NFS文件系统中,如果有两个以上进程同时向一个文件中追加文件会导致系统崩溃;
O_ASYNC
O_CREAT 打开文件,如果文件不存在就创建它
2.2、read
函数原型:ssize_t read(int fd, void *buf, size_t count);
头文件:#include <unistd.h>
函数参数:fd 文件描述符
buf读取数据缓冲区
count 需要读取的数据长度
返回值:成功返回读取到的字节数,失败返回-1
2.3、write
函数原型:ssize_t write(int fd, const void *buf, size_t count);
头文件:#include <unistd.h>
返回值:成功返回写入的字节数,失败返回-1
三、目录操作
3.1、opendir
函数原型:DIR *opendir(const char *name);
头文件:#include <sys/types.h>#include <dirent.h>
函数参数:name 目录文件的路径;
返回值:成功返回DIR结构体,其中包含文件描述符、目录大小等信息,这个结构体我们通常不必关心,失败返回NULL;
opendir用来打开一个目录文件,name指定目录的路径,如果打开目录成功返回一个DIR结构体,如果失败返回NULL.
3.2、readdir
函数原型:struct dirent *readdir(DIR *dirp);
头文件:#include <dirent.h>
函数参数:dirp 调动用opendir的返回值
返回值:成功返回一个指向dirent结构体的指针,当访问目录的末尾或者有错误发生时返回NULL
readdir用来访问调用opendir打开目录下的文件,并将文件的名称、大小等信息保存到dirent结构体中。
dirent结构体:
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types 文件的类型*/;
char d_name[256]; /* Null-terminated filename 文件名长度,最大255个字符,文件名以NULL结尾*/
};
四、文件偏移
4.1、lseek
lseek用来设置文件偏移地址,offset指定文件偏移的字节数,whence指定文件偏移的方向:
- SEEK_SET 从文件起始位置向后偏移
- SEEK_CUR 设置文件偏移地址位当前地址
- SEEK_END 设置文件偏移地址为文件末尾
函数原型:off_t lseek(int fd, off_t offset, int whence);
头文件:#include <sys/types.h>
#include <unistd.h>
函数参数:fd 文件描述符
offset 文件偏移地址
whence 指定文件偏移的方向
返回值:成功返回从文件起始地址的偏移量,失败返回-1
五、获取文件信息
在介绍函数之前需要先了解存储文件信息的结构体struct stat:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
结构体详细的说明请参考:
5.1、stat函数
函数原型:int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
头文件: #include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
函数参数:
五、文件操作举例
5、1 输出指定目录下的所有文件名称和大小(深度为1,不遍历)
int main()
{
int ret = -1;
DIR *dir = NULL;
char *dir_path = "./DIR";
struct dirent *pDirent;
struct stat file_info;
char file_path[PATH_MAX];
if ((dir = opendir(dir_path)) == NULL) {
perror(dir);
return ;
}
while(NULL != (pDirent = readdir(dir)))
{
sprintf(file_path,"./DIR/%s",pDirent->d_name);//需要将pDirent->d_name转换成当前操作目录下的路径,当前操作目录是
if(0 == stat(file_path,&file_info))//获取文件信息,不需要打开文件
{
printf("%s %d\r\n",pDirent->d_name,file_info.st_size);
}
else
{
perror(file_path);
}
}
return 0;
}