1.open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags,[mode_t mode]);
若成功,返回非负整数,称为文件描述符。出错返回-1;
pathname可以是相对路径或绝对路径
flags:
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
mode为可选参数,当flags为O_CREAT是才有效。
举例:
filedes = open("/tmp/newfile", O_WRONLY | O_CREAT, 0644);
如文件不存在,会创建一个长度为0的文件,并以只读方式打开。
八进制数0644,表示权限,以后再讨论。
若文件存在,如果访问权限允许,就以写的方式打开,和没有O_CREAT一样。
也可以加上O_EXCL(相斥)属性,若文件存在,返回-1;
另外一个有用标志O_TRUNC,若文件已存在,强制把文件长度截为0.
2.creat
int creat(const char* pathname, mode_t mode);
默认以写的方式打开,若文件已存在,第二个参数无意义。
和open不同,总是把已存在的文件长度截为0;
一个程序不能用creat创建一个文件后,先把数据写入文件,再从此文件读取数据,除非关闭这个文件后重新用open打开它;
3.close
int close(int filedes);
4.read
ssize_t read(int filedes, boid *buffer, size_t n);
返回的数表示真正从文件中读取的字节数,通常等于n或小于n。出错时返回-1;
文件指针:记录文件的读写位置,由系统维护;
判断是否到大文件尾:检查read的返回值是否为0;
unix系统中以磁盘块大小的整数倍传输的效率是最高的。可以通过stdio.h中定义的常量BUFSIZ来得到真正的磁盘块大小值;
5.write
ssize_t write(int filedes, const void *buffer, size_t n);
返回值表示实际写入文件的字节数,若小于n,那么就应该是出错了;
在一个以写的方式打开一个已存在的文件之后立即写文件,旧数据会被新数据覆盖;
若想把数据加到文件末尾,加上O_APPEND标志;
6.lseek
off_t lseek(int filedes, off_t offset, int start_flag);
返回值为文件读写指针的新位置
offset一般这样用:(off_t)5
flag:
SEEK_SET 从起始位置开始算
SEEK_CUR 从当前位置
SEEK_END 从文件末尾
注意:
1 offset可以是负数,只有在你想把文件指针移动到文件头之前才会出错;
2 可以指定一个在文件之外的位置,对write来说使文件变长,中间的空数据区用ASCII的null字符填充;
3 通过lseek可得到文件的大小,即末尾位置-开始位置
7.删除文件
int unlink(const char * pathname);
int remove(const char * pathname);
在删除正规文件上,两者完全相同;
但用remove删除一个空目录时,remove和另一个系统调用rmdir功能相同,而unlink不能用来删除目录
8.fcntl
int fcntl(int filedes, int cmd,..);
主要介绍cmd为F_GETFL,F_SETFL;
F_GETFL命令返回文件当前状态标志,该标志由open打开文件时设定;
举例:
int arg;
arg = fcntl(filedes,F_GETFL);
switch(arg & O_ACCMODE)//O_ACCMODE用来测定文件是以只读、只写、读写方式打开
{
case O_WRONLY:
printf("write_only");break;
.........
}
if(arg1 & O_APPEND)
printf("-append flag set");
F_SETFL用来重新设定一个文件的状态标志位,但很多情况下都不行
fcntl(filedes, F_SETFL,O_APPEND);
9.标准输入、输出、错误
unix会为正在执行的程序自动打开三个文件,。。。,文件描述符为0,1,2;
10.标准I/O库
标准i/o库和系统调用最明显的区别是如何描述一个文件;系统调用使用一个整数文件描述符,而i/o库用一个名为FILE的结构来访问文件;
FILE *stream;
stream = fopen("junk", "r");
fopen最终还是会调用open的;标准i/o库的库函数都离不开系统调用原语,只是提供了一个更友好的编程接口,并附加了一个自动缓冲机制;
int getc(FILE istream);
int putc(int c, FILE *ostream);
while((c = getc(istream)) != EOF)
putc(c, ostream);
当getc读到文件尾的时候,返回一个值EOF,其真正的值为-1;
系统调用下,单个字节效率极低,但是标准库的缓冲机制解决了这个问题,但是数据只会成批的被输出到文件,这样文件就比程序存在着某些程度上的滞后。对同一文件混合使用系统调用和标准i/o库函数是不明智的。
输出错误信息:
fprintf(stderr,"error number %d\n",errno);
erron变量:
unix提供一个全局的×××变量记录错误的类型。为保险起见,在系统调用刚结束并出错的情况下,立即读取errno的值
perror子程序:
库函数perror是报告错误的标准方法
perror("error opening");