第五讲 高级文件操作
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int fds[2];
char buf[4096];
int i, fd;
if ((fds[0] = open("p1",O_RDONLY)) < 0)
{
perror("open");
return 1;
}
if (fds[1] = open("p2",O_RDONLY) < 0)
{
perror("open p2");
return 1;
}
fd = 0;
while (1)
{
i = read(fds[fd],buf,sizeof(buf) - 1);
if (i < 0)
{
perror("read");
return 1;
}
else if (!i)
{
printf("pipe close/n");
return 0;
}
buf[i] = '/0';
printf("read:%s", buf);
fd = (fd + 1) % 2;
}
return 0;
}
[root@localhost tmp]mknod p1 p
[root@localhost tmp]mknod p2 p
[root@localhost tmp]gcc –o mpxb1 mpxb1.c
[root@localhost tmp]./mpxb1 // 在终端一中运行
[root@localhost tmp]cat > p1 // 在终端二中运行
test1
[root@localhost tmp]cat > p2 // 在终端三中运行
test2
[root@localhost tmp]./mpxb1 // 在终端一中运行
read:test1
对于test2不能显示啊
多路输入输出
#include <sys/poll.h>
int poll(struct pollfd *fds, int numfds, int timeout);
struct pollfd{
int fd;
short events;
short revents;
}
POLLIN, POLLPRI, POLLOUT, POLLERR, POLLHUP, POLLNVAL
例
#include <fcntl.h>
#include <stdio.h>
#include <sys/poll.h>
#include <unistd.h>
int main()
{
struct pollfd fds[2];
char buf[4096];
int i, rc;
if ((fds[0].fd = open("p1", O_RDONLY|O_NONBLOCK)) < 0)
{
perror("open p1");
return 1;:
}
if ((fds[1].fd = open("p2", O_RDONLY | O_NONBLOCK)) < 0)
{
perror("open p2");
return 0;
}
fds[0].events = POLLIN;
fds[1].events = POLLIN;
while (fds[0].events || fds[1].events)
{
if (poll(fds, 2, 0))
{
perror("poll");
return 1;
}
for (i = 0; i < 2; i++)
{
if (fds[i].revents)
{
rc = read(fds[i].fd, buf, sizeof(buf) - 1);
if ( rc < 0 )
{
perror("read");
return 1;
}
else if (!rc)
{
fds[i].events = 0;
}
else
{
buf[rc] = '/n';
printf("read:%s", buf);
}
}
}
}
return 0;
}
#include <sys/select.h>
int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
FD_ZERO(fd_set *fds); FD_SET(int fd, fd_set *fds);
FD_CLR(int fd, fd_set *fds); FD_ISSET(int fd, fd_set *fds);
#include <sys/time.h>
struct timeval{
int tv_sec;
int tv_usec;
}
例
#include <fcntl.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
int main(void)
{
int fds[2];
char buf[4096];
int i, rc, maxfd;
fd_set watchset;
fd_set inset;
if (fds[0] = open("p1", O_RDONLY | O_NONBLOCK) < 0)
{
perror("open p1");
return 1;
}
if (fds[1] = open("p2", O_RDONLY | O_NONBLOCK) < 0)
{
perror("open p2");
return 1;
}
FD_ZERO(&watchset);
FD_SET(fds[0], &watchset);
FD_SET(fds[1], &watchset);
maxfd = fds[0] > fds[1] ? fds[0] : fds[1];
while (FD_ISSET(fds[0], &watchset) || FD_ISSET(fds[1], &watchset))
{
inset = watchset;
if (select( maxfd + 1, &inset, NULL, NULL, NULL) < 0)
{
perror("select");
return 1;
}
for ( i = 0; i < 2; i++)
{
if(FD_ISSET(fds[i], &inset))
{
rc = read(fds[i], buf, sizeof(buf) - 1);
if (rc < 0)
{
perror("read");
return 1;
}
else if (!rc)
{
close(fds[i]);
FD_CLR(fds[i], &watchset);
}
else
{
buf[rc] = '/0';
printf("read:%s", buf);
}
}
}
}
return 0;
}
比较poll()和select()
例
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <unistd.h>
#include <signal.h>
int gotAlarm;
void catch(int sig)
{
gotAlarm = 1;
}
#define HIGH_FD 1000
int main( int argc ,const char *argv)
{
int devZero;
int count;
fd_set selectFds;
struct pollfd pollfds;
devZero = open("dev/zero",O_RDONLY);
dup2(devZero, HIGH_FD);
signal(SIGALRM, catch);
gotAlarm = 0;
count = 0;
alarm(1);
while (!gotAlarm)
{
FD_ZERO(&selectFds);
FD_SET(HIGH_FD, &selectFds);
select(HIGH_FD + 1, &selectFds, NULL, NULL, NULL);
count++;
}
printf("select() calls per second :%d/n", count);
pollfds.fd = HIGH_FD;
pollfds.events = POLLIN;
count = 0;
gotAlarm = 0;
alarm(1);
while (!gotAlarm)
{
poll(&pollfds, 0, 0);
count++;
}
printf("poll() calls per second :%d/n", count);
return 0;
}
#include <sys/epoll.h>
int epoll_create(int numDescriptors);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
struct epoll_event{
union{
void *ptr;
int fd;
unsigned int u32;
unsigned long long u64;
} data;
}
EPOLLIN, EPOLLOUT, EPOLLPRI
EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD
read和write的替代
例
#include <sys/uio.h>
struct iovec{
void *iov_base;
void *iov_len;
};
int readv(int fd, const struct iovec *vector, sieze_t count);
int writev(int fd, const struct iovec *vector, size_t count);
例
#include <unistd.h>
#include <stdio.h>
#include <sys/uio.h>
int main()
{
struct iovec buffers[3];
buffers[0].iov_base = "hello";
buffers[0].iov_len = 5;
buffers[1].iov_base = " ";
buffers[1].iov_len = 1;
buffers[2].iov_base = "world/n";
buffers[2].iov_len = 6;
writev(1,buffers, 3);
return 0;
}