linux+c 基本文件操作笔记
标准与API
ISO C标准 文件指针
#include<stdio.h>
FILE* fopen(filename, "r/w”);
fread()
fwrite()
fseek()
ftellp()
fclose(fp)
stderr是文件指针, stdio.h 头文件
UNIX C标准 文件描述符
#include<unistd.h>
#inclucde<sys/type.h>
#include<sys/stat.h>
#include<fcntl.h>
int fd = open(filename, flag, ?)
write(fd, buf, len)
read(fd, buf, len)
close(fd)
offset_t lseek(fd, offset_t, flag)
int newfd = dup(oldfd)
int dup2(oldfd, newfd)
STDERR_FILENO int unistd.h
文件描述符&系统文件表&内存索引节点表
https://blog.csdn.net/cws1214/article/details/8086789
- 每个open函数对应一个文件描述符,每个文件描述符有自己的偏移变量
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
int main()
{
//123456
char buf[1024] = {0};
int f1_1 = open("./1.txt", O_RDWR, 0);
if(f1_1<0)
{
perror("open failed! 1");
}
write(f1_1, "ab", 2);
//zt3456
int f1_2 = open("./1.txt", O_RDWR, 0);
if(f1_2<0)
{
perror("open failed! 2");
}
memset(buf, 0, 1024);
read(f1_2, buf, 1024);
printf("*%s*\n",buf); //*ab3456*
memset(buf, 0, 1024);
read(f1_1, buf, 1024); //读字符串,读到\0就停止
printf("*%s*\n",buf); //*3456*
int f1_3 = dup(f1_1);
memset(buf, 0, 1024);
read(f1_3, buf, 1024);
printf("*%s*\n",buf); //** //因为f1_1已经读完了,偏移已经到了最后面
write(f1_3, "cd", 2);
//ab3456cd
memset(buf, 0, 1024);
read(f1_1, buf, 1024);
printf("*%s*\n",buf); //** //这里不是cd表示:f1_1与f1_3共享偏移量。
memset(buf, 0, 1024);
read(f1_2, buf, 1024);
printf("*%s*\n",buf); //*cd* //与f1_3和f1_1不共享偏移
memset(buf, 0, 1024);
read(f1_3, buf, 1024);
printf("*%s*\n",buf); //**
//f1_1与f1_3 是否共享偏移量确认测试。 结果表示:共享。 dup只复制数字句柄,指向同一个文件描述符表(进程概念)。
lseek(f1_1, 0, SEEK_SET);
memset(buf, 0, 1024);
read(f1_3, buf, 3);
printf("*%s*\n",buf); //*ab3*
memset(buf, 0, 1024);
read(f1_1, buf, 3);
printf("*%s*\n",buf); //*456*
printf("%d, %d, %d", f1_1, f1_2, f1_3); //3,4,5
//close(f1_1), 再操作f1_3是否会出错? 不会,说明文件描述符结构内有引用计数。
close(f1_1);
memset(buf, 0, 1024);
read(f1_3, buf, 3);
printf("*%s*\n",buf); //*cd*
lseek(f1_3, 0, SEEK_SET);
memset(buf, 0, 1024);
read(f1_3, buf, 3);
printf("*%s*\n",buf); //*ab3*
memset(buf, 0, 1024);
read(3, buf, 3);
printf("*%s*\n",buf); //** //close(f1_1)之后,3不再与之前的文件描述符关联,输出为空。上面的read读取应该会返回一个错误码。
// #include <unistd.h>
// int dup2(int oldfd, int newfd);
// 1. newfd已经被使用,则先关闭newfd执行的文件,应该是相当于先执行close(newfd)。
// 2. newfd等于oldfd, (这个操作好像没有意义。。。。) 若newfd等于oldfd,则返回newfd,而不关闭newfd所指的文件。
// 返回值: 若dup2调用成功则返回新的文件描述符,出错则返回-1.
// dup2与dup区别为: dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等. 即共享一个内部的文件描述符结构体
// dup返回目前系统可用的最小文件句柄。 eg。 5
// dup2可以指定一个数字作为newfd。
}
int main()
{
//test_1
// fprintf(stderr, "heheda1\n");
// close(STDERR_FILENO);
// fprintf(stderr, "heheda2\n"); //未输出
//test_2
write(STDERR_FILENO, "heheda", 6);
close(STDERR_FILENO);
write(STDERR_FILENO, "2heheda", 6); //未输出
return 1;
}