Linux高级编程 8.14 目录操作

目录

一、操作目录相关函数

1.opendir

2.readdir

3.closedir 

4.chdir  (cd)

5.getcwd  (pwd) 

6.mkdir 

7.rmdir   (rm -r或rmdir)

8.stat

二、获取时间的相关函数

1.time

2.ctime

3.localtime

三、uid、gid

1.getpwuid

2.getgrgid


一、操作目录相关函数

1.opendir

DIR *opendir(const char *name);
功能:打开一个目录获得一个目录流指针
参数:
    name:目录名
返回值:
    成功返回目录流指针
    失败返回NULL

2.readdir

struct dirent *readdir(DIR *dirp);
功能:
    从目录流中读取文件信息并将保存信息的结构体地址返回
参数:
    dirp:目录流指针
返回值:
    包含文件信息的结构体
    出错或者读到目录流末尾返回NULL

通过man 3 readdir

struct dirent结构体有以下成员(不完整)
d_ino;
d_type;                                       
d_name[256]; 
 

d_type有以下宏

DT_BLK      This is a block device.块设备

DT_CHR      This is a character device.字符设备

DT_DIR      This is a directory.目录

DT_FIFO     This is a named pipe (FIFO).管道文件

DT_LNK      This is a symbolic link.软链接

DT_REG      This is a regular file.普通文件

DT_SOCK     This is a UNIX domain socket.套接字

DT_UNKNOWN

通过这些可以仿写ls命令

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

int main(int argc, const char *argv[])
{
	DIR * dir=opendir("./");
	if(dir==NULL)
	{
		fprintf(stderr,"opendir error\n");
		return 1;
	}

	while(1)
	{
		struct dirent * info=readdir(dir);
		if(info==NULL)
		{
			break;
		}
		switch(info->d_type)
		{
			case DT_DIR:
				printf("目录:");
				break;
			case DT_REG:
				printf("普通文件:");
				break;
			case DT_UNKNOWN:
				printf("其他文件:");
				break;
			default:
				printf("未知:");
				break;
		}
		printf("%s\n",info->d_name);
	}
	closedir(dir);
	
	return 0;
}

3.closedir 

int closedir(DIR *dirp);
 功能:关闭之前已经打开的目录流对象
 参数:opendir的返回结果中目录流对象
 返回值:
    成功 0
    失败 -1

4.chdir  (cd)

int chdir(const char *path);
功能:
    改变当前程序的工作路径
参数:
    path:改变到的路径
返回值:
    成功返回0
    失败返回-1

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int ret=chdir("..");//..表示上级目录
	if(-1==ret)
	{
		fprintf(stderr,"chdir error\n");
		return 1;
	}

	fopen("aaa","w");//用来检查是否切换到了上级目录
	
	return 0;
}

5.getcwd  (pwd) 

char *getcwd(char *buf, size_t size);
功能:
    获得当前的工作路径
参数:
    buf:保存工作路径空间的首地址
    size:保存路径空间的长度
返回值:
    成功返回包含路径空间的字符串首地址
    失败返回NULL

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	char buf[256]={0};
	char * ret=getcwd(buf,sizeof(buf));
	if(ret==NULL)
	{
		fprintf(stderr,"getcwd error\n");
		return 1;
	}
	printf("current path is: %s\n",buf);

	chdir("..");
	getcwd(buf,sizeof(buf));
	printf("change path is: %s\n",buf);
	
	return 0;
}

6.mkdir 

int mkdir(const char *pathname, mode_t mode);
功能:
    创建一个目录
参数:
    pathname:路径
    mode:
        mode & ~umask(0002)
返回值:
    成功返回0
    失败返回-1

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

int main(int argc, const char *argv[])
{
	int ret=mkdir("hhh",0777);//前导0不要忘
	if(-1==ret)
	{
		fprintf(stderr,"nkdir error\n");
		return 1;
	}

	return 0;
}

7.rmdir   (rm -r或rmdir)

int rmdir(const char *pathname);
功能:
    删除一个空目录文件
参数:
    pathname:目录文件的名字
返回值:
    成功返回0
    失败返回-1

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int ret=rmdir("./hhh");
	if(-1==ret)
	{
		fprintf(stderr,"rmdir error\n");
		return 1;
	}
	
	return 0;
}

8.stat

int  stat(const  char  *path, struct stat *buf);
功能:
    获得文件的属性
参数:
    path: 文件的路径
    buf:  属性存放空间的首地址
返回值:
    成功返回0
    失败返回-1

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

int main(int argc, const char *argv[])
{
	struct stat sta;
	char filename[]="1.txt";
	int ret=stat(filename,&sta);
	if(-1==ret)
	{
		fprintf(stderr,"stat error\n");
		return 1;
	}

	printf("ino:%lu\n",sta.st_ino);
	printf("mode:%d\n",sta.st_mode);
	printf("link:%lu\n",sta.st_nlink);
	printf("uid:%u\n",sta.st_uid);
	printf("gid:%u\n",sta.st_gid);
	printf("size:%lu\n",sta.st_size);
	printf("time:%lu\n",sta.st_mtime);
	printf("%s\n",filename);
	
	return 0;
}

struct stat  是一个用于存储文件状态信息的结构体。

它通常包含以下一些成员:

-  st_ino :文件的 inode 号码

-  st_mode :文件的类型和权限

-  st_nlink :硬链接的数量

-  st_uid :用户 ID

-  st_gid :组 ID

-  st_size :文件的大小(以字节为单位)

-  st_atime:文件的最后访问时间

-  st_mtime :文件的最后修改时间

-  st_ctime:文件的最后状态更改时间

对于st_mode的文件类型可以通过man 7 inode查看文件类型的宏

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

对于st_mode的权限可以通过man 7 inode查看

-  S_IRUSR :所有者的读权限。

-  S_IWUSR :所有者的写权限。

-  S_IXUSR :所有者的执行权限。

-  S_IRGRP :所属组的读权限。

-  S_IWGRP :所属组的写权限。

-  S_IXGRP :所属组的执行权限。

-  S_IROTH :其他用户的读权限。

-  S_IWOTH :其他用户的写权限。

-  S_IXOTH :其他用户的执行权限。

通过位与操作( & )可以检查文件是否具有特定的权限或类型。

二、获取时间的相关函数

1.time

time_t time(time_t *t);
功能:
    获得1970年到现在的秒数
参数:
    t:存放秒数的空间首地址
返回值:
    成功返回1970年到现在的秒数
    失败返回-1

#include <stdio.h>
#include <time.h>

int main(int argc, const char *argv[])
{
	time_t tm;
	time(&tm);//tm = time(NULL); 也可以这样定义
	printf("%ld\n",tm);
	printf("%s",ctime(&tm));
	
	return 0;
}

2.ctime

char *ctime(const time_t *timep);
功能:
   将时间秒数转化成字符串
   该字符串的格式固定为: Wed Jun 30 21:49:08 1993\n
参数:
    timep:保存时间的地址

返回值:
    成功返回获得时间字符串的首地址
    失败返回NULL

3.localtime

struct tm *localtime(const time_t *timep);
功能:
    将一个秒数转化成日历时间(可以自定义打印的年日月的顺序)
参数:
    timep:保存秒数空间的地址
返回值:
    成功返回保存日历时间结构体的指针
    失败返回NULL

#include <stdio.h>
#include <time.h>

int main(int argc, const char *argv[])
{
	time_t tm;
	time(&tm);
	struct tm * t=localtime(&tm);
	printf("%d-%d-%d %d:%d:%d\n",t->tm_year+1900
			,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min
			,t->tm_sec);
	
	return 0;
}

struct tm  结构体通常包含以下成员:

-  tm_sec  :秒

-  tm_min  :分

-  tm_hour  :时

-  tm_mday  :一个月中的日期

-  tm_mon  :月份

-  tm_year  :从 1900 年开始的年数。

-  tm_wday  :一周中的日期

-  tm_yday  :一年中的日期

三、uid、gid

1.getpwuid

struct passwd *getpwuid(uid_t uid);
功能:
    根据用户id到/etc/passwd文件下解析获得结构体信息
参数:
    uid:用户id
返回值:
    成功返回id对应用户的信息
    失败返回NULL

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

int main(int argc, const char *argv[])
{
	uid_t uid=1000;
	struct passwd * pw=getpwuid(uid);
	if(NULL==pw)
	{
		fprintf(stderr,"getpwuid error\n");
		return 1;
	}
	printf("%s %d %s %s\n",pw->pw_name,pw->pw_gid
			,pw->pw_dir,pw->pw_shell);
	return 0;
}

struct passwd 有以下成员
char   *pw_name;       /* username */用户名
char   *pw_passwd;     /* user password */用户密码
uid_t   pw_uid;        /* user ID */用户ID
gid_t   pw_gid;        /* group ID */用户组ID
char   *pw_gecos;      /* user information */用户的备注信息
char   *pw_dir;        /* home directory */用户的主目录
char   *pw_shell;      /* shell program */用户的默认shell

2.getgrgid

struct group *getgrgid(gid_t gid);
功能:
    根据gid到/etc/group文件中解析组信息
参数:
    gid:组id
返回值:
    成功返回组信息
    失败返回NULL

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

int main(int argc, const char *argv[])
{
	gid_t gid=1000;
	struct group * gr=getgrgid(gid);
	if(NULL==gr)
	{
		fprintf(stderr,"getgrgid error\n");
		return 1;
	}

	printf("name:%s\n",gr->gr_name);

	int i=0;
	while(1)
	{
		if(gr->gr_mem[i]==NULL)
		{
			break;
		}
		printf("%s\n",gr->gr_mem[i]);
		++i;
	}
	return 0;
}

struct group 有以下成员
char   *gr_name;       /* group name */组名
char   *gr_passwd;     /* group password */组密码
gid_t   gr_gid;        /* group ID */组ID
char  **gr_mem;        /* group members */组成员用户名列表

通过stat、localtime、getpwuid、getgrgid可以仿写ll命令

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>

int main(int argc, char *argv[])
{
	if(argc<2)
	{
		fprintf(stdout,"usage:./a.out dirname\n");
		return 1;
	}
	DIR * dir=opendir(argv[1]);
	if(dir==NULL)
	{
		fprintf(stderr,"opendir error\n");
		return 1;
	}

	while(1)
	{
		struct dirent * info=readdir(dir);
		if(info==NULL)
		{
			break;
		}
		
    struct stat st;
    char path_filename[512]={0};
	sprintf(path_filename,"%s/%s",argv[1],info->d_name);
    int ret= stat(path_filename,&st); 
    if(-1 == ret)
    {
        fprintf(stderr,"stat error\n");
        return 1;
    }
	if(S_ISREG(st.st_mode))
	{
		printf("-");
	}
	else if(S_ISDIR(st.st_mode))
	{
		printf("d");
	}
	else if(S_ISCHR(st.st_mode))
	{
		printf("c");
	}
	else if(S_ISBLK(st.st_mode))
	{
		printf("b");
	}
	else if(S_ISFIFO(st.st_mode))
	{
		printf("p");
	}
	else if(S_ISLNK(st.st_mode))
	{
		printf("l");
	}
	else if(S_ISSOCK(st.st_mode))
	{
		printf("s");
	}

	if(st.st_mode&S_IRUSR)
	{
		printf("r");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IWUSR)
	{
		printf("w");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IXUSR)
	{
		printf("x");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IRGRP)
	{
		printf("r");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IWGRP)
	{
		printf("w");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IXGRP)
	{
		printf("x");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IROTH)
	{
		printf("r");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IWOTH)
	{
		printf("w");
	}
	else
	{
		printf("-");
	}
	if(st.st_mode&S_IXOTH)
	{
		printf("x");
	}
	else
	{
		printf("-");
	}

	time_t tm=st.st_mtime;
	struct tm * t=localtime(&tm);

	uid_t uid = st.st_uid;
	struct passwd * pw = getpwuid(uid);

	gid_t gid=st.st_gid;
	struct group * gr=getgrgid(gid);

	printf(" %2lu %s %s %5lu %d月  %d %02d:%2d %s\n",st.st_nlink
			,pw->pw_name,gr->gr_name, st.st_size
			,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min
			,path_filename);
	}

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值