Linux操作系统-文件(3)

Linux操作系统—文件(3)

分类:Linux操作系统

文件属性的修改

改变文件的所有者

  使用chown系列函数可以改变文件的所有者,同时还可以改变文件的所属组。这些函数的原型如下:

#include <sys/types.h>
#include <unistd.h>
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, git_t group);

  成功时返回0,失败时返回-1
  chown和lchown的区别:当一个文件是一个符号连接时,lchown改变的是该符号连接本身的所有者,而chown改变的是该连接指向的文件的所有者。
  因为涉及到了管理权限的问题,只有root用户才可以使用这些函数来改变任意文件的所有者和所属组,而普通用户只能改变属于自己的文件的所属组,并且指定的所属组只能是用户自身所在组之一。

改变文件的访问权限

  使用chmod系列函数可以改文件的访问权限

#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *pathname, modt_t mode);
int fchmod(int fd, modt_t mode);

  其中mode为文件的权限。一般由一组八进制数进行二进制“或”运算构成,其中的各个位表示一种权限,称为权限位,如下:

权限位 八进制常量 含义
S_ISUID 04000 设置SUID
S_ISGID 02000 设置SGID
S_ISVTX 01000 设置粘滞位
S_IRUSR 00400 文件所有者可读
S_IWUSR 00200 文件所有者可写
S_IXUSR 00100 文件所有者可执行
S_IRGRP 00040 文件所属组可读
S_IWGRP 00020 文件所属组可写
S_IXGRP 00010 文件所属组可执行
S_IROTH 00004 其它用户可读
S_IWOTH 00002 其它用户可写
S_IXOTH 00001 其它用户可执行

  成功时返回0,出错返回-1

重命名文件

  普通文件和目录文件均可以使用rename函数重命名,该函数原型如下:

#include <stdio.h>
int rename(const char *oldpath, const char *newpath);

复制文件描述符

  复制文件描述符需要用到dup或dup2函数,这两个函数常用于重定向一个已打开的文件描述符。其原型如下:

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);

  这两个函数都将返回复制后的文件描述符,不同的是,dup函数返回的是最小未用的文件描述符,而dup2函数返回的是预先指定的文件描述符newfd。如果newfd正在使用,则会先关闭newfd。但如果newfd与oldfd一样,则关闭文件正常返回。

上锁和解锁文件

  Linux下可以调用flock函数来上锁或解锁一个文件。该函数原型如下:

#include <sys/file.h>
int flock(int fd, int operaation);

  函数各参数和返回值含义如下:
- fd:文件描述符
- operation:上锁或解锁方式,可取以下值之一

  • LOCK_SH:共享锁
  • LOCK_EX:独占锁
  • LOCK_UN:解锁

  • 返回值:成功时返回0,失败时返回-1

  一个进程对一个文件只能有一个独占锁,但可以有多个共享锁。上锁的作用只有在别的进程要对该文件上锁时才能表现出来。如果一个进程不试图去上锁一个已经被上锁的文件,就不应该对其进行访问。
  应当注意:对文件的操纵本身与锁并没有什么关系。无论文件是否被上锁,用户都可以随便对文件进行正常情况下的任何操作。上锁文件的目的是为了同步多个进程之间的操作,参与同步的各进程必须遵守约定的规则,上锁才有意义。
  默认情况下,flock是阻塞式的。也就是说,如果另一个进程已持有该文件的锁且该锁与本进程请求的锁不兼容,flock将会阻塞,直到拥有该文件的锁的进程对其解锁为止。如果要进行非阻塞式调用。应将operation参数与常量”LOCK_NB”进行二进制”或“操作后再传递给flock函数。非阻塞式调用flock后,flock会立即返回-1, 并且errno的值将为EWOULDBLOCK。

创建硬链接

  调用link函数可以对一个已经存在的文件建立新的链接

#include <unistd.h>
int link(const char *oldpath, const char *newpath);

  使用link创建的新的链接文件和原文件是一模一样的,地位是对等的,它们都指向相同的文件。创建之后,就没有必要也无法区分哪个是原始文件了。

创建和读取符号链接

#include <unistd.h>
int symlink(const char *oldpath, const char *newpath);

  注意:符号链接文件的权限和原文件的权限是无关的

读取符号链接

  读取符号链接所指向的目标文件需要使用系统调用readlink函数,该函数原型如下:

#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsize);

  函数各参数和返回值的含义如下:
- path:符号链接文件名
- buf:用于存储获取到的信息的缓冲区
- bufsize:缓冲区大小
- 返回值:若成功为实际写入缓冲区的字节数;若出错为-1,错误记录在errno

删除链接

  要删除链接,包括硬链接和符号链接,可通过系统调用unlink函数实现,该函数原型如下:

#include <unistd.h>
int unlink(const char *pathname);

目录文件的操作

目录文件的创建

  创建目录文件使用mkdir函数,该函数原型如下:

#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);

  各参数和返回值含义如下:
pathname:新建的目录文件名
mode:存取许可权位,由下列一个或多个常数进行或运算构成。最终权限受系统变量umask限制
- S_IRUSR:文件所有者读
- S_IWUSR:文件所有者写
- S_IXUSR:文件所有者执行
- S_IRGRP:组用户可读
- S_IWGRP:组用户可写
- S_IXGRP:组用户可执行
- S_IROTH:其它用户可读
- S_IWOTH:其它用户可写
- S_IXOTH:其它用户可执行

目录文件的删除

#include <unistd.h>
int rmdir(const char *pathname);

注意:使用rmdir函数只能删除空的目录,如果pathname所指定的目录中含有文件,则函数调用将失败

目录的打开和关闭

打开目录文件

&emap; 打开目录文件可使用opendir函数(非系统调用),原型如下:

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);

  函数调用成功则返回指向目录文件的结构指针;若出错为NULL,错误记录在errno中
  如果opendir函数执行成功会返回一个目录流(directory stream),该流定位在目录块的第一项。

关闭目录文件

#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *drip);

函数各参数和返回值的含义如下:
dirp:已打开的目录流
返回值:成功返回0,出错返回-1

目录文件的读取

#include <dirent.h>
struct dirent *readdir(DIR *dirp);

  函数各参数和返回值含义如下:
返回值:若成功为下一个目录项的指针;若已达到目录流末尾则返回NULL且errno值不变;若出错为NULL,错误记录值记录在errno中
  函数返回的结构体类型如下:

struct dirent{
    ino_t           d_ino;          //索引节点
    off_t           d_off;          //下一目录项的位移量
    unsigned short  d_reclen;       //本记录的长度
    unsigned char   d_type;         //文件类型
    char            d_name[256];    //文件名
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章