目录
[1 文件IO编程基础](#1 文件IO编程基础)
[1.1 文件IO与标准IO的区别](#1.1 文件IO与标准IO的区别)
[1.2 文件描述符概念](#1.2 文件描述符概念)
[2 文件IO核心函数详解](#2 文件IO核心函数详解)
[2.1 文件打开函数open](#2.1 文件打开函数open)
[2.2 文件关闭函数close](#2.2 文件关闭函数close)
[2.3 文件写入函数write](#2.3 文件写入函数write)
[2.4 文件读取函数read](#2.4 文件读取函数read)
[2.5 文件定位函数lseek](#2.5 文件定位函数lseek)
[3 文件IO实战应用](#3 文件IO实战应用)
[3.1 图片文件拷贝示例](#3.1 图片文件拷贝示例)
[3.2 文件大小统计程序](#3.2 文件大小统计程序)
[4 目录IO编程](#4 目录IO编程)
[4.1 目录操作核心函数](#4.1 目录操作核心函数)
[4.1.1 打开目录opendir](#4.1.1 打开目录opendir)
[4.1.2 关闭目录closedir](#4.1.2 关闭目录closedir)
[4.1.3 读取目录项readdir](#4.1.3 读取目录项readdir)
[4.2 目录创建与删除](#4.2 目录创建与删除)
[4.2.1 创建目录mkdir](#4.2.1 创建目录mkdir)
[4.2.2 删除目录rmdir](#4.2.2 删除目录rmdir)
[4.3 目录遍历实战示例](#4.3 目录遍历实战示例)
[4.4 工作目录操作](#4.4 工作目录操作)
[4.4.1 切换工作目录chdir](#4.4.1 切换工作目录chdir)
[4.4.2 获取当前目录getcwd](#4.4.2 获取当前目录getcwd)
[5 时间相关接口](#5 时间相关接口)
[5.1 时间获取函数](#5.1 时间获取函数)
[5.1.1 获取当前时间time](#5.1.1 获取当前时间time)
[5.1.2 时间转换localtime](#5.1.2 时间转换localtime)
[5.1.3 时间生成mktime](#5.1.3 时间生成mktime)
1 文件IO编程基础
1.1 文件IO与标准IO的区别
文件IO(文件输入输出)是Linux系统编程中直接使用系统调用的IO方式,与标准IO相比具有以下特点:
核心差异:
-
缓存机制:文件IO无缓存,标准IO有缓存
-
函数类型:文件IO是系统调用,标准IO是库函数
-
适用场景:文件IO适合设备文件、通信文件,标准IO适合普通文件
-
性能特点:文件IO实时性强,标准IO效率高
系统调用与库函数关系:
-
系统调用:Linux内核提供的底层接口
-
库函数:对系统调用的封装,提供更友好的接口
1.2 文件描述符概念
文件描述符是Linux内核为每个打开文件分配的唯一标识符,是一个非负整数。系统默认打开三个文件描述符:
-
0:标准输入(stdin)
-
1:标准输出(stdout)
-
2:标准错误(stderr)
文件描述符特性:
-
有上限限制(可通过ulimit -n查看)
-
新描述符选择最小未使用的非负整数
-
进程结束时自动关闭所有打开的文件描述符
2 文件IO核心函数详解
2.1 文件打开函数open
cpp
#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);
参数说明:
-
pathname:文件路径
-
flags:打开标志位
-
mode:文件权限(创建文件时使用)
常用flags标志:
cpp
O_RDONLY // 只读
O_WRONLY // 只写
O_RDWR // 读写
O_CREAT // 文件不存在则创建
O_TRUNC // 文件存在则截断清空
O_APPEND // 追加模式
O_EXCL // 与O_CREAT配合,文件存在则报错
权限模式示例:
cpp
0664 // rw-rw-r--
0777 // rwxrwxrwx
open与fopen模式对应关系:
cpp
"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.2 文件关闭函数close
cpp
#include <unistd.h>
int close(int fd);
关闭文件描述符,释放系统资源。成功返回0,失败返回-1。
2.3 文件写入函数write
cpp
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
参数说明:
-
fd:文件描述符
-
buf:写入数据缓冲区
-
count:要写入的字节数
返回值:
-
成功:实际写入的字节数
-
失败:-1
2.4 文件读取函数read
cpp
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
参数说明:
-
fd:文件描述符
-
buf:读取数据缓冲区
-
count:最大读取字节数
返回值:
-
成功:实际读取的字节数
-
文件末尾:0
-
失败:-1
2.5 文件定位函数lseek
cpp
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
whence参数:
cpp
SEEK_SET // 文件开头
SEEK_CUR // 当前位置
SEEK_END // 文件末尾
特殊用法:
cpp
lseek(fd, 0, SEEK_END); // 获取文件大小
lseek(fd, 0, SEEK_SET); // 回到文件开头
3 文件IO实战应用
3.1 图片文件拷贝示例
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
int fp1 = 0;
int fp2 = 0;
char tmpbuff[1024] = {0};
ssize_t nret = 0;
fp1 = open("ssr.bmp",O_RDONLY);
if(-1 == fp1)
{
perror("fail to open");
return -1;
}
fp2 = open("dst.bmp",O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(-1 == fp1)
{
perror("fail to open");
return -1;
}
while (1)
{
nret = read(fp1,tmpbuff,sizeof(tmpbuff));
if(nret == 0)
{
break;
}
write(fp2,tmpbuff,nret);
}
return 0;
}
3.2 文件大小统计程序
cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int main() {
int fd;
char filename[256];
off_t file_size;
printf("请输入文件路径: ");
scanf("%s", filename);
// 打开文件
fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("文件打开失败");
return -1;
}
// 获取文件大小
file_size = lseek(fd, 0, SEEK_END);
if (file_size == -1) {
perror("获取文件大小失败");
close(fd);
return -1;
}
printf("文件大小: %ld 字节 (%.2f KB)\n",
file_size, (double)file_size / 1024);
close(fd);
return 0;
}
4 目录IO编程
4.1 目录操作核心函数
4.1.1 打开目录opendir
cpp
#include <dirent.h>
DIR *opendir(const char *name);
4.1.2 关闭目录closedir
cpp
#include <dirent.h>
int closedir(DIR *dirp);
4.1.3 读取目录项readdir
cpp
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
dirent结构体重要成员:
cpp
ino_t d_ino; // 索引节点号
char d_name[256]; // 文件名
4.2 目录创建与删除
4.2.1 创建目录mkdir
cpp
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
目录权限说明:
-
读权限(r):查看目录项
-
写权限(w):在目录中新建/删除文件
-
执行权限(x):进入目录
4.2.2 删除目录rmdir
cpp
#include <unistd.h>
int rmdir(const char *pathname);
只能删除空目录。
4.3 目录遍历实战示例
cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
int main(void)
{
DIR *dp = NULL;
struct dirent *pp = NULL;
dp = opendir(".");
if (NULL == dp)
{
perror("fail to opendir");
return -1;
}
while(1)
{
pp = readdir(dp);
if (NULL == pp)
{
break;
}
if (pp->d_name[0] == '.')
{
continue;
}
printf("%s\n", pp->d_name);
}
closedir(dp);
return 0;
}
4.4 工作目录操作
4.4.1 切换工作目录chdir
cpp
#include <unistd.h>
int chdir(const char *path);
4.4.2 获取当前目录getcwd
cpp
#include <unistd.h>
char *getcwd(char *buf, size_t size);
使用示例:
cpp
#include <stdio.h>
#include <unistd.h>
int main() {
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("当前工作目录: %s\n", cwd);
} else {
perror("获取当前目录失败");
}
// 切换目录
if (chdir("/tmp") == 0) {
printf("成功切换到 /tmp 目录\n");
} else {
perror("切换目录失败");
}
return 0;
}
5 时间相关接口
5.1 时间获取函数
5.1.1 获取当前时间time
cpp
#include <time.h>
time_t time(time_t *tloc);
返回1970年1月1日至今的秒数。
5.1.2 时间转换localtime
cpp
#include <time.h>
struct tm *localtime(const time_t *timep);
tm结构体成员:
cpp
int tm_sec; // 秒 [0-59]
int tm_min; // 分 [0-59]
int tm_hour; // 时 [0-23]
int tm_mday; // 日 [1-31]
int tm_mon; // 月 [0-11]
int tm_year; // 年(从1900开始)
int tm_wday; // 星期 [0-6]
int tm_yday; // 年内天数 [0-365]
int tm_isdst; // 夏令时标志
5.1.3 时间生成mktime
cpp
#include <time.h>
time_t mktime(struct tm *tm);