UNIX文件I/O函数
来源:互联网 发布:淘宝1688批发 编辑:程序博客网 时间:2024/05/16 04:43
大多数UNIX都提供I/O函数,一般只需要这几个:open,read,write,lseek,close
不带缓存I/O:指的是每个read和write都调用内核中的一个系统调用,不带缓存的I/O函数不是ANSI C的一部分,但却是POSIX.1和XPG3的组成部分。
文件描述符:
对内核而言,所有打开的文件都由文件描述符来引用。在POSIX.1中,0,1,2分别代表常数STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO,它们都在《unistd.h》中定义,文件描述符的范围是0~OPEN_MAX,早期的UNIX一般支持20(OPEN_MAX=19)个,后来基本上扩展到64个。
open——打开或者创建文件
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//返回:成功时返回文件描述符,失败则返回-1int open(const char *pathname,int oflag,.../*,mode_t mode*/);
当open创建文件时,才使用第三个参数,用来说明文件的存取的许可权位。
pathname用于指定打开或者创建的文件的名字,oflag说明函数的选择项:
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读写打开
这三个选项应当只指定一个,下列是可选常数选项:
O_APPEND 每次写时都自动把写入位置置于文件尾端
O_CREAD 若此文件不存在,则创建文件,需要指定第三个参数
O_EXCL 如果指定了O_CREAT的同时文件又存在则出错,它可测试文件是否存在
O_TRUNC 如果文件存在,且是以只读或者只写打开,则将其长度截短为0
O_NOCTTY 如果pathname所指定的文件是终端设备,那么不能将此设备分配为进程的控制终端
O_NONBLOCK 如果pathname所指定的文件是FIFO,一个块特殊文件,一个字符特殊文件则此次打开文件操作和后续操作均设置为非阻塞
文件名或者文件路径截短
如果我们试图创建一个文件名或者路径名大于NAME_MAX的新文件,会发生什么呢?
早期的系统V版,允许使用文件名截短为NAME_MAX值,BSD系统则返回ENAMETOOLONG错误
在POSIX.1中,常数_POSIX_NO_TRUNC决定了是否要截短文件名或者路径名,否则返回错误
creat——创建一个新文件
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//返回:成功则返回只写打开文件的描述符,出错则返回-1int creat(const char *pathname,mode_t mode);
此函数等价于:
open( pathname , O_WRONLY | O_CREAT | O_TRUNC , mode );
如今已经不需要creat函数了,因为本身creat函数受制于只写打开文件,调用creat函数并读取文件,必须经过如下序列函数调用:creat——>close——>open——>read
close——关闭一个打开的文件
#incluede <unistd.h>//返回:成功为0,出错为-1int close(int filedes);
调用close关闭一个文件时,也会释放进程加载在该文件上的所有记录锁。另外,当进程终止时,它多打开的文件都由内核自动关闭。
lseek——定位文件
#include <sys/types.h>#include <unistd.h>//返回:成功则返回新的文件位移,出错则为-1off_t lseek(int filedes,off_t offset,int whence);
每一个打开的文件都有一个与其关联的“文件当前位移量”,通常它为一个非负数,用以度量从文件开始处计算的字节数,而文件的读和写都从当前文件位移量处开始,并使位移量增加所读和所写的字节数,按系统默认,当打开一个文件时,除非指定O_APPEND选项,位移量均为0
对whence参数
SEEK_SET 文件开始处
SEEK_CUR 文件当前处
SEEK_END 文件末尾处
为此,可以用下列方式获取一个打开的文件的当前位移量
off_t curpos=lseek(fileded,0L,SEEK_CUR);
同时这中方法也可以用来测试所涉及的文件是否支持设置位移量,比如当文件描述符所指定的文件是一个FIFO,一个管道,则lseek返回-1,并将errno设置为EPIPE。
通常,文件位移量为非负值,但有部分特殊设备支持文件位移量为负数,所以对lseek的返回值需慎重,不要检测其是否小于 0,而应检测是否等于 -1。
lseek将文件偏移量记录在内核中,这个操作并不会引起I/O操作,这个具体将在文件的数据结构中解释。
文件位移量可以大于文件长度,在这种情况下会延长文件长度,并在中间未写入部分形成空洞,空洞部分都置为0。
read——读文件
#include <unistd.h>//返回:读到的字节数,若已经到文件末尾则返回0,出错则返回-1int read(int filedes,void *buff,size_t nbytes);
有多种情况使读到的字节数少于要求读的字节数
a.读普通文件,在读到要求的字节数之前就达到文件末尾了,返回0
b.当从终端中读取时,通常一次读取一行
c.当从网络读取时,因为网络的缓冲机制,可能造成读取的字节数少于要求的字节数
d.某些面向记录的设备,比如磁带,一次最多读取一个记录
write——写文件
#include <unistd.h>//返回:成功时返回写入字节数,出错返回-1int write(int filedes,void *buff,size_t nbytes);
write可能因为返回写入的字节数少于要求的字节数而出错,常见原因是:磁盘已满或者文件超出一个给定进程的文件长度限制。
实例:
1.标准输入复制到标准输出
//把标准输入复制到标准输出#include <unistd.h>int main(){//8192这个块大小值在很多情况下可以提高I/O效率char buff[8192];int n;while( (n=read(STDIN_FILENO,buff,8192)) >0){if( write(STDOUT_FILENO,buff,n)!=n){perror("Write error .\n");}} return 0;}
2.创建一个有空洞的文件
//创建一个空洞文件#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>int main(){char filename[]="file.hole";int fd;if( (fd=open(filename,O_RDWR|O_CREAT,777)) <0){perror("File create error .");}//the offset now=0if( write(fd,"abcdefghi",10) !=10){perror("File write error ");}//the offset now=10if( lseek(fd,10L,SEEK_CUR) ==-1){perror("File seek error .");}//the offset now=20if( write(fd,"ABCDEFGHI",10) !=10){perror("File write error ");}//the offset now=30return 0;}
这篇只是介绍了几个非缓冲文件I/O基本的函数,不属于ANSI C的组成部分。
加油。
- UNIX文件I/O函数
- unix----文件I/O
- UNIX文件 I / O
- 《Unix环境高级编程》读书笔记:常用文件I/O函数
- UNIX 文件I/O总结
- 文件 I/O 函数
- 文件I/O函数
- 标准I/O与Unix I/O函数整合
- unix环境下文件I/O函数
- unix i/o create函数解惑
- UNIX环境编程—文件I/O
- unix 文件I/O之诠释
- UNIX环境高级编程----文件I/O
- UNIX系统文件I/O总结
- 《unix高级环境编程》文件I/O
- 《unix高级环境编程》文件I/O
- UNIX文件I/O之判断文件类型
- unix编程(一)文件I/O
- 黑马程序员_学习日记63_710jQuery2(属性选择器、表单选择器、操作Dom节点、事件、动画)
- 免费馅饼(dp)
- xtable-addons在ubuntu 12.04上安装
- 命运(dp)
- Android JNI知识简介
- UNIX文件I/O函数
- Oracle 监听器日志配置与管理
- POJ1308
- one trick in C pointer.
- 新浪技术部笔试题
- 26个Jquery使用小技巧
- Monkey and Banana(dp)
- C语言 ---- 快速排序算法
- Python十分钟入门