linux系统编程——文件操作总结(1)

来源:互联网 发布:淘宝怎么开好直通车 编辑:程序博客网 时间:2024/06/10 06:13

1. linux的文件结构

linux是一个基于文件的操作系统,对于每个文件都有访问权限的设置,可以通过系统调用或C语言的库函数进行对文件的操作。

文件包含两方面:一是文件本身包含的数据;另外就是文件的属性,也成为元数据,包括文件的访问权限,所有者,文件大小,创建日期等。

2. 文件的分类

2.1. linux中包含以下几种文件类型

2.1.1. 普通文件:常见的文件类型,包含某种形式的数据。

2.1.2. 目录文件:实质就是目录,目录同时具有访问权限,目录文件的内容就是该目录下的文件和子目录的信息,有读权限的进程可读取该目录的内容,但只有内核可以写目录文件。

2.1.3. 字符特殊文件:用于表示文件系统中字符类型的设备,如键盘,鼠标等,这些硬件对于操作系统来说只是一个文件。

2.1.4. 块特殊文件:用于表示系统中块类型的设备,如硬盘,光驱等。对这些设备上的数据访问通常已块的方式进行,即一次至少读写一个块。

2.1.5. FIFO:进程间的通信,也命名为通信管道。

2.1.6. 套接字:用于网络通信,也可用于一台主机上进程间的通信。

2.1.7. 符号链接:指向另一个文件,是另一个文件的引用。

3.文件的访问权限的控制

linux的安全基于用户访问权限的控制,在shell下可通过ls -l <filename>查看文件的属性,其中文件属性10位中第1位表示文件类型,其余9位表示文件的访问权限,按3个一组分为三组,3组依次是文件所有者,文件所属组的用户,其他用户的操作权限。r表示可读,w表示可写,x表示可执行。可通过chmod命令来更改文件的访问权限。

//功能:改变文件的访问权限#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>int main(int argc, char ** argv){    int mode;   //权限    int mode_u;     //所有者权限    int mode_g;     //所属组权限    int mode_o;     //其他用户的权限    char *path;    //检查参数个数的合法性    if(argc < 3)    {        printf("%s <mode num> <target file>\n", argv[0]);        exit(0);    }    //获取命令行参数    mode = atoi(argv[1]);   //atoi(%s)函数将字符串转换成整形数    if(mode > 777 || mode < 0)    {        printf("mode num error!\n");        exit(0);    }    mode_u = mode / 100;    mode_g = (mode - (mode_u * 100)) / 10;    mode_o = mode - (mode_u * 100) - (mode_g * 10);    mode = (mode_u * 8 * 8) + (mode_g * 8) + mode_o;    //八进制转换    path = argv[2];    if(chmod(path, mode) == -1)    {        perror("chmod error");        exit(1);    }    return 0;}
在这段代码中  mode = (mode_u * 8 * 8) + (mode_g * 8) + mode_o;   是将所传入的参数对每一位进行解析之后,将连起来的数字按照一个8进制的数字进行转化得到10进制的结果,在chmod的参数mode实质就是一个10进制的数字,然后在chmod函数执行时,在其函数内部又转换为一个2进制的数,然后与代表着不同权限的字符常量(宏定义)的 2进制每位进行对比得出是否改变该权限,实质就是二进制的mode与各个权限的宏定义进行与运算(&)得出文件的操作权限的。

其中参数mode的数值如下:分别是 字符常量     字符常量对应的八进制值    含义

S_IRUSR(S_IREAD) 00400文件所有着具有可读取权限

S_IWUSR(S_IWRITE) 00200文件所有者具有可写入权限

S_IXUSR(S_IEXEC) 00100文件所有者具有可执行权限

S_IRGRP 00040用户组具有可读取权限

S_IWGRP 00020用户组具有可写入权限

S_IXGRP 00010用户组具有可执行权限

S_IROTH 00004其他用户具有可读取权限

S_IWOTH 00002其他用户具有可写入权限

S_IXOTH 00001其他用户具有可执行权限

S_ISUID 04000文件的(set user-id execution)位

S_ISGID 02000 文件的(setgroup-id execution)位

S_ISOTH 01000文件的sticky位

权限修改成功返回0,修改失败返回-1.


4. 对于文件的打开,有着不同的方式:

O_RDONLY:以只读方式打开文件

O_WRONLY:以只写方式打开文件

O_RDWR:以可读可写的方式打开文件

这些打开方式是互斥的,只能以其中一种方式打开,但也可与以下标志进行或运算

O_CREAT;如果文件按不存在自动建立该文件

O_EXCL:如果O_CREAT被设置,此时则会检查文件是否存在,文件不存在则创建,存在则出错

O_TRUNC:若文件存在并且以可写的方式打开时,此标志会将文件长度清零,即原文数据丢失,被空覆盖,单文件属性不变

O_APPEND:所写入的数据已追加的方式加入到文件后面

O_SYNC:以同步的方式打开文件按,任何对文件的修改都会阻塞直到物理磁盘数据同步以后才返回

O_NOFLOLLOW:若参数pathname所指文件为一符号连接,则打开失败

O_DIRECTORY:若参数pathname所指文件非目录,则会令打开失败

O_NONBLOCK / O_NDELAY:以非阻塞方式打开文件,对open以及随后的对文件的操作都会立即返回。

新文件的实际存取权限是mode与umask按照(mode & ~umask)运算后的结果,每个权限在mode的二进制位上实际只占一位,若本位为0则代表无此权限,1则反之

5.文件的创建与关闭

文件的创建可通过creat系统调用来完成

int creat(const char *pathname, ode_t mode);

若pathname指向的文件不存在,则创建一个新文件,若存在,则原文件被覆盖,成功返回一个文件描述符,失败返回-1

creat只能以只写的方式打开创建的文件,无法创建设备文件

文件打开操作完成之后需要关闭,调用close函数关闭,参数为打开时得到的文件描述符,但close调用成功并不保证数据能全部写回硬盘

6. 文件的读写

读数据可使用read系统调用,返回值为实际读取的字节数,若返回0表示已到达文件尾或无可读数据,文件读写指针也会随着读取到的字节移动。

写数据可调用write,返回值为写入字节数,文件读写指针也会随之移动。

7.文件读写指针的移动

每一个已打开的文件都有一个读写位置,当打开的文件时一般指向文件的开头,若是以添加的方式打开(O_APPEND),则读写位置指向文件尾。

文件指针的偏移,使用lseek来移动文件读写指针的位置:off_t lseek(int fildes, off_t offset, int whence);参数whence有以下3种取值:

SEEK_SET:从文件开始出计算偏移量,文件指针到文件开始处的距离为off_set

SEEK_CUR:从文件指针的当前位置开始计算偏移量,文件指针等于当前指针值加上offset的值,offset值允许取负数

SEEK_END:从文件结尾处开始就散偏移量,文件指针值等于当前指针值加上offset的值

lseek的常用用法:

将文件读写指针西东到文件开头: lseek(int fildes, 0, SEEK_SET);

将文件读写指针移动到文件结尾: lseek(int fildes, 0, SEEK_END);

获取文件读写指针当前的位置(相对于文件开头的偏离): lseek(int fildes, 0, SEEK_CUR);

0 0
原创粉丝点击