【Linux应用编程】文件属性

一.文件类型有哪些,怎么看,怎么用

 1.文件类型

  普通文件(- regular file),包括文本文件和二进制文件

  目录文件(d directory),本身不适合用普通的方式来读写,linux中是使用特殊的一些API来专门读写文件夹的

  字符设备文件(c character),设备文件对应的是硬件设备,也就是说这个文件虽然在文件系统中存在,但是并不是真正存在于硬盘上的一个文件,而是文件系统虚拟制造出来的(叫虚拟文件系统,如/dev /sys /proc等)

  管道文件(p pipe)

  套接字文件(s socket)

  符号链接文件(l link)

2.怎么看,怎么用

  命令行中:stat 文件名

  C程序中: 

int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);

struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */

/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */

struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */

#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};

linux中文件类型宏定义(man 7 inode中查看)

S_IFMT     0170000   bit mask for the file type bit field
S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO

Thus, to test for a regular file (for example), one could write:

 stat(pathname, &sb);
 if ((sb.st_mode & S_IFMT) == S_IFREG) {
  /* Handle regular file */
 }

或者用下面的判断的方法

S_ISREG(m)  is it a regular file?

S_ISDIR(m)  directory?

S_ISCHR(m)  character device?

S_ISBLK(m)  block device?

S_ISFIFO(m) FIFO (named pipe)?

S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

The preceding code snippet could thus be rewritten as:

stat(pathname, &sb);
if (S_ISREG(sb.st_mode)) {
/* Handle regular file */
}

3.fstat和stat的区别是:stat是从文件名出发得到文件属性信息结构体,而fstat是从一个已经打开的文件fd出发得到一个文件的属性信息。所以用的时候如果文件没有打开(我们并不想打开文件操作而只是希望得到文件属性)那就用stat,如果文件已经被打开了然后要属性那就用fstat效率会更高(stat是从磁盘去读取文件的,而fstat是从内存读取动态文件的)。
lstat和stat/fstat的差别在于:对于符号链接文件,stat和fstat查阅的是符号链接文件指向的文件的属性,而lstat查阅的是符号链接文件本身的属性。

二.文件权限有哪些,怎么看,怎么改

 1.怎么看

  命令行中:ls -l

  打印出的权限列表
  (1)123456789一共9位,3个一组。第一组三个表示文件的属主(owner、user)对该文件的可读、可写、可执行权限;第2组3个位表示文件的属主所在的组(group)对该文件的权限;第3组3个位表示其他用户(others)对该文件的权限。
  (2)属主就是这个文件属于谁,一般来说文件创建时属主就是创建这个文件的那个用户。但是我们一个文件创建之后还可以用chown命令去修改一个文件的属主,还可以用chgrp命令去修改一个文件所在的组。

  C程序中:st_mode位用来检查权限,宏定义如下

The  following  mask values are defined for the file mode component of
       the st_mode field:

S_ISUID     04000   set-user-ID bit (see execve(2))
S_ISGID     02000   set-group-ID bit (see below)
S_ISVTX     01000   sticky bit (see below)

S_IRWXU     00700   owner has read, write, and execute permission
S_IRUSR     00400   owner has read permission
S_IWUSR     00200   owner has write permission
S_IXUSR     00100   owner has execute permission

S_IRWXG     00070   group has read, write, and execute permission
S_IRGRP     00040   group has read permission
S_IWGRP     00020   group has write permission
S_IXGRP     00010   group has execute permission

S_IRWXO     00007   others (not in group) have read,  write,  and
                               execute permission
S_IROTH     00004   others have read permission
S_IWOTH     00002   others have write permission
S_IXOTH     00001   others have execute permission


stat(pathname, &sb); if (sb.st_mode & S_IRUSR) { //... }

此外,还有access函数用来检查权限

 int access(const char *pathname, int mode);

mode可以是R_OK,W_OK,X_OK,分别是读写和执行权限检查,有权限函数返回0,无权限返回-1

2.怎么改

  chmod修改文件权限,命令行中:https://www.runoob.com/linux/linux-comm-chmod.html

  C文件中:

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

  函数返回0修改成功,返回-1修改失败

  chown修改文件属主:https://www.runoob.com/linux/linux-comm-chown.html

  umask用来设定系统中新创建的文件的默认权限的

mode_t umask(mode_t mask);

三.目录文件的读取

opendir与readdir函数

(1)opendir打开一个目录后得到一个DIR类型的指针给readdir使用
(2)readdir函数调用一次就会返回一个struct dirent类型的指针,这个指针指向一个结构体变量,这个结构体变量里面记录了一个目录项(所谓目录项就是目录中的一个子文件)。
(3)readdir调用一次只能读出一个目录项,要想读出目录中所有的目录项必须多次调用readdir函数。readdir函数内部户记住哪个目录项已经被读过了哪个还没读,所以多次调用后不会重复返回已经返回过的目录项。当readdir函数返回NULL时就表示目录中所有的目录项已经读完了。

例程:

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>


int main(int argc, char **argv)
{
    DIR *pDir = NULL;
    struct dirent * pEnt = NULL;
    unsigned int cnt = 0;
    
    if (argc != 2)
    {
        printf("usage: %s dirname\n", argv[0]);
        return -1;
    }
    
    pDir = opendir(argv[1]);
    if (NULL == pDir)
    {
        perror("opendir");
        return -1;
    }
    
    while (1)
    {
        pEnt = readdir(pDir);
        if(pEnt != NULL)
        {
            // 还有子文件,在此处理子文件
            printf("name:[%s]    ,", pEnt->d_name);
            cnt++;
            if (pEnt->d_type == DT_REG)
            {
                printf("是普通文件\n");
            }
            else
            {
                printf("不是普通文件\n");
            }
        }
        else
        {
            break;
        }
    };
    printf("总文件数为:%d\n", cnt);
    
    
    return 0;
}
 struct dirent *readdir(DIR *dirp);
struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值