Linux系统编程7之文件和目录管理。

0:基本介绍:
  在LINUX系统中,每一个文件都对应一个inode(索引结点),其是由文件系统中唯一数值编码,该数值称为inode编号。inode即是UNIX类的文件系统的物理对象,也是LINUX内核数据结构描述的概念实体,inode储存了与文件相关的元数据。相同文件系统中inode唯一,不同文件系统中不一定。

linux目录结构是树结构。

1.一组stat函数。

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

int stat(const char* path,struct stat* buf);
int fstat(int fd,struct stat* buf);
int lstat(const char* path,struct stat* buf);

STAT函数会返回指定路径的文件信息并存储在结构体STAT中
FSTAT函数会返回由文件描述符FD指向的文件信息。
lstat函数是对于符号链接,其返回的是链接本身,而非目标文件。

三个函数查询的结果都返回在stat结构体中,
调用失败返回-1.

下面介绍stat结构体。

主要注意第三个位置,其记录的是文件的用户组,所有者等的读写权限和文件类型

st_mode分类如下(只给出权限宏,文件类型宏用的少,自行查阅):以下宏是对于调用open/creat函数创造新文件时进行赋予的文件权限,而不是O_()的宏,后者是以什么方式进行操作文件,这是两个不同,要区别。操作文件的方式不能和创造文件时的权限冲突。

其他stat结构体成员如下:

如下代码例子,查看文件是啥类型:

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

int main(int argc,char* argv[]){
    struct stat sb;
    int ret;
    
    if(argc<2){
        std::cout<<"not enough"<<std::endl;
        exit(0);
    }

    ret=stat(argv[1],&sb);
    if(ret){
        perror("stat error");
        exit(0);
    }
    
    std::cout<<"file type :";
    switch (sb.st_mode&S_IFMT)//与运算
    {
    case S_IFBLK:
         std::cout<<"block device node\n";
        break;
    case S_IFCHR:
          std::cout<<"character device node\n";
          break;
    case S_IFDIR:
          std::cout<<"director\n";
          break;
    case S_IFIFO:
           std::cout<<"ifio\n";
           break;
    default:
           std::cout<<"other \n";
           break;
    }
      return 0;

}

2.文件权限的系统调用(和黑框命令修改差不多)。

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


int chmod(const char* path,mode_t mode);
int fchmod(int fd,mode_t mode);
上述两个函数都可以将文件权限修改为参数mode指定值,
前者是需要用到相对路径或者绝对路径,后者是由文件描述符。
mode_t是参数mode的合法值,这些常量能执行二进制或运算
调用成功返回0,失败返回-1.

int ret;
      ret=chmod("/home/user/map.png",S_IRUSR|S_IWUSR);
      /*将此文件权限设置为所有者可读,所有者可写*/

对于修改所有权(所属用户组那些)和文件的扩展操作不做介绍,学习黑框命令即可。

3.目录:

LINUX系统中,目录就是包含一个文件列表名,每个文件名映射一个INODE编号,每个文件称之为目录项,目录当然还可能包含其他目录,子目录。路径名由文件名及其一级或者多级父目录组成的,绝对目录是从根目录开始的,相对目录从当前所在目录开始。每个进程都有一个当前目录,一般是创建时从父进程继承而来。

3.1) 获得当前目录:

#include <unistd.h>

char* getcwd(char* buf,size_t size);
调用成功时,会将当前工作目录以绝对路径的方式拷贝到buf中,buf长为size,
并且返回一个指向buff的指针,拷贝失败返回NULL。
注意size的长度要确保能存放目录

char* t;
t=getwcd(NULL,0);//获得当前工作目录,不包含文件名

3.2)改变当前工作目录(黑框对应的操作是cd):

#include <unistd.h>

int chdir(const char* path);
int fchdir(int fd);//是目录的文件描述符,不是文件
前者是将当前工作目录更改为path指定路径,可以是相对,也可以是绝对,
后者是会将当前工作目录更换为文件描述符指向的路径,fd必须是打开的目录。
成功返回0,失败返回-1.

int fd1=open("/home/user",O_RDONLY);//user目录的文件描述符

int a=fchdir(fd1);//当前工作目录转移到user目录下

3.3)创建目录:

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

 int mkdir(const char* path,mode_t mode);
调用此函数会创建PATH所指定的目录(可能是绝对路径,也可能是相对路径,其权限位为mode)并返回零。
shell命令的mkdir也是创建目录(把他当成一个文件夹)

若新目录的父目录拥有已设置的用户组ID位设置,或文件系统以BSD的组方式被挂截,新目录将继承父目录用户组从属关系,否则进程有效用户组ID将应用于新目录。

3.4)删除目录:
 

#include <unistd.h>

int rmdir(const char* path);
调用成功时,此函数会删除PATH指向的目录,并返回零,注意
PATH直线的目录必须为空,这与shell中的rmdir一致,且不能递归dfs删除(rm -f)

读取目录的系统调用不涉及,不如命令ls好用。

LINUX知识补充:

链接:目录中的每个名字至inode的映射被成为链接,即链接本质就是目录中一个指向inode的名字,所以没有限制inode的链接数目。

硬链接:硬连接指通过索引节点来进行连接。在 Linux 中,多个文件名 (一个文件包含一个目录项,目录项包含文件名和索引结点,索引结点指向磁盘内容)指向同一索引节点是存在的。比如:A 是 B 的硬链接(A 和 B 都是文件名,文件名不同,但inode相同),则 A 的目录项中的 inode 节点号与 B 的目录项中的 inode 节点号相同,即一个 inode 节点对应两个不同的文件名,两个文件名指向同一个文件,A 和 B 对文件系统来说是完全平等的。删除其中任何一个都不会影响另外一个的访问。文件的链接数量没有限制,链接为零的文件在文件系统中没有目录项。LINUX中,内核通过链接计数和使用计数来管理文件,后者是被打开的实例的计数,只有当某个文件的两个计数都为零,文件才会被删除(和软连接无关)。本质:允许一个文件拥有多个有效路径名。

软连接:其与硬链接都是指向文件系统中的文件。它是一种特殊的文件类型,软连接不会增加目录项。软连接可以是相对/绝对路径。软连接最大区别是,可以跨不同的文件系统,其可以指向任何位置。可以指向删除的文件(悬空符号链接),当文件删除时,软连接就是悬空的,删除软连接对文件本身无影响。

#include <unistd.h>

int link(const char* oldpath,const char* newpath);//绝对路径
创建硬链接,调用成功时,会为oldpath所指向的已存在的文件,在路径newpath下创建新的链接,并返回0,
oldpath的newpath指向相同的文件
/* 不能跨文件系统*/

int ret;
ret=link("/home/kidd/old","home/kidd/new");
调用成功,会创建新的目录项new,old,new指向相同文件。
新的目录项(文件)new会包含原来old的所有内容,这点注意


int symlink(const char* oldpath,const char* newpath);
调用成功 创建符号链接new指向oldpath表示的文件。


int unlink(const char* pathname);
删除链接,即从文件系统中删除路径名,若该文件是最后一个硬链接,
则文件被删除。若是符号链接,则只会删除链接,不影响目标文件。
注意unlink不会删除目录,可以用rmdir()

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值