目录
一、基础IO
1. C语言文件读写
2. 标志位传参
3. C语言与系统调用关系
二、文件系统
1. 文件描述符
2. 输入输出重定向
文件调用
#include
#include
#include
#include
int main()
{
//FILE* pf = fopen("test.txt", "w");
//FILE* pf = fopen("test.txt", "a");
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
exit(errno);
}
//w
// int cnt = 5;
// while (cnt--)
// fprintf(pf, "%s\n", "hello world -- write");
//a
// int cnt = 5;
// while (cnt--)
// fprintf(pf, "%s\n", "append");
//r
char buffer[64];
while (fgets(buffer, sizeof(buffer) - 1, pf))
{
buffer[strlen(buffer) - 1] = 0;
printf("%s\n", buffer);
}
return 0;
}
#include
#define ONE (1 << 1)
#define TWO (1 << 2)
#define THREE (1 << 3)
#define FOUR (1 << 4)
void Show(int flag)
{
if (flag & ONE)
printf("one\n");
if (flag & TWO)
printf("two\n");
if (flag & THREE)
printf("three\n");
if (flag & FOUR)
printf("four\n");
}
void ShowTest()
{
Show(ONE);
printf("-----------\n");
Show(TWO);
printf("-----------\n");
Show(TWO | THREE);
printf("-----------\n");
Show(TWO | THREE | FOUR);
}
int main()
{
ShowTest();
return 0;
}
#include
#include
#include
#include
#include
int main()
{
umask(0); //只修改当前进程的umask
//int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
//int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
int fd = open("test.txt", O_RDONLY);
if (fd < 0)
{
perror("open");
return 1;
}
//写/追加
// int cnt = 5;
// char outBuffer[64] = {0};
// while (cnt--)
// {
// sprintf(outBuffer, "%s: %d\n", "hello --- a", cnt);
// write(fd, outBuffer, strlen(outBuffer));
// }
//读
char buffer[1024];
ssize_t num = read(fd, buffer, sizeof(buffer) - 1);
if (num > 0)
{
buffer[num] = 0;
}
printf("%s", buffer);
return 0;
}
在Linux中,一切皆文件,不仅普通的文件和目录,块设备、管道、socket等等,都是由文件系统管理的。在Linux中的文件系统会给每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),它们都主要是被用来记录文件的元信息和目录层次结构。
文件描述符(file descripter)FD:Linux内容默认情况下一个进程只能打开1024个文件,内核为了管理进程,当一个进程打开了哪些文件,内核就会维护一个表,这个表就会记录这个进程打开了哪些文件,然后给每个文件进行编号,这个编号就叫文件描述符(句柄),默认文件描述符的范围为0-1023。
三个标准输入输出流:
FILE ----> 结构体
文件描述符表:struct file* fd_array[]
文件分配规则:寻找最小且没被占用的下标
#include
#include
#include
#include
#include
#define TEST_FILE(number) "test"#number
int main()
{
umask(0);
printf("stdin ---> fd : %d\n", stdin->_fileno); //0
printf("stdout ---> fd : %d\n", stdout->_fileno); //1
printf("stderr ---> fd : %d\n", stderr->_fileno); //2
//close(0);
//close(2);
close(1); //关闭文件描述符对应下标的文件
//关闭文件描述符表的 1 后, fd0 会被分配到 1 的位置,也就是原本stdout的位置
//而原本输出到stdout的数据,会写入 fd0 中
int fd0 = open(TEST_FILE(0), O_WRONLY | O_CREAT | O_APPEND, 0666);
int fd1 = open(TEST_FILE(1), O_WRONLY | O_CREAT | O_APPEND, 0666);
int fd2 = open(TEST_FILE(2), O_WRONLY | O_CREAT | O_APPEND, 0666);
int fd3 = open(TEST_FILE(3), O_WRONLY | O_CREAT | O_APPEND, 0666);
printf("fd : %d\n", fd0);
printf("fd : %d\n", fd1);
printf("fd : %d\n", fd2);
printf("fd : %d\n", fd3); //fd分配规则,寻找最小的且没被占用的下标
fprintf(stdout, "fd : %d\n", fd3); //打印到 f0 对应的文件
fflush(stdout);
close(fd0);
close(fd1);
close(fd2);
close(fd3);
return 0;
}
int dup2(int old_fd, int new_fd)
重定向:将新的文件文件描述符充当老的文件描述符的一份拷贝(old_fd内容 拷贝到 new_fd内容)
上层的fd不变,在内核中更改fd对应的struct file*地址
#include
#include
#include
#include
#include
int main()
{
umask(0);
//int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
//int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
int fd = open("test.txt", O_RDONLY);
if (fd < 0)
{
perror("open");
return 1;
}
//输出重定向
// dup2(fd, 1);
// printf("open fd: %d\n", fd);
// fprintf(stdout, "open fd: %d\n", fd);
// const char* msg = "hello world\n";
// write(1, msg, strlen(msg));
// fflush(stdout);
//输入重定向
dup2(fd, 0);
char line[1024];
while (1)
{
printf("> ");
if (fgets(line, sizeof(line) - 1, stdin) == NULL)
break;
printf("%s", line);
}
close(fd);
return 0;
}