close()函数:
int close(int fd);
错误处理函数: 与errno相关。
printf("XXX error:%d\n",errno);
char *strerror(int errnum);
printf("XXX error:%s\n",strerror(errno));
void perror(const char *s);
perror("open error");
read函数:
ssize_t read(int fd,void *buf,size_t count)
参数:
fd:文件描述符
buf:存数据的缓冲区
count:缓冲区大小(这个count代表容器的大小)
返回值:
0:读到文件末尾
成功:读到的字节数
失败:-1,设置errno
-1:并且errno = EAGIN 或 EWOULDBLOCK,说明不是read失败,而是read在以非阻塞方式读一个设备文件(或者网络文件),并且文件无数据。
错误处理函数:
void perror(const char *s);
write函数:
ssize_t write(int fd,const void *buf,size_t count);
参数:
fd:文件描述符
buf:数据缓冲区
count:缓冲区大小(这个count代表数据的大小)
返回值:
成功:读到的字节数
失败:-1,设置errno
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
char buf[1024];
int n=0;
int fd1=open(argv[1],O_RDONLY);
int fd2=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);
//读取参数1文件的数据,当读到文件未尾时,退出
while((n=read(fd1,buf,1024))!=0)
{
write(fd2,buf,n);//把缓冲区数据写入到fd2对应的文件中
}
close(fd1);
close(fd2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
char buf[1024];
int n=0;
int fd1=open(argv[1],O_RDONLY);
if(fd1==-1)
{
perror("open argv1 error");
exit(1);
}
int fd2=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd2==-1)
{
perror("open argv2 error");
exit(1);
}
while((n=read(fd1,buf,1024))!=0)
{
if(n<0)
{
perror("read error");
break;
}
write(fd2,buf,n);
}
close(fd1);
close(fd2);
return 0;
}
文件描述符:
PCB进程控制块:本质 结构体
成员:文件描述符表
文件描述符:0/1/2/3/4/................/1023
表中可用的最小STD的。
0 -STDIN_FILENO
1 -STDOUT_FILENO
2 -STDERR_FILENO
阻塞、非阻塞:是设备文件的属性
产生阻塞的场景。读设备文件。读网络文件。(读常规文件无阻塞概念)
/dev/tty ---终端文件
open("/dev/tty",O_RDWR|O_NONBLOCK) ---设置非阻塞状态
不加O_NONBLOCK,默认为阻塞状态
阻塞方式:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char buf[10];
int n;
n = read(STDIN_FILENO,buf,10);
if(n < 0)
{
perror("read STDIN_FILENO");
exit(1);
}
write(STDOUT_FILENO,buf,n);
return 0;
}
执行结果如下:
read()函数起阻塞功能
非阻塞方式:
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buf[10];
int fd,n;
fd = open("/dev/tty",O_RDONLY|O_NONBLOCK);
if(fd < 0){
perror("open /dev/tty");
exit(1);
}
tryagain:
n=read(fd,buf,10);
if(n < 0){
if(errno != EAGAIN){
perror("read /dev/tty");
exit(1);
}else{
write(STDOUT_FILENO,"try again\n",strlen("try again"));
sleep(2);
goto tryagain;
}
}
write(STDOUT_FILENO,buf,n);
close(fd);
return 0;
}
执行结果如下:
设置一个超时:
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MSG_TRY "try again\n"
#define MSG_TIMEOUT "time out\n"
int main(void)
{
char buf[10];
int fd,n,i;
fd = open("/dev/tty",O_RDONLY|O_NONBLOCK);
if(fd < 0){
perror("open /dev/tty");
exit(1);
}
printf("open /dev/tty ok...%d\n",fd);
for(i=0;i<5;i++){
n=read(fd,buf,10);
if(n > 0){ //说明读到了东西
break;
}
if(errno != EAGAIN){ //EWOULDBLOCK
perror("read /dev/tty");
exit(1);
}else{
write(STDOUT_FILENO, MSG_TRY,strlen(MSG_TRY));
sleep(2);
}
}
if(i ==5){
write(STDOUT_FILENO,MSG_TIMEOUT,strlen(MSG_TIMEOUT));
}else{
write(STDOUT_FILENO,buf,n);
}
close(fd);
return 0;
}
执行结果如下: