目录和文件

1.获取文件属性

创建一个名为-a的文件,touch -a是创建不了的,因为系统会把-a当作一个选项。任何命令+--表示当前命令选项完毕。touch -- -a成功。touch ./a也是可以的,rm  -a不行但是rm ./-a可以。

stat();fstat();lstat();

int stat(const char *path,struct stat *buf);通过路径

面对符号链接时获取的是所指向目标文件的属性

int  fstat(int fd,struct stat *buf);通过文件描述符

int  lstat(const char *path,struct stat *buf);通过路径

面对符号链接时,获取的是符号链接文件的属性

将属性信息传到结构体buf中去。成功返回0,失败返回-1并生成errno。

struct stat{

dev_t st_dev;  //包含当前设备ID名

ino_t st_ino;  //inde号,一个文件一个唯一的标号

mode_t st_mode; //权限信息 (16位整形数)基本位9位(777*3)粘住位 U+s位 g+s位

nlink_t st_nlink;  //硬连接数

uid_t st_uid;  //userID

gid_t  st_gid;//groupID

dev_t st_rdev;//当前拿到的是device,则是设备号

off_t st_size; //文件大小 (以字节为单位)

blksize_t st_blksize;//block的大小

blkcnt_t st_blocks;//当前文件占了多少512b的快

time_t st_atimes;//最后一次读的时间

time_t st_mtime;//最后一次写的时间

time_t st_ctime;//最后一次亚数据修改的时间

};

注意 st_size!=st_blksize*st_blocks;

st_size只是文件属性,并不是在磁盘上所占空间。空洞文件就是文件属性很大但是磁盘上所占空间非常小。st_blksize*st_blocks是文件真正在磁盘上占的空间。

下面我们创建一个空洞文件

#include "main.h"
#define _FILE_OFFSET_BITS 64
int main(int argc,char ** argv)
{
    if(argc<2)
    {
        fprintf(stderr,"Usage:%s,<destfile>",argv[0]);
        exit(1);
    }
    int fd;
    off_t len;
    fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0600);
    if(fd<0)
    {
        perror("open()");
        exit(1);
    }
    len=lseek(fd,5LL*1024*1024*1024-1LL,SEEK_SET);
    if(len<0)
    {
        perror("lseek()");
        exit(1);
    }    
    write(fd,"",1);
    close(fd);
    exit(0);
}
 

从这里我们可以看到文件大小为5G但是在磁盘上面的空间其实是8K

lseek(fd,5LL*1024*1024*1024-1LL);为什么要加单位呢,因为没有单位的值是没有意义的,当什么单位也没有,系统会默认给一个单位,当前默认为32位的有符号整数。如果不加单位会有溢出Waring但是已经是err,gcc编译器里面大部分waring就是err。我们要调试到除了一些我们能解释通的警告,没有其他警告。

cp命令也可证明这一点,我们使用cp命令复制上面程序生成的文件,只需要几秒,但是我们都知道你复制个几个G的文件是需要十几秒或者几十秒的。

执行过程:读一块,写一块,但是在写之间要进行检查,检查是不是空字符,如果是,那就记录不下,不写,再读一块写一块,写之前检查一下。如果还是那就还记录,直到读完,到现在还没有写一次,最后一下子在文件中一下子扯了你记录那么大的空间。

在linux中并不是文件有多大,在磁盘里面就有这么大的空间。window下是这样的。

有一个命令叫stat

#include "main.h"
#define _FILE_OFFSET_BITS  64
static off_t flen(const char* fname)
{
        struct stat statres;
        if(stat(fname,&statres)<0)
        {
                perror("stat()");
                exit(1);
        }
        return statres.st_size;
}
int main(int argc,char ** argv)
{
    if(argc<2)
    {
            fprintf(stderr,"Usage : %s,<destfile>",argv[0]);
            exit(1);
    }
    long long len;
    len=flen(argv[1]);
    printf("文件大小为:%lld\n",len);
    exit(0);
}
 

-rwxrwxrwx

第一个位置表示文件类型,dcb-lsp

d direction目录文件

c charcter special file字符设备文件

b block special file块设备文件

- regular file常规文件

l symbol link链接文件(符号链接文件)

s socket网络套接字socket文件

p pipe管道(特指命名管道,匿名管道在磁盘上看不到)

程序:识别文件类型

#include "main.h"
static int fType(const char *Fname);
static char *ftype(const char* FNAME)
{
    struct stat *statres=NULL;
    char* mode=NULL;
    mode=malloc(sizeof(char));
    *mode='-';
    static char mode1='0';
    statres=malloc(sizeof(struct stat));
       if(stat(FNAME,statres)<0)
    {
        perror("stat()");
        exit(1);
    }
    if(S_ISREG(statres->st_mode))
        {
            return mode ;
        }
        return &mode1;
}
/*
返回值类型可以是char 我这样写是变复杂了。
*/
int main(int argc,char **argv)
{
    if(argc<2)
    {
        fprintf(stderr,"Usage : %s <destfile>",argv[0]);
        exit(1);
    }
    printf("文件类型为:%c\n",*ftype(argv[1]));
    printf("文件类型位:%c\n",fType(argv[1]));
    exit(0);
}
    
static int fType(const char *Fname)
{
    struct stat statres;
    if(stat(Fname,&statres)<0)
    {
        perror("stat()");
        exit(1);
    }
    
    if(S_ISREG(statres.st_mode))
        return '-';
    else
        return '?';
}
 

得到文件权限的方法有两种,一种是通过宏来判断,也就是上面这种,虽然S_ISREG看着是一个函数但是它是通过带参宏来定义的。

另外一种是通过位图或和与来判断,其实就是S_ISREG的原型。

2.文件的访问权限

文件的范文权限是一个16位的位图,用于表示文件类型,文件的访问权限,及特殊权限位。

3.umask

在你创建文件时,给一个权限,把你给出的权限跟&~umsk,如果没给就是0666&~umask。

umask可以进行修改,命令输入umask  +你想修改成什么样的权限。

其实umask命令使用umask函数封装的。在进程中可以用umask函数调整权限,作用是防止产生权限过松的文件。

4.文件权限的更改/管理

chmod  chmod 权限 文件名

fchmod  

int chmod(const char *path,mode_t mode);

int fchmod(int fd,mode_t mode);

5.粘住位:t位

原本时给某一个可执行的二进制命令设置当前t位,设置t位是为了把某一个命令的使用痕迹进行保留,为了下次转载这个模块比较快。

现在常用数据块就会留在内存里面。

现在常用给目录设置t位。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白羊羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值