在 Linux 系统编程中,文件与目录操作是我们和系统交互的核心能力,而时间接口则是处理日志、定时任务等场景的基础。今天,我们就来系统梳理这些关键知识点,帮你建立完整的知识体系。
一、文件 IO
1、文件IO与标准IO的区别:
标准IO有缓存的
文件IO没有缓存
标准IO是库函数
文件IO是系统调用
标准IO适合于处理普通文件
文件IO适合于处理设备文件、通信文件

2、系统调用:
Linux内核中的函数接口
3、库函数:
对系统调用的封装
4、文件IO接口:
(1) open
原型:int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
功能:
打开文件获得操作文件的文件描述符
文件描述符:一个很小的非负整数,内核每打开一个文件就会获得一个文件描述符
句柄 Handle
参数:
pathname:打开文件的路径
flags:
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 文件不存在创建 权限:rwxrwxrwx 421421421 0777 0664(rw-rw-r--)
O_TRUNC 文件存在截断清0
O_EXCL 文件存在报错
O_APPEND 追加
O_ASYNC 异步IO
返回值:
成功返回新的文件描述符
失败返回-1
r O_RDONLY
r+ O_RDWR
w O_WRONLY | O_CREAT | O_TRUNC, 0664
w+ O_RDWR | O_CREAT | O_TRUNC, 0664
a O_WRONLY | O_CREAT | O_APPEND, 0664
a+ O_RDWR | O_CREAT | O_APPEND, 0664
(2) close
原型:int close(int fd);
功能:
关闭文件描述符

(3) write
原型:ssize_t write(int fd, const void *buf, size_t count);
功能:
向文件描述符中写入buf开始的count个字节
参数:
fd:文件描述符
buf:写入数据空间的首地址
count:写入数据的字节数
返回值:
成功返回实际写入的字节数
失败返回-1
----使用示例

(4)read
原型:ssize_t read(int fd, void *buf, size_t count);
功能:
从文件描述符中读取count个字节放入buf开始的空间
参数:
fd:文件描述符
buf:存放数据空间的首地址
count:最多读取的字节数
返回值:
成功返回实际读取字节个数
读到文件末尾返回0
读取出错返回-1
----使用示例

练习:利用read和write文件IO实现图片内容的拷贝

(5)lseek
原型:off_t lseek(int fd, off_t offset, int whence);
功能:
重定位文件描述符的偏移量
参数:
fd:文件描述符
offset:偏移量
whence:
SEEK_SET 文件开头
SEEK_CUR 文件当前位置
SEEK_END 文件末尾
返回值:
成功返回偏移量
失败返回-1
----使用示例

5、系统默认打开三个文件描述符
0:标准输入 -> stdin
1:标准输出 -> stdout
2:标准错误 -> stderr
6、文件描述符的特性
文件描述符有上限限制
新产生的文件描述符总是选择最小且尚未被使用的非负整数
二、目录IO
1、opendir
原型:DIR *opendir(const char *name);
功能:
打开目录获得操作该目录的目录流指针
参数:
name:目录路径
返回值:
成功返回目录流指针
失败返回NULL
2、closedir
原型:int closedir(DIR *dirp);
功能:
关闭目录流指针
参数:
dirp:目录流指针
返回值:
成功返回0
失败返回-1
----使用示例


3、 readdir
原型:struct dirent *readdir(DIR *dirp);
功能:
读取下一个目录项的信息
参数:
dirp:文件流指针
返回值:
成功返回结构体指针
失败或者读到末尾返回NULL
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 */文件名
};
练习:遍历目录

4、mkdir
原型:int mkdir(const char *pathname, mode_t mode);
功能:
创建目录文件,pathname:目录的路径 mode:权限(通常为0777)
掩码:umask
r: 是否能够查看目录项
w: 是否能够在目录中新建文件
x: 是否能够进入目录文件
5、rmdir
原型:int rmdir(const char *pathname);
功能:
删除pathname空目录文件
6、 chdir
原型:int chdir(const char *path);
功能:
切换当前工作的路径
----使用示例

7、 getcwd
原型:char *getcwd(char *buf, size_t size);
功能:
返回当前工作目录的绝对路径
参数:
buf:存放路径空间的首地址
size:最多存放路径的字节数
返回值:
成功返回存放路径空间的首地址
失败返回NULL
三、时间相关接口
1、 time
原型:time_t time(time_t *tloc);
功能:
获得1970-1-1日到现在的秒数
参数:
tloc:存放秒数空间首地址
返回值:
返回1970-1-1到现在的秒数
失败返回-1
2、 localtime
原型:struct tm *localtime(const time_t *timep);
功能:
将timep指向的秒数转换为日历时间(包含时区)
struct tm {
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
3、mktime
原型:time_t mktime(struct tm *tm);
功能:
将日历时间转换为秒数
---使用示例



总结
文件 IO、目录操作和时间接口是 Linux 系统编程的基础,掌握这些知识点不仅能让你更好地理解系统的底层工作原理,也能为后续学习网络编程、进程通信等高级内容打下坚实的基础。