函数集合
- 函数结构
- 标准IO
- fopen
- fclose
- fgetc
- fputc
- fgets
- fputs
- fread
- fwrtie
- rewind
- ftell
- fseek
- fflush
- fprintf
- perror
- 文件IO
- 文件IO用到的头文件
- open
- close
- read
- write
- lseek
- 目录IO
- 目录IO用到的头文件
- opendir
- closedir
- readdir
- chdir
- stat
- getpwuid
- getgrgid
- 时间
- time
- localtime
- ctime
函数结构
头文件:
函数声明:
功能:
参数:
返回值:
成功:
失败:
使用注意事项:
标准IO
定义在C库中的用于输入输出的函数接口
fopen
头文件:
# include <stdio.h>
函数声明
FILE *fopen(const char *path, const char *mode);
功能: 打开文件
参数:
const char *path:打开文件的路径
const char *mode:文件打开方式
返回值:
成功:返回文件流指针
失败:返回NULL,更新errno
使用注意事项:
- mode打开方式
打开方式 | 权限 | 功能 |
---|---|---|
r | 只读 | 文件指针定位到文件开头(有文件) |
r+ | 可读可写 | 文件指针定位到文件开头(有文件) |
w | 只写 | 文件不存在则创建,文件存在则清空,文件指针定位到文件开头 |
w+ | 可读可写 | 文件不存在则创建,文件存在则清空,文件指针定位到文件开头 |
a | 只写 | 文件不存在则创建,文件存在则追加,文件指针定位到文件末尾 |
a+ | 可读可写 | 文件不存在则创建,文件存在则追加,文件指针定位到文件末尾 |
- 打开文件是有限资源,最多打开1024个文件,所以操作完文件要及时关闭
fclose
头文件:
#include <stdio.h>
函数声明:
int fclose(FILE *stream);
功能: 关闭文件
参数: 文件流指针
返回值:
成功:返回0
失败:返回EOF,更新errno
fgetc
头文件:
#include <stdio.h>
函数声明:
int fgetc(FILE *stream);
功能: 从文件中读取一个字符
参数: 流指针,指向目标文件
返回值:
成功:返回读取到的字符的ASCII,读取到文件末尾返回-1
失败:返回EOF
fputc
头文件:
#include <stdio.h>
函数声明:
int fputc(int c, FILE *stream);
功能: 向文件中输入一个字符
参数:
int c:输入字符的ASCII
FILE *stream:文件流指针,指向目标文件
返回值:
成功:写入字符的ASCII
失败:返回EOF,更新errno
fgets
头文件:
#include <stido.h>
函数声明:
char *fgets(char *s, int size, FILE *stream);
功能: 从文件中获取一定长度的字符串
参数:
char *s:从文件中获取的字符串存放的首地址
int size:从文件中获取的字符串的长度
FILE *stream:流指针,指向目标文件
返回值:
成功:返回读获取的字符串的首地址,读到文件结尾会返回NULL
失败:返回NULL
使用注意事项:
- fgets获取到字符串之后会自动补’\0’,所以实际获取的字符个数为size-1
- 文件中不满size-1个字符,有多少字符读多少字符,最后自动补’\0’
- 当读取到’\n’时,停止读取内容,再次调用fgets之后从下一行起始位置开始继续读取
fputs
头文件:
#include <stdio.h>
函数声明:
int fputs(const char *s, FILE *stream);
功能: 向文件中写入一定长度的字符串
参数:
const char *s:向文件中写入的字符串首地址
FILE *stream:流指针,指向目标文件
返回值:
成功:输入字符个数
失败:返回EOF
fread
头文件:
#include <stdio.h>
函数声明:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能: 从指定文件中读取内容
参数:
void *ptr:存放读取内容的首地址
size_t size:读取一个数据元素的字节大小,一次读多少字节
size_t nmemb:读取的元素个数
FILE *stream:流指针,指向目标文件
返回值:
成功:读取到的文件个数,读到文件末尾返回0
失败:返回EOF
fwrtie
头文件:
#include <stdio.h>
函数声明:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能: 向文件中写入内容
参数:
void *ptr:向文件中写入内容的首地址
size_t size:写入的一个数据元素的字节大小,一次写多少字节
size_t nmemb:写入的元素个数
FILE *stream:流指针,指向目标文件
返回值:
成功:返回写入数据元素的个数
失败:返回EOF
rewind
头文件:
#incldue <stdio.h>
函数声明:
void rewind (FILE *stream);
功能: 将文件指针移动到文件开头
参数: FILE *stream:流指针,指向目标文件
返回值: 空
ftell
头文件:
#include <stdio.h>
函数声明:
long ftell(FILE *stream);
功能: 计算文件指针相对于文件开头的字节数
参数: FILE *stream:流指针,指向目标文件
返回值:
成功:返回文件指针所在位置
失败:返回EOF,更新errno
fseek
头文件:
#include <stdio.h>
函数声明:
int fseek(FILE *stream, long offset, int whence);
功能: 偏移文件指针的位置
参数:
FILE *stream:目标文件
long offset:偏移量,向后为正方向
int whence:相对位置
返回值:
成功:返回0
失败:返回EOF,更新errno
使用注意事项:
宏名 | 相对位置 |
---|---|
SEEK_SET | 文件开头 |
SEEK_CUR | 当前位置 |
SEEK_END | 文件结尾 |
fflush
头文件:
#include <stdio.h>
函数声明:
int fflush(FILE* stream);
功能: 强制刷新缓存区
参数: FILE* stream:指向文件,NULL时刷新所有流
返回值:
成功:返回0
失败:返回EOF,更新errno
fprintf
头文件:
#include <stdio.h>
函数声明:
int fprintf(FILE *stream, const char *format, ...);
功能: 向指定文件中以指定格式写入数据
参数:
FILE *stream:流指针,指向目标文件
const char *format:指定的格式
……:多个参数
返回值:
成功:返回输出字符个数
失败:返回EOF
使用注意事项: 用法上同printf
,只是多了一个指向文件的指针
perror
头文件:
#include <stdio.h>
函数声明:
void perror(const char *s);
功能: 根据errno获取错误信息,将信息输出到终端
参数: const char *s:提示内容
返回值: 无
文件IO
文件IO用到的头文件
- 纯享版
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unsitd.>
头文件对应的函数
#include <sys/types.h> // open/lseek
#include <sys/stat.h> // open
#include <fcntl.h> // open
#include <unsitd.h> // close/read/write/lseek
open
头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数声明:
int open(const char *pathname, int flags);
功能: 打开文件
参数:
const char *pathname:文件路径
int flags:打开方式
返回值:
成功:返回文件描述符
失败:返回EOF
使用注意事项:
- 文件打开方式对应的操作
文件打开方式 | 对应权限 |
---|---|
O_RDONLY | 只读 |
O_WRONLY | 只写 |
O_RDWR | 可读可写 |
O_CREAT | 创建 |
O_TRUNC | 清空 |
O_APPEND | 追加 |
- 当参数
int flags
为O_CREAT(创建)时,函数定义改变
int open(const char *pathname, int flags, mode_t mode);
mode:创建文件的权限,权限的算法:mode &~umask
umask:文件权限掩码,值为0002
权限掩码修改:查看权限掩码:umask 修改文件权限掩码:umask 0000 修改后的权限掩码可以与mode保持一致
close
头文件:
#include <unsitd.h>
函数声明:
int close(int fd);
功能: 关闭文件
参数: 文件描述符
返回值:
成功:0
失败:-1
read
头文件:
#include <unsitd.h>
函数声明:
ssize_t read(int fd, void *buf, size_t count);
功能: 读文件
参数:
int fd:文件描述符
void *buf:存放内容的首地址
size_t count:期待读取的字符个数
返回值:
成功:返回实际读取到的字符个数,读到文件结尾返回0
失败:返回EOF,更新errno
使用注意事项:
- read读文件时count是多少就读多少,不会自动补‘\0’,遇到\n也不会自动停止,会继续读取下一行的内容。所以在使用时,需要人为预留下\0的位置
- 通过返回值作为实际读到的字符个数
char *buf[32] = {};
ssizeo_t ret = read(fd,buf,31);
buf[ret] = '\0';
- 每次读取到的内容放到数组之前先清空数组
memset(buf, 0, sizeof(char)*32);
bzero(buf, sizeof(char)*32);
write
头文件:
#include <unistd.h>
函数声明:
ssize_t write(int fd, const void *buf, size_t count);
功能: 写文件
参数:
int fd:文件描述符
void *buf:写入内容的首地址
size_t count:期待写入的字符个数
返回值:
成功:返回实际写入的字符个数
失败:失败返回EOF,并更新errno
使用注意事项: “ 读多少写多少 “ 代码模型
ssize_t ret = read(fd1, buf, 64);
write(fd2, buf, ret);
数组不需要清空,也不需要预留 ’ \0 ’ 的位置
lseek
头文件:
#include <sys/types.h>
#include <unistd.h>
函数声明:
off_t lseek(int fd, off_t offset, int whence);
功能: 将文件指针偏移到指定位置
参数:
fd:文件描述符
offset:偏移量:向后为正方向
whence:相对位置
返回值:
成功:返回基于文件开头的当前位置,即文件长度,单位为字节
失败:返回EOF,更新errno
使用注意事项:
宏名 | 相对位置 |
---|---|
SEEK_SET | 文件开头 |
SEEK_CUR | 当前位置 |
SEEK_END | 文件结尾 |
目录IO
目录IO用到的头文件
- 纯享版
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
- 头文件对应的函数
#include <sys/types.h> // opendir/closedir/stat
#include <dirent.h> // opendir/closedir/readdir
#include <unistd.h> // chdir/stat
#include <sys/stat.h> // stat
opendir
头文件:
#include <sys/types.h>
#include <dirent.h>
函数声明:
DIR *opendir(const char *name);
功能: 打开目录文件
参数: 目录流,指向打开的目录文件
返回值:
成功:返回目录流指针
失败:返回NULL,更新errno
closedir
头文件:
#include <sysy/types.h>
#include <dirent.h>
函数声明:
int closedir(DIR *dirp);
功能: 关闭目录文件
参数: 目录流,指向打开的目录文件
返回值:
成功:返回0
失败:返回EOF,更新errno
readdir
头文件:
#include <dirent.h>
函数声明:
struct dirent *readdir(DIR *dirp);
功能: 读取目录文件内容
参数: 目录流,指向打开的目录文件
返回值:
成功:返回结构体指针,读到文件结尾返回NULL
失败:返回NULL
使用注意事项:
结构体
struct dirent
{ino_t dino; // 文件的inodeoff_t d_off;unsigned short d_reclen;unsigned char d_type; //文件类型,并不支持所有文件类型char d_name[256]; // 文件名
};
chdir
头文件:
#include <unistd.h>
函数声明:
int chdir(const char* path);
功能: 改变当前的工作路径
参数: const char* path:修改之后的路径
返回值:
成功:返回0
失败:返回EOF,更新errno
使用注意事项:
- 只有程序走到该函数之后,工作路径才会改变,后续的操作都是在修改之后的路径下实现的
stat
头文件:
#include <sysy/types.h>
#include <sys/stat.h>
#include <unistd.h>
函数声明:
int stat(const char *pathname, struct stat *buf);
功能: 获取文件属性
参数:
const char *pathname:文件
struct stat *buf:获取到属性存放的位置
返回值:
成功:返回0
失败:返回EOF,更新errno
使用注意事项:
buf的结构体内容如下
struct stat
{dev_t st_dev; // 包含文件的设备IDino_t st_ino; // 文件的inode号mode_t st_mode; // 文件的类型和权限nlink_t st_nlink; // 硬链接数uid_t st_uid; // 用户IDgid_t st_gid; // 组IDdev_t st_rdev;off_t st_size; //大小blksize_t st_blksize; // 文件系统IO块的大小blkcnt_t st_blocks; // 512b的分配数量struct timespec st_atim; // 最后一次访问的时间struct timespec st_mtim; // 最后一次修改的时间struct timespec st_ctim; // 最后一次状态改变的时间
}
- 基本用法
获取文件的inode号
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>int main()
{// 定义变量DIR* dirp = NULL;struct stat sb = {};struct dirent *dir = NULL;// 打开文件dirp = opendir("./");if(dirp == NULL){perror("opendir err");return EOF;}// 读取文件dir = readdir(dirp);// stat获取inode号stat(dir->name, &sb);printf("%s inode is %ld\n", dir->name, sb->st_ino);closedir(dirp);return 0;
}
- 获取文件类型
查询 man 7 inode可以得到对于文件类型定义了以下8进制掩码
宏名 | 掩码值 | 文件类型 |
---|---|---|
S_IFMT | 0170000 | 判断文件类型 |
S_IFSOCK | 0140000 | socket—套接字 |
S_IFLNK | 0120000 | symbolic link—连接文件 |
S_IFREG | 0100000 | regular file —普通文件 |
S_IFBLK | 0060000 | block device — 块设备文件 |
S_IFDIR | 0040000 | directory — 目录文件 |
S_IFCHR | 0020000 | character—字符设备文件 |
S_IFIFO | 0010000 | FIFO—管道文件 |
- 先通过stat获取8进制的mode
stat(dir->name, &sb);
printf("mode is %o",sb.st_mode);
- 掩码的使用
if((sb.st_mode & S_IFMT) == S_IFREG)printf("普通文件");
- man手册里还写了另一种宏名写法
宏名 | 判断文件类型 |
---|---|
S_ISREG(mode) | regular file—普通文件 |
S_ISDIR(mode) | directory—目录文件 |
S_ISCHR(mode) | character device—字符设备文件 |
S_ISBLK(mode) | block device—块设备文件 |
S_ISFIFO(mode) | FIFO—管道文件 |
S_ISLNK(mode) | symbolic link—连接文件 |
S_ISSOCK(mode) | socket—套接字文件 |
if(S_ISREG(sb.st_mode))printf("regular file\n");
- 获取文件权限
对于文件权限,也有相应的掩码
宏名 | 掩码 | 权限 |
---|---|---|
S_IRUSR | 00400 | 用户的读权限 |
S_IWUSR | 00200 | 用户的写权限 |
S_IXUSR | 00100 | 用户的执行权限 |
S_IRGRP | 00040 | 同组的读权限 |
S_IWGRP | 00020 | 同组的写权限 |
S_IXGRP | 00010 | 同组的执行权限 |
S_IROTH | 00004 | 其他用户的读权限 |
S_IWOTH | 00002 | 其他用户的写权限 |
S_IXOTH | 00001 | 其他用户的执行权限 |
if(sb.st_mode & S_IRUSR)printf("r");
- 其他结构体成员的使用
- 通过用户ID获取用户名
struct passwd* user_name = NULL;
user_name = getpwuid(sb.st_uid);
user_name->pw_name;
- 通过组ID获取组名
struct group* gig_name = NULL;
gig_name = getgrgid(sb.st_gid);
gig_name->gr_name;
- 转换时间格式
ctime(sb.st_mtim);
// 将时间转换成为"Wed Jun 30 21:49:08 1993\n"的固定格式
getpwuid
头文件:
#include <pwd.h>
函数声明:
struct passwd* getpwuid(uid_t uid);
功能: 获取用户信息
参数: uid_t uid:用户ID
返回值:
成功:返回结构体地址
失败:NULL
使用注意事项:
用户信息结构体
struct passwd
{char *pw_name; // 用户名char *pw_passwd; // 用户密码uid_t pw_uid; // 用户IDgid_t pw_gid; // 组IDchar *pw_gecos; // 用户信息char *pw_dir; // 家目录char *pw_shell;
};
getgrgid
头文件:
#include <grp.h>
函数声明:
struct group *getgrgid(gid_t gid);
功能: 获取组信息
参数: gid_t gid:组ID
返回值:
成功:返回结构体地址
失败:NULL
使用注意事项:
组信息结构体
struct group
{char *gr_name; // 组名char *gr_passwd; // 组密码gid_t gr_gid; // 组IDchar **gr_mem; // 组内成员
};
时间
time
头文件:
#include <time.h>
函数声明:
time_t time(time_t *tloc);
功能: 获取1970-01-01 00:00:00到现在的秒数
参数: time_t *tloc:获取到的时间的地址
返回值:
成功:返回获取到的时间
失败:返回EOF
使用注意事项: 返回的是秒数,是一个很大的int类型的数据
localtime
头文件:
#include <time.h>
函数声明:
struct tm *localtime(const time_t *timep);
功能: 将time获取的时间转换成结构体中的格式
参数: const time_t *timep:保存时间变量的地址
返回值:
成功:返回结构体地址
失败:返回NULL
使用注意事项:
- localtime的结构体定义如下
struct tm
{int tm_sec; // seconds(0-60)秒int tm_min; // minutes(0-59)分钟int tm_hour; // Hours(0-23)小时int tm_yday; // day in the year(0-365, 1 Jan = 0)天数int tm_wday; // day in the week (0-6, sunday = 0)周int tm_mday; // day in the month (1-31)日期int tm_mon; // month(0-11)月份int tm_year; // year-1900年份
}
- 年份在计算时-掉了1900,所以在输出的时候要+1900
ctime
头文件:
#include <time.h>
函数声明:
char *ctime(const time_t *timep);
功能: 将时间转换成固定格式
参数: const time_t *timep:保存时间变量的地址
返回值:
成功:返回转换后地址
失败:返回NULL
使用注意事项:
将时间转换成为"Wed Jun 30 21:49:08 1993\n"的固定格式