一.文件的创建打开与关闭
1.open函数 系统调用用来打开或创建一个文件
#define O_RDONLY 00000000
#define O_WRONLY 00000001
#define O_RDWR 00000002
所以:O_RDONLY | O_WRONLY = 1 ,并不等于O_RDWR。
函数原型:
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open(const char * pathname , int flags);
int open(const char * pathname , int falgs , mode_t mode);
第一个参数pathname 是要打开或创建的含路径的文件名。第二个参数flags表示打开文件方式。
O_RDONLY :以只读方式打开文件 //
O_WRONLY:以只写方式打开文件 ///文件不存在返回-1
O_RDWR : 可读可写方式打开 //
O_CREAT : 若文件不存在则自动建立该文件, 只在此时需要第三个参数mode (见下),用来说新文件的存取权限
O_CREAT | O_EXCL : (两者通常一起使用) 文件不存在建立新文件,文件存在时出错(文件存在反而打不开)
O_TRUNC : 若文件存在 并 (|)以 可写!可写!可写!(重要的事情要说三遍)方式打开时,此标志会将文件长度清零,即原文件中保存的数据将丢失,文件属性不变
(PS: open("test.txt", O_WRONLY(可写) | O_TRUNC)相当与删除文件再创建文件)
O_APPEND : 所写入的数据会以追加的方式加入到文件后面 (继续写入)
第三个参数:
模式:S_IR(EAD) / IW(RITE) / IX(执行) + US(E)R /GR(OU)P / OTH(ER)
S_IRWX + U/G/O
S_IRWXU 00700 权限,代表该文件所有者具有可读、可写及可执行的权限。
S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。
S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。
S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。
S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。
S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。
S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。
S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。
S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。
S_IROTH 00004 权限,代表其他用户具有可读的权限
S_IWOTH 00002权限,代表其他用户具有可写入的权限。
S_IXOTH 00001 权限,代表其他用户具有可执行的权限。
open("test.txt", O_CREAT | O_EXCL ,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
相当与 vim test.txt
2.creat函数:文件的创建可以通过creat系统调用来完成,函数原型为:
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int creat(const char * pathname, mode_t mode);
其中第一个参数pathname时要打开或创建的文件名, 如果pahtname指向的文件不存在,则创建一个新文件;如果pathname指向的文件存在,则元文件江北覆盖。第二个参数mode与open函数的第三个参数mode相同。
书上说creat()相当于这样用open():
open(const cahr * pathname, (O_CREAT | O_WRONLY | O_TRUNC));
这样似乎有点问题在于第三个参数mode
creat(const char * pathname , mode_t mode); 相当于
open(const cahr * pathname , (O_CREAT | O_WRONLY | O_TRUNC) , mode_t mode);
3.close函数 :系统调用用来关闭一个已经打开的文件,函数原型为:
#include<unistd.h>
int close(int fd); 打开文件后必须关闭
4.read函数 :系统调用用来从代开的文件中读取数据,函数原型为:
#include<unistd.h>
ssize_t read(int fd, void *buf, size_t count)
从文件描述符fd所指向的文件中读取count个字节的数据到buf所指向的缓存中,若参数count为0,则read()不会读取数据,只返回0。 返回值表示实际读取到的字节数,如果返回0,标识已经到达文件尾部或是无数据可读,此外文件读写指针会随着读取到的字节移动。如果read()顺利返回实际读到的字节数,最好能将返回值与count比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾,或者read()被信号中断了(不懂)读取过程,或者其他原因,出错返回 -1 。详细错误errno。
5. wite()函数:系统调用用来将数据写入已打开的文件中,原型为:
#include<unistd.h>
ssize_t write (int fd , const void * buf , size_t count);
将buf所指向的缓冲区中count个字节数据写入到由文件描述符fd所示的文件中。文件读写指针也会随之逸动。如果调用成功,write()会返回写入的字节数。当有错误发生时返回-1,错误代码存入errno中。
6.文件读写指针的移动 lseek()函数:系统调用来移动文件读写指针的位置,原型:
#include<sys/types.h>
#include<unistd.h>
off_set lseek(int fildes , off_set , int whence)
参数whence:
SEEK_SET 从文件开头处计算偏移量, 文件指针到文件开始处的距离为offset。
SEEK_CUR 从文件指针的当前位置开始计算偏移量,文件指针值等于当前指针值加上offset值,
offset的值允许取负数。
SEEK_END 从文件结尾处开始计算偏移量,文件指针值等于当前指针值加上offset的值,可为负数。
常用方法:
1)将文件指针移动到文件开头:lseek(int fildes , 0 , SEEK_SET)
2)将文件指针移动到文件结尾:lseek(int fildes , 0 , SEEK_END)
3)将文件指针移动到当前位置:lseek(int fildes , 0 , SEEK_CUR)