您的位置:首页 > 产品设计 > UI/UE

《APUE》读书笔记-第三章文件I/O

2017-04-12 10:43 423 查看
Unix系统中大多数文件I/O只需用到五个函数:open,read,write,lseek,(移动指针读写位置),close。本章说介绍的I/O是不带缓冲的,即:每个read和write都调用内核中的一个系统调用。不是ISO C的组成部分。对于内核而言,所有打开的文件都通过文件描述符引用。

在<uinstd.h>中定义三个标准的文件描述符:

STDIN_FILENO     标准输入

STDOUT_FILENO    标准输出

STDERR_FILENO    标准出错输出

具体函数描述在<fcntl.h>头文件下

int open (const char* path, int oflag,....); //打开或者创建一个文件

int creat(const char* path, mode_t mode); //创建一个文件

int close (int fides); //关闭一个打开的文件

Off_t lseek(int fides, off_t offset, int whence);//为打开的文件设置偏移量

Ssize_t read(int fd, void *buf, size_t count);

Ssize_t write (int fildes, const void *buf, size_t nbyte); 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main()
{
char *filename = ".//file";
char buf[100];
int fd;
memset(buf, 0, 100);
printf("Open file to write\n");
//打开文件,不存在和新建
if ((fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
{
perror("Cannot open file\n");
exit(-1);
}
printf("Open file successfully.\n");
printf("Input a string: ");
gets(buf);
//写入文件
write(fd, buf, strlen(buf));
close(fd);
printf("Open file to read.\n");
if ((fd = open(filename, O_RDONLY)) == -1)
{
perror("Cannot open file\n");
exit(-1);
}
//从文件中读取
read(fd, buf, 100);
printf ("Read from file is: %s\n", buf);
close(fd);
return 0;
}


程序测试结果如下:



复制一个现有的文件描述符函数

Int dup(int fildes);

Int dup2(int fildes, int fildes2);

Dup返回的新文件描述符是当前可用文件描述符中最小值,dup2则是用fildes2参数指定新文件描述符的数值,若fildes2打开则关闭,若fildes等于fildes2则不关闭,返回fildes2在CGI程序用dup2将文件描述符重新定位到标准输入和标准输出。即:dup2(fd,STDOUT_FILENO)或dup2(fd, STDIN_FILENO)。

改变已打开文件的性质函数:

Int fcntl(int fd, int cmd,.../*arg*/);

函数功能:

复制一个现有的描述符(cmd = F_DUPFD)

获得或设置文件描述符(cmd = GETFDIF_SETFD)

获得或设置文件状态标志(cmd=F_GETFL|F_SETFL)
获得或设置异步I/O所有权(cmd=F_GETOWN|F_SETOWN)
获得或设置记录锁(cmd=F_GETLK|F_SETLK、F_SETLKW)

可以用fcntl函数设置文件状态,常用设置套接字描述为非阻塞O_NONBLOCK

下面写个程序完成打印出指定描述符的文件状态标志。程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char * argv[])
{
int val;
if (argc != 2)
{
printf("usage:<descriptor#>\n");
exit(-1);
}
val = fcntl(atoi(argv[1]),F_GETFL,0);
if (val == -1)
{
perror("fcntl() error");
exit(-1);
}
switch(val & O_ACCMODE)
{
case O_RDONLY:
printf("read only.\n");
break;
case O_WRONLY:
printf("write only.\n");
break;
default:
printf("unknown access mode");

}
if (val & O_APPEND)
printf(", append");
if (val & O_NONBLOCK)
printf (", nonblocking");
putchar('\n');
return 0;
}


程序测试结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: