2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > LinuxC语言 目录操作

LinuxC语言 目录操作

时间:2024-07-12 16:51:53

相关推荐

LinuxC语言 目录操作

创建目录和列出目录功能最常使用。

一、获取当前工作目录

1. Linux

在shell中我们可以直接输入命令pwd来显示当前的工作目录

2. C

在C程序中调用getcwd函数可以获取当前的工作目录。

函数声明:char *getcwd(char * buf,size_t size);当前工作目录存入buf中#include <unistd.h>返回值:如果目录名超出了参数size长度,函数返回NULL,如果成功,返回buf。例如:char strpwd[301];memset(strpwd,0,sizeof(strpwd));getcwd(strpwd,300);printf("当前目录是:%s\n",strpwd);

示例:

void main(){char * strpwd=malloc(301);memset(strpwd,0,sizeof(strpwd));printf("strpwd=%p\n",strpwd);printf("res=%p\n",getcwd(strpwd,300));printf("当前目录是:%s\n",strpwd);free(strpwd);}

二、切换工作目录

1. Linux

在shell中我们可以直接输入命令cd来显示当前的工作目录

2. C

C中用chdir函数切换目录

函数声明:int chdir(const char *path);就像我们在shell中使用cd命令切换目录一样,在C程序中使用chdir函数来改变工作目录。 #include <unistd.h>返回值:0-切换成功;非0-失败。

示例:

char * strpwd1=malloc(301);memset(strpwd1,0,sizeof(strpwd1));chdir("aaa");getcwd(strpwd1,300);printf("当前目录是:%s\n",strpwd1);

三、目录的创建和删除

1. Linux

我们可以在shell中可以通过mkdir/rmdir命令来创建/删除目录

2. C

C程序中用mkdir/rmdir函数来创建/删除目录。

创建目录函数的声明:int mkdir(const char *pathname, mode_t mode);#include <sys/stat.h>返回值:创建一个目录,若成功则返回0,否则返回-1 。mode的含义将按open系统调用的O_CREAT选项中的有关定义设置,当然,它还要服从umask的设置况,是不是看不明白?那先固定填0755,注意:0不要省略哦,它表示八进制。 例如:mkdir("/tmp/aaa",0755); // 创建/tmp/aaa目录返回值:若目录创建成功,则返回0;否则返回-1,并将错误记录到全局变量errno中。删除目录函数的声明:int rmdir(const char *pathname);返回值:若成功则返回0,否则返回-1

mkdir示例:

#include <sys/stat.h>//ubuntuvoid main(){mkdir("ddd",0755);//在程序所在文件夹下创建一个名为ddd的文件夹mkdir("aaa/ddd",0755);//使用这种多文件夹方式创建文件夹时要注意:最后一个文件夹名前面的文件夹都存在,否则就一直返回-1//已存在的文件再次创建也会报错}

rmdir示例:

#include <sys/stat.h>void main(){rmdir("bbb");//如果文件夹中有文件或文件夹也会一直报错,里面是空的才会删除成功。rmdir("aaa/bbb");//一定要保证aaa存在,否则报错}

四、获取目录中的文件列表

1. Linux

我们可以在shell中可以通过ls命令来获取目录中的文件列表

2. C

#include <dirent.h>//包含头文件相关的库函数(配合使用):打开目录的函数opendir的声明:DIR *opendir(const char *pathname);读取目录的函数readdir的声明:struct dirent *readdir(DIR *dirp);关闭目录的函数closedir的声明:int closedir(DIR *dirp);目录指针DIR:DIR *目录指针名;readdir读取目录函数返回值为struct dirent结构体:每调用一次readdir函数会返回一个struct dirent的地址,存放了本次读取到的内容,它的原理与fgets函数读取文件相同。struct dirent{long d_ino;// inode number 索引节点号off_t d_off; // offset to this dirent 在目录文件中的偏移unsigned short d_reclen;// length of this d_name 文件名长unsigned char d_type; // the type of d_name 文件类型char d_name [NAME_MAX+1]; // file name文件名,最长255字符};我们只需要关注结构体的d_type和d_name成员,其它的不必关心。d_name文件名或目录名。d_type描述了文件的类型,有多种取值,最重要的是8和4,8-常规文件(A regular file);4-目录(A directory),其它的暂时不关心。

获取目录中的文件列表示例:

#include <stdio.h>#include <dirent.h>int main(int argc,char *argv[]){if (argc != 2) {printf("请指定目录名。\n"); return -1; }DIR *dir; // 定义目录指针// 打开目录if ( (dir=opendir(argv[1])) == 0 ) return -1;// 用于存放从目录中读取到的文件和目录信息struct dirent *stdinfo;while (1){// 读取一条记录并显示到屏幕if ((stdinfo=readdir(dir)) == 0) break;printf("name=%s,type=%d\n",stdinfo->d_name,stdinfo->d_type);}closedir(dir); // 关闭目录指针}

获取目录中的文件列表实例:

文件存放在某目录中,该目录下还会有多级子目录,程序员想要的是列出该目录及其子目录下全部的文件名。

例如存在/home/wucz/tmp目录,其子目录结构和文件如下:

实现:

#include <stdio.h>#include <dirent.h>// 列出目录及子目录下的文件int ReadDir(const char *strpathname);int main(int argc,char *argv[]){if (argc != 2) {printf("请指定目录名。\n"); return -1; }// 列出目录及子目录下的文件ReadDir(argv[1]);}// 列出目录及子目录下的文件int ReadDir(const char *strpathname){DIR *dir; // 定义目录指针char strchdpath[256]; // 子目录的全路径if ( (dir=opendir(strpathname)) == 0 ) return -1; // 打开目录struct dirent *stdinfo; // 用于存放从目录读取到的文件和目录信息while (1){if ((stdinfo=readdir(dir)) == 0) break; // 读取一记录if (strncmp(stdinfo->d_name,".",1)==0) continue; // 以.开始的文件不读if (stdinfo->d_type==8) // 如果是文件,显示出来printf("name=%s/%s\n",strpathname,stdinfo->d_name);if (stdinfo->d_type==4) // 如果是目录,再调用一次ReadDir{sprintf(strchdpath,"%s/%s",strpathname,stdinfo->d_name);ReadDir(strchdpath);}}closedir(dir); // 关闭目录指针}

运行效果:

五、获取当前用户对文件或目录的存取权限

1. Linux

利用ls命令

ls -l xxx.xxx (xxx.xxx是文件名)执行结果标识符释义:r 表示文件可以被读(read)w 表示文件可以被写(write)x 表示文件可以被执行(如果它是程序的话)- 表示相应的权限还没有被授予之后的root root 就是用户拥有者了

示例:

上面示例解释: 一共有十位数,其中:最前面那个 - 代表的是类型中间那三个 rw- 代表的是所有者(user)拥有的权限然后那三个 r-- 代表的是组群(group)拥有的权限最后那三个 r-- 代表的是其他人(other)拥有的权限

需要注意的是:

查看文件权限的目录问题: 如果有文件夹 /a/b/c那么执行 ls -l /a/b 查看权限的文件并不是b,而是查看的c的权限。ls -l /a 查看的是b文件的权限ls -l /a/b 查看的是c文件的权限ls -l /a/b/c 查看的是c文件的权限

2. C

- 获取权限

access函数用于判断当前操作系统用户对文件或目录的存取权限。

包含头文件:#include <unistd.h>函数声明:int access(const char *pathname, int mode);参数说明:pathname文件名或目录名,可以是当前目录的文件或目录,也可以列出全路径。mode 需要判断的存取权限。在头文件unistd.h中的预定义如下:#define R_OK 4// R_OK 只判断是否有读权限#define W_OK 2// W_OK 只判断是否有写权限#define X_OK 1// X_OK 判断是否有执行权限#define F_OK 0// F_OK 只判断是否存在返回值:当pathname满足mode的条件时候返回0,不满足返回-1。在实际开发中,access函数主要用于判断文件或目录是否是存在。

access示例代码:

#include <unistd.h>#include <stdio.h>void main(){if(access("aaa1",F_OK)==0)printf("exist\n");}

- 获取文件和目录的状态信息

就是创建时间之类的信息。

stat库函数:

包含头文件:#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>函数声明:int stat(const char *path, struct stat *buf);参数说明:获取path指定文件或目录的信息,将信息保存到结构体buf中返回值:执行成功返回0,失败返回-1。

stat结构体:

struct stat结构体用于存放文件和目录的状态信息,如下:struct stat{dev_t st_dev; // device 文件的设备编号ino_t st_ino; // inode 文件的i-nodemode_t st_mode; // protection 文件的类型和存取的权限nlink_t st_nlink; // number of hard links 连到该文件的硬连接数目, 刚建立的文件值为1.uid_t st_uid; // user ID of owner 文件所有者的用户识别码gid_t st_gid; // group ID of owner 文件所有者的组识别码dev_t st_rdev; // device type 若此文件为设备文件, 则为其设备编号off_t st_size; // total size, in bytes 文件大小, 以字节计算unsigned long st_blksize; // blocksize for filesystem I/O 文件系统的I/O 缓冲区大小.unsigned long st_blocks; // number of blocks allocated 占用文件区块的个数, 每一区块大小为512 个字节.time_t st_atime; // time of lastaccess 文件最近一次被存取或被执行的时间, 一般只有在用mknod、 utime、read、write 与tructate 时改变.time_t st_mtime; // time of last modification 文件最后一次被修改的时间, 一般只有在用mknod、 utime 和write 时才会改变time_t st_ctime; // time of last change i-node 最近一次被更改的时间, 此参数会在文件所有者、组、 权限被更改时更新};struct stat结构体的成员变量比较多;对程序员来说,重点关注st_mode、st_size和st_mtime成员就可以了。注意st_mtime是一个整数表达的时间,需要程序员自己写代码转换格式(使用localtime库函数)。st_mode成员的取值很多,或者使用如下两个宏来判断:S_ISREG(st_mode) // 是否为一般文件 S_ISDIR(st_mode) // 是否为目录

示例:

#include <time.h>#include <sys/time.h>#include <utime.h>#include <stdio.h>int timetostr(const time_t ti,char *strtime){//把整数的时间转换为字符串格式的时间struct tm * now=localtime(&ti);if(now!=0){sprintf(strtime,"%d-%02u-%02u %02u:%02u:%02u", now->tm_year+1900,now->tm_mon,now->tm_mday,now->tm_hour,now->tm_min,now->tm_sec);return 0;}return -1;}void main(){char statstr[20];struct stat statTemp;if(stat("aaa1",&statTemp)==0){timetostr(statTemp.st_mtime,statstr);printf("statTemp.st_mtime=%s st_size=%ld\n",statstr,statTemp.st_size);}}

六、修改存取时间和更改时间

Linux

参考链接

①同时变更文件的修改时间和访问时间(Access&Modify)

pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -d "-04-18 08:00:00" aaapl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaaFile: aaaSize: 4096 Blocks: 8IO Block: 4096 directoryDevice: 805h/2053dInode: 1056464Links: 3Access: (0775/drwxrwxr-x) Uid: ( 1000/pl) Gid: ( 1000/pl)Access: -04-18 08:00:00.000000000 +0800Modify: -04-18 08:00:00.000000000 +0800Change: -10-22 15:25:50.968267483 +0800Birth: -

②只变更文件的修改时间(Modify)

pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -m -d "-05-20 08:00:00" aaapl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaaFile: aaaSize: 4096 Blocks: 8IO Block: 4096 directoryDevice: 805h/2053dInode: 1056464Links: 3Access: (0775/drwxrwxr-x) Uid: ( 1000/pl) Gid: ( 1000/pl)Access: -04-18 08:00:00.000000000 +0800Modify: -05-20 08:00:00.000000000 +0800Change: -10-22 15:26:59.712269446 +0800Birth: -

③只变更文件的访问时间(Access)

pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -a -d "-05-10 09:00:00" aaapl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaaFile: aaaSize: 4096 Blocks: 8IO Block: 4096 directoryDevice: 805h/2053dInode: 1056464Links: 3Access: (0775/drwxrwxr-x) Uid: ( 1000/pl) Gid: ( 1000/pl)Access: -05-10 09:00:00.000000000 +0800Modify: -05-20 08:00:00.000000000 +0800Change: -10-22 15:28:20.148271742 +0800Birth: -

C

utime库函数,用于修改文件的存取时间和更改时间:

包含头文件:#include <utime.h>函数声明:int utime(const char *filename, const struct utimbuf *times);参数说明:filename:要修改的文件名字符串times:如果参数times为空指针(NULL), 则该文件的存取时间和更改时间全部会设为目前时间。结构utimbuf 定义如下:struct utimbuf{time_t actime;time_t modtime;};返回值:执行成功则返回0,失败返回-1。

示例:

#include <utime.h>#include <stdio.h>#include <time.h>void main(){struct utimbuf utimTemp;utimTemp.actime=time(0);utimTemp.modtime=time(0);if(utime("aaa1",&utimTemp)==0)//文件夹名字aaa1{printf("modify aaa1 time success!");} }

七、重命名文件或目录

Linux

mv file1 file2#把当前目录下的file1文件名改成file2,如果该目录下有file2,则覆盖以前的file2文件

C

rename函数用于重命名文件或目录.相当于Linux的mv命令

包含头文件:#include <stdio.h>函数声明:int rename(const char *oldpath, const char *newpath);参数说明://oldpath 文件或目录的原名。//newpath 文件或目录的新的名称。返回值:0-成功,-1-失败。

示例:

在这里插入代码片

八、删除文件或目录

Linux

删除文件用:rm 文件名删除空文件夹用:rmdir 文件夹名。删除非空文件夹:rm -rf 非空文件夹名-r 就是向下递归,不管有多少级目录,一并删除。-f 就是直接强行删除,不作任何提示的意思。

C

remove函数用于删除文件或目录,相当于操作系统的rm命令。

包含头文件:#include <stdio.h>函数声明:int remove(const char *pathname);参数说明:pathname 待删除的文件或目录名。返回值:0-成功,-1-失败。

示例:

#include <stdio.h>void main(){if(remove("aaa11")==0)//aaa1文件夹中不为空就失败{printf("rm aaa11 success!\n");}elseprintf("rm aaa11 failed\n");if(remove("bbb")==0)//bbb是空文件夹名 成功printf("rm bbb success!\n");}

利用所学知识编写函数

1. mkdir创建多级目录

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>int Customize_mkdir(const char *path ){if(strstr(path,"/")==NULL){if(access(path,F_OK)!=0)//F_OK是否存在该文件名{if(mkdir(path,0755)!=0)//第二个参数加0时是表示八进制{printf("create %s failed!\n",path);return -1;}}else{printf("%s:This ictionary exist\n",path);return -1;}}else{//example:"temp/aaa/bbb/ccc/testfile.c"// 123456789 13 17 27char * index=0;char * strtemp=malloc(301);int n=0;//累加/前面的字符,包含当前/memset(strtemp,0,sizeof(301));while(1){index=strstr((path+n),"/");//动态找到第几个/if(index==0){char *dot=strstr(path+n,".");//find . positionif(dot!=0)//最后/后面是文件名{FILE * filetemp=fopen(path+n,"w");//如果文件存在,则清除原文件内容;如果文件不存在,则新建文件。if(filetemp==NULL)return -1;fclose(filetemp);}else//最后/后面是文件夹名{strncpy(strtemp,path+n,strlen(path)-n);mkdir(strtemp,0755);chdir(strtemp);}break;}if(n==0)strncpy(strtemp,path+n,index-(path+n));elsestrncpy(strtemp,path+n,index-(path+n+1));n=(index-path)+1;mkdir(strtemp,0755);chdir(strtemp);//cd new path//printf("%s 创建成功!\n",strtemp);memset(strtemp,0,301);}free(strtemp);}return 0;//成功返回0}void main(){printf("res=%d\n",Customize_mkdir("temp1/aaa"));//创建两个文件夹printf("res=%d\n",Customize_mkdir("temp1/a.c"));//创建文件夹并创建文件}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。