FILE结构体
FILE是c语言文件结构体定义,打开文件和文件操作要用到这类结构。可以看成变量类型,用于变量声明、
主要包含文件描述符、文件读写位置、IO缓冲区三部分内容。
两个进程同时打开,系统调用方式执行:
1.每个进程会独立创建一个文件描述表,读取时互不影响。
2.读写形式打开,先读后写,会从读后的位置开始覆盖写入新的内容。
2.阻塞和非阻塞
阻塞:顾名思义,就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足。
非阻塞:就是反过来,进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直到可以进行位置。
3.fcntl改文件属性
改变一个[已经打开]的文件的访问控制属性
掌握两个参数的使用,F_GETFL和F_SETFL。
#include<fcntl.h>
#include<sys/types.h>
#include<string.h>
int main()
{
char buf[10];
int fd,n,i;
fd = fcntl(STDIN_FILENO,F_GETFL);
if(fd<0)
{
printf("open error\n");
exit(1);
}
fd |= O_NONBLOCK;
int ret = fcntl(STDIN_FILENO,F_SETFL,flags);
if(ret == -1)
{
printf("open error\n");
exit(1);
}
for(i=0;i<5;i++)
{
n = read(STDIN_FILENO,buf,10);
if(n>0)
{
break;
}
if(n<0)
{
if(errno != EAGAIN)
{
printf("read /dev/tty");
exit(1);
}
else
{
write(STDOUT_FILENO,"try again\n",strlen("try again\n"));
sleep(2);
}
}
}
if(i == 5)
{
write(STDOUT_FILENO,"time out\n",strlen("time out\n"));
}
else
{
write(STDOUT_FILENO,buf,n);
}
return 0;
}
小结:
int flags = fcntl(fd,F_GETFL)
获取文件状态:F_GETFL
设置文件状态:F_SETFL
4.lseek函数
linux中可使用系统函数,lseek来修改文件偏移量(读写位置)
lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫做偏移量)
fseek的作用及常用参数。SEEK_SET、SEEK_CUR、SEEK_END.
使用lseek拓展文件
write操作才能实质性的拓展文件。单lseek是不能进行拓展的。
结论:
1.光标往后移动100个字节,lseek测试总文件大小144字节,实际文件大小44字节
2.光标往后移动100个字节,增加一个write动作,lseek测试总文件大小145字节,实际文件大小145字节
3.lseek的返回值是光标从0到文件结束的地址,如果使用lseek移动会造成假拓展。
5.od显示文件或流
od作用:指定格式查看文件内容。
od(octal dump)命令可以以八进制、十进制、十六进制和ASCII码的格式来显示文件或者流,它们对于访问或可视地检查文件中不能直接显示在终端上的字符(如换行符等)很有用。此外,在一些有空洞的文件中可以通过od命令查看空洞的位置。
-A ( 地址进制)按指定的进制显示地址信息;
-t 指定数据显示的格式。
-A 指定的地址进制包括:
o:八进制(系统默认值)
d:十进制
x:十六进制
n:不打印位移值
-t 指定数据的显示格式的主要参数有:
c:ASCII字符或反斜杠序列(如\n)
d:有符号十进制数
f:浮点数
o:八进制(系统默认值)
u:无符号十进制数
x:十六进制数
6.dup和dup2函数 重定向
功能:复制一个已有的文件描述符,实现指向同一个文件。
int dup(int oldfd);
参数:oldfd已有文件描述符
成功:返回一个新文件描述符
失败:-1返回error为相应值。
测试dup代码
#include<string.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
int fd = open("1.txt",O_RDWR);
if(fd<0)
{
printf("open error\n");
}
int newfd = dup(fd);
if(newfd<0)
{
printf("open error\n");
}
int ret = write(fd,"hello\n",strlen("hello\n"));
if(ret<0)
{
printf("write fd error\n");
}
ret = write(newfd,"world\n",strlen("world\n"));
if(ret<0)
{
printf("write fd error\n");
}
close(fd);
close(newfd);
return 0;
}
dup2测试代码
#include<string.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
int fd1 = open("1.txt",O_RDWR);
if(fd1<0)
{
printf("open error\n");
}
printf("fdq1= %d\n",fd1);
int fd2 = open("2.txt",O_RDWR);
if(fd2<0)
{
printf("open error\n");
}
printf("fd2 = %d\n",fd2);
int newfd = dup2(fd1,fd2);
if(newfd<0)
{
printf("open error\n");
}
printf("newfd = %d\n",newfd);
write(fd1,"hello\n",strlen("hello\n"));
write(fd2,"world\n",strlen("world\n"));
write(newfd,"happy\n",strlen("happy\n"));
close(fd1);
close(fd2);
close(newfd);
return 0;
}