您的位置:首页 > 编程语言

Unix环境高级编程笔记 :3、文件I/O

2013-10-30 11:23 393 查看
1、文件io需求5个函数

open read write lseek close

这些函数被称为不带缓冲的IO,不带缓冲IO指的是每个read和write都调用内核中的系统调用

只要涉及多个进程间共享资源,原子操作的概念就变的非常重要。

dup、fcntl、sync、fsync、ioctl

2、文件描述符

文件描述符是一个非负整数,当打开一个现有的文件或创建一个新文件时,内核向进程返回一个文件描述符。

<unistd.h>

0 标准输入 STDIN_FILENO

1 标准输出 STDOUT_FILENO

2 标准出错输出 STDERR_FILENO

3、open

open函数可以打开或创建一个文件

#include <fcntl.h>

int open(const char * pathname,int oflag,.../*mode_t mode*/);

oflag参数说明此函数多个选项,用下面一个或多个常量进行“或”运算构成oflag参数 <fcntl.h>

O_RDONLY 只读打开

O_WRONLY 只写打开

O_RDWR 读写打开

O_APPEND 写时追加到文件尾端

O_CREAT 或此文件不存在则创建。使用此选项,需要第三个参数mode,用其指定新文件的访问权限位

O_EXCL

O_TRUNC 如果此文件存在,而且为只写或读写成功打开,则将其长度截短为0

O_NOCTTY

O_NONBLOCK 设置非阻塞IO

4、 creat

#include <fcntl.h>

int creat(const char * pathname,mode_t mode);

5、close

#include <unistd.h>

int close(int fildes); 成功0,出错-1

6、lseek

按系统默认情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0

lseek显式的为一个打开的文件设置其偏移量

off_t lseek(int fildes,off_t offset,int whence);

whence是SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节

whence是SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正或负

whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可为正或负

7、read

#include<unistd.h>

ssize_t read(int filedes,void *buf,size_t nbytes) 成功返回读到的字节数,已到文件结尾返回0,出错返回-1

8、write

#include<unistd.h>

ssize_t write(int filedes,const void *buf,size_t nbyes); 成功则返回已写的字节数,若出错则返回-1

stdin.c 标准输入写到标准输出

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdlib.h>

#define BUFFER_SIZE 4096

int main(int argc, char **argv) {

char buffer[BUFFER_SIZE];

int n;

while ((n = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0) {

if (write(STDOUT_FILENO, buffer, n) != n) {

printf("write error");

exit(1);

}

}

if (n < 0) {

printf("read error");

exit(1);

}

exit(0);

}

9、dup dup2

#include <unistd.h>

int dup(int fileds);

int dup2(int files,int files2);

dup返回的新文件描述符一定是当前可用的文件描述符中最小的值。dup2可以用fileds2参数指定新描述符的数值

当此函数执行时,二个描述符指向同一个文件表项,所以他们共享同一文件状态标志(读 写 添加)以及同一个文件偏移量。

10、fsync fdatasync sync

为保证磁盘上的实际文件与缓冲区内容的一致性

11、fcntl

#include<fcntl.h>

int fcntl(int filedes,int cmd,.../*int arg*/);

fcntl函数有5种功能

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

b)获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)

c)获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)

d)获得/设置异步IO所有权(cmd=F_GETOWN或F_SETOWN)

e)获得/设置记录锁(cmd=F_GETTLK、F_SETLK、F_SETLKW)

fcntl文件状态标志

O_RDONLY 只读打开

O_WRONLY 只写打开

O_RDWR 读写打开

O_APPEND 写时追加到文件尾端

O_CREAT 或此文件不存在则创建。使用此选项,需要第三个参数mode,用其指定新文件的访问权限位

O_EXCL

O_TRUNC 如果此文件存在,而且为只写或读写成功打开,则将其长度截短为0

O_NOCTTY

O_NONBLOCK 设置非阻塞IO

fcntl.c

#include <stdio.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

int main(int argc, char **argv) {

int val;

if(argc !=2) {

printf("argc !=2\n");

exit(1);

}

if((val = fcntl(atoi(argv[1]),F_GETFL,0)) < 0) {

printf("fcntl error");

exit(1);

}

switch (val & O_ACCMODE) {

case O_RDONLY:

printf("read only");

break;

case O_WRONLY:

printf("write only");

break;

case O_RDWR:

printf("read write");

break;

default:

printf("unknow acces mode");

}

if(val & O_APPEND)

printf("append");

if(val & O_NONBLOCK)

printf("nonblocking");

#if defined (O_SYNC)

if(val & O_SYNC)

printf("synchronous");

#endif

putchar('\n');

exit(0);

}

12、ioctl

ioct函数是io操作的杂物箱,不能使用本中其他函数表示的io操作通用都能用ioctl表示。终端io是ioctl的最大使用方面。

13、/dev/fd

/dev/fd目录,其目录项是名为0、1、2等文件,打开文件/dev/fd/n 等效于复制描述符n

fd = open("/dev/fd/0",mode);

等效于fd = dup(0)

所以描述符0和fd共享同一文件表项,例如,描述符0先前被打开为只读,那么我们也只能对fd进行只读操作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: