linux目录和文件

一、目录和文件
获取文件的属性信息:
stat(文件路径,文件属性结构体):通过文件路径获取到文件的属性,获取到的文件属性回填到文件属性结构体中
返回值:成功返回0,失败返回-1并设置errno
文件属性结构体的构成:
st_dev:包含该文件的设备号
st_ino:inode号
st_mode:文件的类型和权限信息
st_nlink:硬链接数
st_uid:用户id
st_gid:组id
st_rdev:设备id号
st_size:文件大小,单位字节
st_blksize:块的大小
st_blocks:块数
st_atime:最后一次访问时间
st_mtime:最后一次修改时间
st_ctime:最后一次改变时间(只属性,也就是亚数据)

做一个flen的案列

st_mode值判定文件类型的带参宏使用:
S_ISREG(m):是否是普通文件   m----->s.st_mode
S_ISDIR(m):是否是目录文件
S_ISCHR(m):是否是字符设备文件
S_ISBLK(m):是否是块设备文件
S_ISFIFO(m):是否是管道文件
S_ISLNK(m):是否是符号链接文件
S_ISSOCK(m):是否是网络套接字文件

例子:

static char getflty(struct stat s)
{
if(S_ISREG(s.st_mode))
return '-';
if(S_ISDIR(s.st_mode))
return 'd';
if(S_ISCHR(s.st_mode))
return 'c';
if(S_ISBLK(s.st_mode))
return 'b';
if(S_ISFIFO(s.st_mode))
return 'p';
if(S_ISLNK(s.st_mode))
return 'l';
if(S_ISSOCK(s.st_mode))
return 's';
}


st_mode值判定文件类型及权限的宏值使用:
S_IFMT:文件类型的字段位,使用st_mode 按位与上该宏值得到的结果与以下比较判断文件的类型
S_IFSOCK:网络套接字文件
S_IFLNK:连接文件
S_IFREG:普通文件
S_IFBLK:块设备文件
S_IFDIR:目录文件
S_IFCHR:字符设备文件
S_IFIFO:管道文件

S_ISUID:U+S权限
S_ISGID:G+S权限
S_ISVTX:O+T文件的粘滞位

S_IRWXU:文件所属主用户的权限段位,使用st_mode按位与上该宏值得到的结果如果为真那么
代表该文件拥有可读可写可执行的权限
S_IRUSR:文件所主组用户的可读权限
S_IWUSR:文件所主组用户的可写权限
S_IXUSR:文件所主组用户的可执行权限

S_IRWXG:文件所属组用户的权限段位,使用st_mode按位与上该宏值得到的结果如果为真那么
代表该文件所属组拥有可读可写可执行的权限
S_IRGRP:文件所属组用户的可读权限
S_IWGRP:文件所属组用户的可写权限
S_IXGRP:文件所属组用户的可执行权限

S_IRWXO:其他用户的权限段位,使用st_mode按位与上该宏值得到的结果如果为真那么
代表该文件其他用户拥有可读可写可执行的权限
用户的读写执行权限
S_IROTH:其他用户的可读权限
S_IWOTH:其他用户的可写权限
S_IXOTH:其他用户的可执行权限

char *getquanxian(struct stat s)
{
//char arr[10];
char *arr = malloc(10);

arr[0] = s.st_mode & S_IRUSR ? 'r':'-';
arr[1] = s.st_mode & S_IWUSR ? 'w':'-';
arr[2] = s.st_mode & S_IXUSR ? 'x':'-';
arr[3] = s.st_mode & S_IRGRP ? 'r':'-';
arr[4] = s.st_mode & S_IWGRP ? 'w':'-';
arr[5] = s.st_mode & S_IXGRP ? 'x':'-';
arr[6] = s.st_mode & S_IROTH ? 'r':'-';
arr[7] = s.st_mode & S_IWOTH ? 'w':'-';
arr[8] = s.st_mode & S_IXOTH ? 'x':'-';


arr[9] = '\0';


return arr;

}


fstat(文件描述符,文件属性结构体):通过文件描述符获取到文件的属性,获取到的文件属性回填到文件属性结构体中
返回值:成功返回0,失败返回-1并设置errno

lstat(文件路径,文件属性结构体):和stat函数的功能是一致的,但在获取符号链接文件时两个函数有一定的区别,
sata获取到的是符号链接指向的文件的属性,而lstat获取到的是符号链接本身的权限

文件权限更改:
chmod(文件路径,权限值):更改指定路径文件的权限,成功返回0,失败返回-1并且设置errno
fchmod(文件描述符,权限值):更改指定已打开文件的权限,成功返回0,失败返回-1并且设置errno

unlink(文件路径):从磁盘中删除一个文件,成功返回0,失败返回-1并设置errno

link(原文件,新的硬链接文件):为一个指定文件创建一个硬链接文件,成功返回0,失败返回-1并设置errno

rename(原文件,新的文件):改变文件的名称或name,封装的命令是mv,成功返回0,失败返回-1并设置errno

mkdir(目录名称,权限):创建一个目录文件,注意umask值会影响权限,成功返回0,失败返回-1并设置errno
rmdir(目录名称):删除一个目录文件,必须是空目录

getcwd(缓存,缓存大小):获取到当前的工作路径,填充到缓存中,
成功返回一个指针指向当前工作路径的字符串,失败返回NULL,并设置errno


#define BUFSIZE 1024


int main(void)
{

char buf[BUFSIZE];

getcwd(buf,BUFSIZE); //获取当前工作目录的据对路径




puts(buf);


exit(0);
}

glob(pattern,特殊要求,函数指针,回填结构体): //读取当前目录文件到glb 结构体中
参数一:要解析的路径,可以带通赔符
参数二:需要多个特殊要求就使用按位或的形式进行传参
特殊要求:
GLOB_NOCHECK:如果没有匹配上正确与指定的pattern相等的字符串,就直接返回pattern
GLOB_APPEND:以追加的形式存放到结构体中的argv中,注意argv中是一个随机值,第一次不要追加

参数三:错误信息的函数
参数四:解析后的数据存入到该结构体中  

 glob_t glb;

getpwuid(用户id):根据用户的id来获取用户的详细信息,成功获取到的数据通过返回值带出一个结构体指针,
失败返回NULL并设置errno

atoi(字符串):将一个字符串转为整数

getpwnam(用户名):根据用户的名称来获取用户的详细信息,成功获取到的数据通过返回值带出一个结构体指针,
失败返回NULL并设置errno

getgrgid(组id):根据用户组的id来获取用户组的详细信息,成功获取到的数据通过返回值带出一个结构体指针,
失败返回NULL并设置errno

getgrgnam(用户组名称):根据用户组的名称来获取用户组的详细信息,成功获取到的数据通过返回值带出一个结构体指针,
失败返回NULL并设置errno



时间戳:
time_t是一个大整型
time():从内核中获取一个时间戳,如果参数为NULL,成功返回1970-01-01 00:00:00
距离当前时间所过去的秒数,失败返回-1并设置errno
如果参数不为空,成功将值存储到参数中,返回值与参数数据相同,失败返回-1并设置errno

gmtime(时间戳):将一个时间戳转为一个tm的结构体,成功返回值为结构体指针,
失败返回值为NULL,转为格林威治时间

localtime(时间戳):将一个时间戳转为一个tm的结构,成功返回值为结构体指针,
失败返回值为NULL,转为本地时间

mktime(时间结构体):将一个时间结构体转为一个时间戳,成功返回该时间戳,失败返回-1

strftime(缓存区地址,缓存区大小,格式化字符串,时间结构体指针):格式化时间日期

练习写文件:
1 2017-1-1 10:00:00
2 2017-1-1 10:00:01
3 2017-1-1 10:00:02
4 2017-1-1 10:00:03


buf

fp = fopen("/aa");

while(1)
{
fprintf(fp,"%d %s",i,buf);
fflush(fp);
sleep(1);
}
......
注意缓存模式

2.做一个程序,先输出当前日期,再输出100天以后的日期

./myls -l
argv[0] = "./myls";
argv[1] = "-l";

argc = 2;

./myls -l /etc/pwd

./mmplayer -H1202 -W1231


命令行分析:
getopt(参数的个数argc,参数的首地址argv,遍历的选项列表):分析出命令行参数中所指定的选项,
成功返回分析出的选项字符,失败返回-1




遍历的选项列表中如果选项后带有参数可以使用冒号:
例如:
"n:ab":n代表后面会跟有一个参数,且必须跟有一个,在命令行出-n 2
"n::ab":n后面可以跟有一个参数,也可以不跟

全局变量:
optarg:当选项是带参数的,那么遍历到该选项时,optarg便指向该选项后的参数
optind:获取到当前读取到的argv的下标的下一个位置

遍历的选项中加入一个-号:遍历选项中加入一个-号代表除了可以获取到选项外,还可以获取到非选项的传参
遇到非选项的传参函数返回值为1


myls 简单实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <glob.h>
#include <sys/types.h>
#include <sys/stat.h>


//ls 
//ls -l


#define BUFSIZE 1024


static char getflty(struct stat s)
{
if(S_ISREG(s.st_mode))
return '-';
if(S_ISDIR(s.st_mode))
return 'd';
if(S_ISCHR(s.st_mode))
return 'c';
if(S_ISBLK(s.st_mode))
return 'b';
if(S_ISFIFO(s.st_mode))
return 'p';
if(S_ISLNK(s.st_mode))
return 'l';
if(S_ISSOCK(s.st_mode))
return 's';
}


char *getquanxian(struct stat s)
{
//char arr[10];
char *arr = malloc(10);

arr[0] = s.st_mode & S_IRUSR ? 'r':'-';
arr[1] = s.st_mode & S_IWUSR ? 'w':'-';
arr[2] = s.st_mode & S_IXUSR ? 'x':'-';
arr[3] = s.st_mode & S_IRGRP ? 'r':'-';
arr[4] = s.st_mode & S_IWGRP ? 'w':'-';
arr[5] = s.st_mode & S_IXGRP ? 'x':'-';
arr[6] = s.st_mode & S_IROTH ? 'r':'-';
arr[7] = s.st_mode & S_IWOTH ? 'w':'-';
arr[8] = s.st_mode & S_IXOTH ? 'x':'-';


arr[9] = '\0';


return arr;
}


int main(int argc,char **argv)
{
int res;
char buf[BUFSIZE];
glob_t glb;
int i;
struct stat sta;
while(1)
{
res = getopt(argc,argv,"l");//分析出命令行参数中所指定的选项,
                                    //成功返回分析出的选项字符,失败返回-1
if(res < 0)
break;
switch(res)
{
case 'l':
getcwd(buf,BUFSIZE);//读取当前绝对路径地址
printf("%s",buf);
strcat(buf,"/*");// 添加在buf 末尾/*
printf("%s",buf);

glob(buf,0,NULL,&glb);//读取当前目录文件到glb 结构体中
for(i = 0 ; i < glb.gl_pathc; i++)
{
stat(glb.gl_pathv[i],&sta);
printf("%c%s\n",getflty(sta),getquanxian(sta));
}


break;
}
}


exit(0);

}

结果:



实现一个mydate:
要求:./mydate
输出:2017-10-11 10:00:00

./mydate -y
输出:2017




字符串分割:
strtok(要分割的字符串,分隔符):将一个字符串根据分割符分割成若干个子串,
每次返回一个子串,返回NULL代表分割结束
注意:在循环分割的过程中需要将参数1(要分割的字符串)制NULL

int main(void)
{
char arr[] = "192.168.1.123";
char *ptr = arr;
char *p = NULL;
while(1)
{
p = strtok(ptr,".");
if(p == NULL)
break;

puts(p);


ptr = NULL;
}


exit(0);

}

strsep(要分割的字符串的地址,分割符):根据分割符将第一个参数分割成若干子串,
返回值为每一个子串的首地址,返回NULL代表分割结束
int main(void)
{
char arr[] = "/bin/linux/pwd";
char *ptr = arr;
char *res = NULL;
while(1)
{
res =strsep(&ptr,"/");
if(res == NULL)
break;


puts(res);
}
    exit(0);
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值