文章目录
1. 文件IO
标准IO:
- ANSIC(美国国家学会)
- 文件流指针操作文件
- 有缓冲区
- 高级IO
- 适用于普通文件
- 标准I0较少系统调用的次数(先缓冲区—系统调用)
- c库
- 标准I0是在文件IO的基础上封装了缓冲机制;
文件IO
- posix 标准
- 文件描述符
- 无缓冲
- 低级IO
- 适用于特殊文件
- 每次调用文件IO必然发生系统调用
- 系统调用的API
open()
read()
write()
close()
lseek()
打开文件open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
/*
功能: 打开一个已经存在的文件;
参数:
pathname: 文件名
flags: 打开方式
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
返回值: 成功返回一个文件描述符,失败返回-1并设置错误号;
文件描述符是一个非负整数,顺序分配,用来标识文件;
系统默认打开三个文件描述符:
0 标准输入 stdin
1 标准输出 stdout
2 标准错误 stderr
*/
int open(const char *pathname, int flags, mode_t mode);
/*
功能:打开文件,如果文件不存在则创建;
参数:
pathname:文件路径名
flags:打开方式和控制选项
- 例如:O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND 等
mode:文件权限设置(仅当使用O_CREAT选项时有效)
- 用八进制表示,例如0777
- 最终权限计算方式:mode & ~umask
返回值:成功返回文件描述符,失败返回-1并设置errno;
注意:创建文件时,必须与O_CREAT选项一起使用,并且需要提供第三个参数mode。
*/
打开一个文件
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_RDWR | O_CREAT, 0666);
if (fd < 0) {
perror("open");
return -1;
}
printf("打开文件成功......\n");
printf("fd = %d\n", fd);
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_RDWR); // 以读写方式打开文件"test.txt"
if (fd < 0) {
perror("open"); // 如果打开失败,打印错误信息
return 1; // 返回错误码1
}
printf("文件成功打开\n");
close(fd); // 关闭文件描述符
return 0; // 返回成功
}
文件的关闭close
#include <unistd.h>
int close(int fd);
/*
功能:关闭已打开的文件描述符;
参数:
fd:文件描述符
返回值:成功返回0,失败返回-1并设置errno;
*/
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_RDWR);
if (fd < 0) {
perror("open");
return -1;
}
printf("文件打开成功\n");
close(fd);
return 0;
}
文件的读取read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
{
/*
功能:从一个打开的文件读取内容;
参数:
fd:文件描述符
buf:存储读取内容的缓冲区
count:要读取的字节数
返回值:实际读取的字节数,读到文件末尾返回0,如果出错则返回-1并设置errno;
*/
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char buffer[100]; // 用于存储读取的内容的缓冲区
int fd = open("test.txt", O_RDONLY); // 打开文件test.txt以读取方式
if (fd < 0) {
perror("open");
return -1;
}
ssize_t num_bytes_read = read(fd, buffer, sizeof(buffer)); // 读取文件内容到缓冲区
if (num_bytes_read < 0) {
perror("read");
close(fd);
return -1;
}
printf("读取的内容:%s\n", buffer); // 打印读取的内容
close(fd);
return 0;
}
读取文件的前十个字节并输出到终端
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFFER_SIZE 10
int main() {
char buffer[BUFFER_SIZE + 1]; // 用于存储读取的内容的缓冲区,多一个字节用于存储字符串结尾的'\0'
int fd = open("test.txt", O_RDONLY); // 打开文件test.txt以读取方式
if (fd < 0) {
perror("open");
return -1;
}
ssize_t num_bytes_read = read(fd, buffer, BUFFER_SIZE); // 读取文件的前十个字节到缓冲区
if (num_bytes_read < 0) {
perror("read");
close(fd);
return -1;
}
buffer[num_bytes_read] = '\0'; // 添加字符串结尾的'\0'
printf("文件的前十个字节:%s\n", buffer); // 打印读取的内容
close(fd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("test.txt", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
printf("文件打开成功......\n");
printf("文件描述符 = %d\n", fd);
char buf[32] = {0}; // 初始化缓冲区
// 读取文件的内容
int ret = read(fd, buf, 10);
if (ret < 0) {
perror("read");
return 1;
} else if (ret == 0) {
printf("已读取到文件末尾\n");
return 1;
}
printf("实际读取的字节数 = %d\n", ret);
printf("读取的内容:%s\n", buf);
close(fd);
return 0;
}
文件的写入(输出)write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
/*
功能:向一个打开的文件写入内容;
参数:
fd:文件描述符
buf:保存要写入的数据的空间首地址
count:预计要写入的字节数
返回值:实际写入的字节数,如果出错则返回-1并设置errno
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char buf[32] = {0};
printf(">:\n");
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n') {
buf[strlen(buf) - 1] = '\0';
}
// 如果文件不存在则创建并以写的方式打开,如果文件存在则以写的方式打开并清空文件内容
int fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd < 0) {
perror("open");
return 1;
}
// 将buf里的数据写入到文件当中
write(fd, buf, sizeof(buf));
close(fd);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char buf[32];
// 提示用户输入内容
printf(">:\n");
// 从标准输入读取用户输入的内容
fgets(buf, sizeof(buf), stdin);
// 检查是否读取到了换行符,如果是,则将其替换为字符串结束符
if (buf[strlen(buf) - 1] == '\n') {
buf[strlen(buf) - 1] = '\0';
}
// 打开或创建文件test.txt,以写的方式打开并清空文件内容
int fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd < 0) {
perror("open");
return -1;
}
// 将用户输入的内容写入到文件中
write(fd, buf, strlen(buf));
// 关闭文件
close(fd);
// 重新打开文件以读取数据
fd = open("test.txt", O_RDONLY);
if (fd < 0) {
perror("open");
return -1;
}
// 定义一个缓冲区用于读取文件中的数据
char data[32] = {0};
// 读取文件中的数据
int ret = read(fd, data, sizeof(data));
if (ret < 0) {
perror("read");
return -1;
} else if (ret == 0) {
printf("读取到文件的末尾\n");
return -1;
}
// 输出读取到的文件中的数据
printf("data: %s\n", data);
return 0;
}
文件的定位lseek
#include <sys/types.h>
off_t lseek(int fd, off_t offset, int whence);
/*
功能:实现对文件的定位。
参数:
fd:文件描述符。
offset:偏移量,可以为正数或负数,表示相对于 whence 参数的偏移量。
whence:指定偏移量的基准位置。
- SEEK_SET:从文件开头开始计算偏移量。
- SEEK_CUR:从当前文件指针位置开始计算偏移量。
- SEEK_END:从文件末尾开始计算偏移量。
返回值:返回文件指针相对于文件开头的偏移量,如果出错则返回-1并设置errno。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
char buf[32];
// 提示用户输入内容
printf(">:\n");
// 从标准输入读取用户输入的内容
fgets(buf, sizeof(buf), stdin);
// 检查是否读取到了换行符,如果是,则将其替换为字符串结束符
if (buf[strlen(buf) - 1] == '\n') {
buf[strlen(buf) - 1] = '\0';
}
// 打开或创建文件 test.txt,以读写的方式打开并清空文件内容
int fd = open("test.txt", O_CREAT | O_RDWR | O_TRUNC, 0666);
if (fd < 0) {
perror("open");
return -1;
}
// 将 buf 里的数据写入到文件中
write(fd, buf, strlen(buf));
// 将文件内部指针指向开头
if (-1 == lseek(fd, 0, SEEK_SET)) {
perror("lseek");
return -1;
}
// 重新定义一个缓冲区用于读取文件中的数据
char data[32] = {0};
// 读取文件中的数据
int ret = read(fd, data, sizeof(data));
if (ret < 0) {
perror("read");
return -1;
}
// 输出读取到的文件中的数据
printf("data: %s\n", data);
return 0;
}
目录
目录的打开
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
/*
功能:打开目录。
参数:
name:目录路径。
返回值:成功打开目录则返回一个指向目录的指针(DIR 类型),失败则返回 NULL,并设置 errno。
*/
#include <stdio.h>
#include <dirent.h>
int main() {
// 打开目录
DIR *dir = opendir(".");
// 检查目录是否成功打开
if (dir == NULL) {
perror("opendir");
return -1;
}
// 读取目录中的内容
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
// 关闭目录
closedir(dir);
return 0;
}
目录的关闭
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
/*
功能:关闭目录流指针。
参数:
dirp:目录流指针。
返回值:成功关闭目录流指针则返回0,失败返回-1,并设置 errno。
*/
#include <stdio.h>
#include <dirent.h>
int main() {
// 打开目录
DIR *dir = opendir(".");
// 检查目录是否成功打开
if (dir == NULL) {
perror("opendir");
return -1;
}
// 读取目录中的内容
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
// 关闭目录
if (closedir(dir) == -1) {
perror("closedir");
return -1;
}
return 0;
}
获取目录里的文件
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
/*
功能:读取目录中的内容。
参数:
dirp:目录流指针。
返回值:成功读取到目录中的下一个目录项则返回一个指向该目录项的指针(`struct dirent *` 类型),如果到达目录末尾或者出错则返回 NULL。
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h> // 包含 DIR 结构体和 opendir 函数的头文件
int main(int argc, char *argv[]) {
// 检查命令行参数是否正确
if (argc != 2) {
printf("Usage: %s dirname\n", argv[0]); // 正确的格式为:程序名 目录名
return -1;
}
// 打开目录
DIR *dirp = opendir(argv[1]);
if (dirp == NULL) {
perror("opendir"); // 打印出错信息
return -1;
}
// 读取目录
struct dirent *dp;
while ((dp = readdir(dirp)) != NULL) {
printf("%s\n", dp->d_name); // 输出每个目录项的名称
}
// 关闭目录
closedir(dirp);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h> // 包含 DIR 结构体和相关函数的头文件
int main(int argc, char *argv[]) {
// 检查命令行参数是否正确
if (argc != 2) {
printf("Usage: %s dirname\n", argv[0]); // 正确的格式为:程序名 目录名
return -1;
}
// 打开目录
DIR *dirp = opendir(argv[1]);
if (dirp == NULL) {
perror("opendir"); // 打印出错信息
return -1;
}
// 读取目录中的内容并输出
struct dirent *dp;
while ((dp = readdir(dirp)) != NULL) {
// 检查目录项名称是否以点开头,如果是则跳过
if (dp->d_name[0] == '.') {
continue;
}
printf("%s\n", dp->d_name); // 输出每个目录项的名称
}
// 关闭目录
closedir(dirp);
return 0;
}
1. 实现文件的拷贝,并加入命令行参数
#include <stdio.h>
int main(int argc, char *argv[]) {
// 检查命令行参数是否正确
if (argc != 3) {
printf("Usage: %s source_file destination_file\n", argv[0]);
return -1;
}
// 打开源文件
FILE *source_file = fopen(argv[1], "r");
if (source_file == NULL) {
perror("fopen source_file");
return -1;
}
// 打开目标文件
FILE *destination_file = fopen(argv[2], "w");
if (destination_file == NULL) {
perror("fopen destination_file");
fclose(source_file);
return -1;
}
// 逐字符读取源文件,并写入目标文件
int ch;
while ((ch = fgetc(source_file)) != EOF) {
fputc(ch, destination_file);
}
// 关闭文件
fclose(source_file);
fclose(destination_file);
printf("File copied successfully.\n");
return 0;
}
2. 实现文件的加密和解密
#include <stdio.h>
void encrypt_decrypt_file(const char *input_file, const char *output_file, int key) {
FILE *input = fopen(input_file, "r");
FILE *output = fopen(output_file, "w");
if (input == NULL || output == NULL) {
perror("fopen");
return;
}
int ch;
while ((ch = fgetc(input)) != EOF) {
ch += key; // 加密或解密操作,加密时 key 为正,解密时 key 为负
fputc(ch, output);
}
fclose(input);
fclose(output);
}
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("Usage: %s input_file output_file key\n", argv[0]);
return -1;
}
const char *input_file = argv[1];
const char *output_file = argv[2];
int key = atoi(argv[3]); // 将命令行参数转换为整数
encrypt_decrypt_file(input_file, output_file, key);
printf("Operation completed successfully.\n");
return 0;
}