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");