Linux 系统编程之文件编程

在这里插入图片描述

达者为先  师者之意


1 文件描述符(fd)

Linux文件的身份证号码
文件描述符是一个非负的整数,当打开一个文件或创建一个文件时,内核向进程返回一个标识该文件的整数,即fd。
注意,若文件不被创建打开(即没有载入进程),是没有文件描述符可言的。
必需明确一个概念;UNUX中的一切皆是文件。因此对于特殊的文件有特殊的文件描述符。

linux中, 每一个进程在内核中,都对应有一个“打开文件”数组,存放指向文件对象的指针,而 fd 是这个数组的下标。
我们对文件进行操作时,系统调用,将fd传入内核,内核通过fd找到文件,对文件进行操作。既然是数组下标,fd的类型为int,< 0 为非法值,>=0 为合法值。

在Linux中,一个进程默认可以打开的文件数为1024个,fd的范围为0~1023。可以通过设置,改变最大值。
在linux中,值为0、1、2的fd,分别代表标准输入、标准输出、标准错误输出。

2 文件的创建(creat)

头文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

函数原型

int creat(const char *filename,mode_t mode)

filename:要创建的文件名(包含路径、缺省为当前路径)
mode:创建模式 //可读可写可执行
常见创建模式:
宏表示 数字
S_IXUSR 1 可执行
S_IWUSR 2 可写
S_IRUSR 4 可读
S_IRWXU 7 可读、写、执行
creat函数的返回值
成功:返回文件描述符
出错:返回-1并设置errno

3 文件打开(open)

头文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

两种函数原型

int open(const char *pathname, int flags);  //不需要创建新文件
int open(const char *pathname,int flags,mode_t mode); //创建新文件

pathname是要打开或创建的文件的名字(包含路径名称,缺省是认为在当前路径下面)
flags可以去下面的一个值或者是几个值的组合:

  • O_RDONLY 以只读的方式打开文件
  • O_WRONLY以只写的方式打开文件
  • O_RDWR 以读写的方式打开文件
  • O_APPEND以追加的方式打开文件
  • O_CREAT创建一个文件
  • O_EXEC 如果使用了O_CREAT而且文件已经存在,就会发生一个错误
  • O_NOBLOCK以非阻塞的方式打开一个文件
  • O_TRUNC如果文件已经存在,则删除文件的内容
  • O_RDONLY、O_WRONLY、O_RDWR 三个标志只能使用任意的一个。
    如果使用了O_CREATE标志, 则使用的函数是int open(const char*pathname,int flags,mode_t mode);

这个时候我们还要指定mode标志,用来表示文件的访问权限。mode可以是以下情况的组合:

  • S_IRUSR 用户可以读
  • S_IWUSR 用户可以写
  • S_ IXUSR 用户可以执行
  • S_IRWXU 用户可以读、写、执行
  • S_IRGRP 组可以读
  • S_IWGRP 组可以写
  • S_IRWXG 组可以读写执行
  • S_IROTH 其他人可以读
  • S_IWOTH 其他人可以写
  • S_IXOTH 其他人可以执行
  • S_IRWXO 其他人可以读、写、执行
  • S_ISUID 设置用户执行ID
  • S_ISGID 设置组的执行ID

除了可以通过上述宏进行“或”逻辑产生标志以外,
我们也可以自己用数字来表示,
Linux总共用5个数字来表示文件的各种权限:
第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位:第四位表示组的权限;最后一位表示其他人的权限。
每个数字可以取1(执行权限)、2(写权限)、4(读权限)、0(无)或者是这些值的和。
0100:可执行
0200:可写
0400:可读
0600:可读,可写:
0700:可读,可写,可执行
如果打开成功返回文件描述符fd
如果打开失败出错返回-1并设置errno

4 文件关闭(close)

头文件

#include <unistd.h>

函数原型

int close(int fd);

将要关闭的文件描述符传入close函数中即可关闭该文件

5 文件的写入(write)

头文件

#include <unistd.h>

函数原型

ssize_t write(int fd, const void *buf, size_t count);

fd: 文件描述符;
buf: 指定的缓冲区,即指针,指向一段内存单元;
count:要写入文件指定的字节数;
该函数就是把缓存区的数据写入到文件中去;
write函数的返回值
成功:写入文档的字节数
失败:-1
成功时返回写的字节数,错误时返回-1

6 文件的读取(read)

头文件

#include <unistd.h>

函数原型

ssize_t read(int fd, void *buf, size_t count);

fd:文件描述符;
buf:指定的缓冲区,即指针,指向一段内存单元;
count:你要读取文件的字节数;
read函数的返回值
成功:返回读取的字节数
出错:返回-1并设置errno
如果在调read之前已到达文件末尾,就是啥都没读到,则这次read返回0。

7 文件光标的移动、计算文件大小(lseek)

头文件

#include <sys/types.h>
#include <unistd.h>

函数原型

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

fd:文件描述符;
offset:向后的偏移值,对whence的偏移值,整数往后,负数往前;
whence:

  • SEEK_SET 参数 offset即为新的读写位置(文件头)
  • SEEK_CUR 以目前的读写位置往后增加 offset 个位移量(当前光标位置)
  • SEEK_END 将读写位置指向文件尾后再增加 offset个位移量(文件尾)

当 whence 值为 SEEK_CUR 或 SEEK_END 时, 参数 offet 允许负值的出现

下列是特别的使用方式:

  • 欲将读写位置移到文件开头时:
    lseek(fd,0, SEEK_SET);
  • 欲将读写位置移到文件尾时:
    lseek(fd,0, SEEK_END);
  • 想要取得目前文件位置时:
    lseek(fd,0, SEEK_CUR);

lseek函数的返回值

  • 成功:返回目前的读写位置, 也就是距离文件开头多少个字节.
  • 失败:则返回-1, errno 会存放错误代码.

lseek函数计算文件的大小
通过 lseek 的返回值来计算内容大小。
lseek(fd,0,SEEK_END);

码字不易  求个三连

在这里插入图片描述


版权声明:本文为MRDOCMAN原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。