二.linux应用&网络编程之文件属性

·有道云笔记地址,详细戳这:http://note.youdao.com/noteshare?id=c3acd730a7443727b1db74d2d44e9ac9&sub=BAD34E04DC5A4AC8AF1FB1F6F149D42D

目录

一、linux中各种文件类型

二、文件属性

1、文件属性概述

2、文件属性函数

2.1、stat

2.2、fstat

2.3、lstat

2.4stat函数三种形态: 

3、函数原型和头文件

4、测试stat函数部分功能(具体函数头文件包含,用man命令)

5、stat函数的应用案例 E:\Linux\3.AppNet\2.fileproperty\3.2.2

用代码判断文件权限设置

access函数检查权限设置E:\Linux\3.AppNet\2.fileproperty\3.2.3

chown修改文件/目录所属拥有者和组。(改文件的属主与属组)

chgrp是修改文件或目录所属组。(只是更改文件的属组)

chmod修改文件的各种权限属性。chmod命令只有root用户才有权利去执行修改。

三、目录文件函数 E:\Linux\3.AppNet\2.fileproperty\3.2.4

1、opendir与readdir函数

主要函数如下:

目录文件信息结构体dirent:

具体用法如下:

2、目录操作函数scandir

函数原型

遍历目录函数:


一、linux中各种文件类型

Linux—— 一切皆是文件,linux将文件分为7个种类

  • 普通文件 (-) :

文本文件 和 二进制文件

  • 目录文件 (d) :

能vi打开,但是需要特殊api来读写的文件

  • 字符设备文件 (c)
  • 块设备文件 (b) :

文件系统虚拟出来的文件,如/dev /sys /proc,大多数不 直接读写,用特殊api,驱动时用

  • 管道文件 (p) :

管道通信

  • 套接字文件 (s) :

socket

  • 符号链接文件 (l):

软链接、硬链接

 

二、文件属性

1、文件属性概述

Linux 文件的属性主要包括:文件的节点、种类、权限模式、链接数量、所归属的用户和用户组、最近访问或修改的时间等内容。文件属性示例如下:

第一字段:文件类型和权限

第二字段:硬链接数

第三字段:所属用户

第四字段:所属用户组

第五字段:文件大小

第六字段:最后访问或修改时间

第七字段:文件名

 

 

2、文件属性函数

Linux 命令: stat xxx.c获取文件属性 

stat指令是根据stat这个api得到的应用

 

  • 2.1、stat

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

path:文件的路径,buf:指向存储文件信息的数据结构的指针

  • 2.2、fstat

int fstat(int fd, struct stat *buf);

fd:文件描述符,buf:指向存储文件信息的数据结构的指针

  • 2.3、lstat

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

path:文件的路径,buf:指向存储文件信息的数据结构的指针

用于查阅链接文件的文件属性

 

  • 2.4stat函数三种形态: 

stat : 不打开文件,读文件属性(在磁盘中读) 

fstat : 若文件打开,读已经打开的文件属性(效率更高,在内存读) 

lstat : 读符号链接文件本身的属性(stat、fstat会追溯指向文件的属性)

 

 

3、函数原型和头文件

#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);

成功返回0,错误返回-1,并设置errno全局变量

 

  • 举例详解结构体stat原型

struct stat {

 dev_t     st_dev;     /* ID of device containing file */

   ino_t     st_ino;     /* inode number */

   mode_t    st_mode;    /* protection */

   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; /* blocksize for file system I/O */

   blkcnt_t  st_blocks;  /* number of 512B blocks allocated */

   time_t    st_atime;   /* time of last access */

   time_t    st_mtime;   /* time of last modification */

   time_t    st_ctime;   /* time of last status change */

           };

结构体各个成员表示含义:

st_dev:文件所在磁盘的磁盘的ID号

st_ino:节点编号

st_mode:描述文件的类型和权限

st_nlink:硬链接的数量

st_uid:文件属于用户的ID

st_gid:文件所属用户组ID

st_rdev:如果是设备文件则是设备ID号

st_size:文件大小

st_blksize:文件内容对应的块的大小

st_blocks:文件内容对应得块数量

time_t     st_atime;      //文件最后被访问的时间

time_t     st_mtime;      //文件内容最后被修改的时间

time_t     st_ctime;      //文件状态改变时间

 

 

4、测试stat函数部分功能(具体函数头文件包含,用man命令)

E:\Linux\3.AppNet\2.fileproperty\3.2.1

#define Name "1.txt"

int main(void)

{

int dout=-1;

struct stat buf;

memset(&buf,0,sizeof(buf));//memset后buf中全是0

dout=stat(Name,&buf);//stat后buf就有内容了

if(dout<0)//失败

{

perror("stat error");

exit(-1);

}

//成功获取了stat结构体,从中打印出各种文件属性信息

printf("st_nlink=%d.\n",buf.st_nlink);

printf("st_size=%d.\n",buf.st_size);

printf("st_mode=%d.\n",buf.st_mode);

return 0;

}

测试程序中调用stat函数和直接在ubuntu中使用stat命令打印信息相同。

 

5、stat函数的应用案例 E:\Linux\3.AppNet\2.fileproperty\3.2.2

  • 用代码判断文件类型

 文件的文件类型和文件权限存在于文件属性数据结构中的st_mode成员。为了使用st_mode检查文件类型,POSIX标准定义了如下的宏:

 

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.)

譬如S_ISREG宏返回值是1表示这个文件是一个普通文件,如果文件不是普通文件则返回值是0.

具体用法如下:

#if 1

// 判断这个文件类型

char result;

if(S_ISREG(buf.st_mode))//普通文件 (-)

{

result='-';

printf("result = %c\n", result);

}

else if(S_ISDIR(buf.st_mode))//目录文件 (d)

{

result='d';

printf("result = %c\n", result);

}

else if(S_ISCHR(buf.st_mode))//字符设备文件 (c)

{

result='c';

printf("result = %c\n", result);

}

else if(S_ISBLK(buf.st_mode))//块设备文件 (b) :

{

result='b';

printf("result = %c\n", result);

}

else if(S_ISFIFO(buf.st_mode))//管道文件 (p) :

{

result='p';

printf("result = %c\n", result);

}

else if(S_ISLNK(buf.st_mode))//符号链接文件 (l):

{

result='l';

printf("result = %c\n", result);

}

else if(S_ISSOCK(buf.st_mode))//套接字文件 (s) :

{

result='s';

printf("result = %c\n", result);

}

 

#endif

 

  • 用代码判断文件权限设置

st_mode中还包含了文件的权限信息

 

S_IFMT     0170000   bit mask for the file type bit fields

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

S_ISUID    0004000   set UID bit

S_ISGID    0002000   set-group-ID bit (see below)

S_ISVTX    0001000   sticky bit (see below)

S_IRWXU    00700     mask for file owner permissions//用户权限掩码

S_IRUSR    00400     owner has read permission

S_IWUSR    00200     owner has write permission

S_IXUSR    00100     owner has execute permission

S_IRWXG    00070     mask for group permissions//组权限掩码

S_IRGRP    00040     group has read permission

S_IWGRP    00020     group has write permission

S_IXGRP    00010     group has execute permission

S_IRWXO    00007     mask for permissions for others //掩码

S_IROTH    00004     others have read permission

S_IWOTH    00002     others have write permission

S_IXOTH    00001     others have execute permission

具体用法如下:

#if 1

// 文件权限测试

unsigned char ownrd,ownwt,ownet,grprd,grpwt,grpet,othrd,othet,othwt;

if(buf.st_mode & S_IRUSR)

ownrd='r';

printf("result = %c\n", ownrd);

if(buf.st_mode & S_IWUSR)

ownwt='w';

printf("result = %c\n", ownwt);

if(buf.st_mode & S_IXUSR)

ownet='x';

printf("result = %c\n", ownet);

if(buf.st_mode & S_IRGRP)

grprd='r';

printf("result = %c\n", grprd);

if(buf.st_mode & S_IWGRP)

grpwt='w';

printf("result = %c\n", grpwt);

if(buf.st_mode & S_IXGRP)

grpet='x';

printf("result = %c\n", grpet);

if(buf.st_mode & S_IROTH)

othrd='r';

printf("result = %c\n", othrd);

if(buf.st_mode & S_IWOTH)

othwt='w';

printf("result = %c\n", othwt);

if(buf.st_mode & S_IXOTH)

othet='x';

printf("result = %c\n", othet);

#endif

 

  • access函数检查权限设置E:\Linux\3.AppNet\2.fileproperty\3.2.3

ccess函数可以测试得到当前执行程序的那个用户在当前那个环境下对目标文件是否具有某种操作权限。

#define name "2.txt"

int main(void)

{

int ret=-1;

ret=access(name,F_OK);

if(ret<0)

{

printf("文件不存在\n");

return -1;

}

else

{

printf("文件存在 ");

}

ret=access(name,R_OK);

if(ret<0)

{

printf("不可读\n");

return -1;

}

else

{

printf("可读 ");

}

ret=access(name,X_OK);

if(ret<0)

{

printf("不可写\n");

return -1;

}

else

{

printf("可写\n");

}

return 0;

}

 

 

  • chown修改文件/目录所属拥有者和组。(改文件的属主与属组)

#chown guest:guest a.txt

#chown -R guest /home/berry (把berry文件下的所有文件都改成guest这个组)

 

  • chgrp是修改文件或目录所属组。(只是更改文件的属组)

#chgrp -R guest /var/tmp/f.txt

#chgrp - R root /home/berry/file/a.txt 

 

  • chmod修改文件的各种权限属性。chmod命令只有root用户才有权利去执行修改。

#chmod 777 /home/berry

#chmod u+x /home/berry

操作对象who可是下述字母中的任一个或者它们的组合:

  • u 表示“用户(user)”,即文件或目录的所有者。
  • g 表示“同组(group)用户”,即与文件属主有相同组ID的所有用户。
  • o 表示“其他(others)用户”。
  • a 表示“所有(all)用户”。它是系统默认值。

 

 

 

三、目录文件函数 E:\Linux\3.AppNet\2.fileproperty\3.2.4

  Linux中目录也是文件,目录操作函数为标准IO库函数。

 

1、opendir与readdir函数

  • 主要函数如下:

#include <sys/types.h>

#include <dirent.h>

 

DIR *opendir(const char *name);

DIR *fdopendir(int fd);

 

成功返回一个指向目录流的指针,失败返回NULL,并且设置errno全局变量。

 

#include <dirent.h>

 

struct dirent *readdir(DIR *dirp);

 

成功返回一个指向目录 dirent结构的指针,如果到达目录流结尾或错误返回NULL。

读取目录文件 opendir函数打开一个目录后,得到一个DIR指针给readdir使用 readdir返回一个struct dirent(dir entry)类型的指针,指向一个结构体变量,记录着目录中的一个子文件

readdir调用一次,只能读取一个文件。要读取n个文件必须n次调用。

readdir函数内部会记忆哪个目录项已经被读过了哪个还没读,所以多次调用后不会重复返回已经返回过的目录项。

当readdir函数返回NULL时就表示目录中所有的目录项已经读完了

 

  • 目录文件信息结构体dirent:

struct dirent {

     ino_t          d_ino;       /* inode number */

     off_t          d_off;       /* offset to the next dirent */

     unsigned short d_reclen;    /* length of this record */

     unsigned char  d_type;      /* type of file; not supported

                                 by all file system types */

     char           d_name[256]; /* filename */

      };

 

  • 具体用法如下:

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;

}

 

sudo apt-get install gparted

2、目录操作函数scandir

  • 函数原型

#include <dirent.h>

 

int scandir(const char *dirp,//目录名

struct dirent ***namelist,//返回目录列表

int (*filter)(const struct dirent *),//过滤目录,NULL不过滤

int (*compar)(const struct dirent **,const struct dirent **));//排序返回目录,NULL不排序

    成功返回目录内文件的数量,失败返回-1。

 

  • 遍历目录函数:

int traverse_dir(const char *path)

 

{

unsigned int cnt = 0;

struct dirent **dent;

 

unsigned int i = 0;

 

i = scandir(path, &dent, NULL, NULL);

 

while(*dent)

 

{

 

printf("name:[%s] \n", (*dent)->d_name);

 

dent++;

cnt++;

 

}

printf("总文件数为:%d\n", cnt);

return 0;

 

}

 

 

int main(int argc, char **argv)

{

if (argc != 2)

{

printf("usage: %s dirname\n", argv[0]);

return -1;

}

traverse_dir(argv[1]);

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值