创建目录和列出目录功能最常使用。
一、获取当前工作目录1. Linux
在shell中我们可以直接输入命令pwd 来显示当前的工作目录
2. C
在C程序中调用getcwd函数可以获取当前的工作目录。
函数声明: char *getcwd(char * buf,size_t size); 当前工作目录存入buf中 #include返回值: 如果目录名超出了参数size长度,函数返回NULL,如果成功,返回buf。 例如: char strpwd[301]; memset(strpwd,0,sizeof(strpwd)); getcwd(strpwd,300); printf("当前目录是:%sn",strpwd);
示例:
void main() { char * strpwd=malloc(301); memset(strpwd,0,sizeof(strpwd)); printf("strpwd=%pn",strpwd); printf("res=%pn",getcwd(strpwd,300)); printf("当前目录是:%sn",strpwd); free(strpwd); }二、切换工作目录
1. Linux
在shell中我们可以直接输入命令cd 来显示当前的工作目录
2. C
C中用chdir函数切换目录
函数声明: int chdir(const char *path); 就像我们在shell中使用cd命令切换目录一样,在C程序中使用chdir函数来改变工作目录。 #include返回值:0-切换成功;非0-失败。
示例:
char * strpwd1=malloc(301); memset(strpwd1,0,sizeof(strpwd1)); chdir("aaa"); getcwd(strpwd1,300); printf("当前目录是:%sn",strpwd1);三、目录的创建和删除
1. Linux
我们可以在shell中可以通过mkdir/rmdir命令来创建/删除目录
2. C
C程序中用mkdir/rmdir函数来创建/删除目录。
创建目录函数的声明: int mkdir(const char *pathname, mode_t mode); #include返回值:创建一个目录,若成功则返回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//ubuntu void main() { mkdir("ddd",0755);//在程序所在文件夹下创建一个名为ddd的文件夹 mkdir("aaa/ddd",0755);//使用这种多文件夹方式创建文件夹时要注意:最后一个文件夹名前面的文件夹都存在,否则就一直返回-1 //已存在的文件再次创建也会报错 }
rmdir示例:
#include四、获取目录中的文件列表void main() { rmdir("bbb");//如果文件夹中有文件或文件夹也会一直报错,里面是空的才会删除成功。 rmdir("aaa/bbb");//一定要保证aaa存在,否则报错 }
1. Linux
我们可以在shell中可以通过ls命令来获取目录中的文件列表
2. C
#include//包含头文件 相关的库函数(配合使用): 打开目录的函数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#include 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=%dn",stdinfo->d_name,stdinfo->d_type); } closedir(dir); // 关闭目录指针 }
获取目录中的文件列表实例:
文件存放在某目录中,该目录下还会有多级子目录,程序员想要的是列出该目录及其子目录下全部的文件名。
例如存在/home/wucz/tmp目录,其子目录结构和文件如下:
实现:
#include#include // 列出目录及子目录下的文件 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/%sn",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函数声明: 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#include void main() { if(access("aaa1",F_OK)==0) printf("existn"); }
- 获取文件和目录的状态信息
就是创建时间之类的信息。
stat库函数:
包含头文件: #include#include #include 函数声明: 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-node mode_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六、修改存取时间和更改时间#include #include #include 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=%ldn",statstr,statTemp.st_size); } }
- Linux
参考链接
①同时变更文件的修改时间和访问时间(Access&Modify)
pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -d "2018-04-18 08:00:00" aaa pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaa File: aaa Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 805h/2053d Inode: 1056464 links: 3 Access: (0775/drwxrwxr-x) Uid: ( 1000/ pl) Gid: ( 1000/ pl) Access: 2018-04-18 08:00:00.000000000 +0800 Modify: 2018-04-18 08:00:00.000000000 +0800 Change: 2021-10-22 15:25:50.968267483 +0800 Birth: -
②只变更文件的修改时间(Modify)
pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -m -d "2018-05-20 08:00:00" aaa pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaa File: aaa Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 805h/2053d Inode: 1056464 links: 3 Access: (0775/drwxrwxr-x) Uid: ( 1000/ pl) Gid: ( 1000/ pl) Access: 2018-04-18 08:00:00.000000000 +0800 Modify: 2018-05-20 08:00:00.000000000 +0800 Change: 2021-10-22 15:26:59.712269446 +0800 Birth: -
③只变更文件的访问时间(Access)
pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ touch -a -d "2017-05-10 09:00:00" aaa pl@pl-virtual-machine:~/Desktop/LPGitHub/CPP/C_Basics$ stat aaa File: aaa Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 805h/2053d Inode: 1056464 links: 3 Access: (0775/drwxrwxr-x) Uid: ( 1000/ pl) Gid: ( 1000/ pl) Access: 2017-05-10 09:00:00.000000000 +0800 Modify: 2018-05-20 08:00:00.000000000 +0800 Change: 2021-10-22 15:28:20.148271742 +0800 Birth: -
- C
utime库函数,用于修改文件的存取时间和更改时间:
包含头文件: #include函数声明: 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七、重命名文件或目录#include #include 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函数声明: int rename(const char *oldpath, const char *newpath); 参数说明: //oldpath 文件或目录的原名。 //newpath 文件或目录的新的名称。 返回值:0-成功,-1-失败。
示例:
在这里插入代码片八、删除文件或目录
- Linux
删除文件用:rm 文件名 删除空文件夹用:rmdir 文件夹名。 删除非空文件夹:rm -rf 非空文件夹名 -r 就是向下递归,不管有多少级目录,一并删除。 -f 就是直接强行删除,不作任何提示的意思。
- C
remove函数用于删除文件或目录,相当于 *** 作系统的rm命令。
包含头文件: #include函数声明: int remove(const char *pathname); 参数说明: pathname 待删除的文件或目录名。 返回值:0-成功,-1-失败。
示例:
#include利用所学知识编写函数void main() { if(remove("aaa11")==0)//aaa1文件夹中不为空就失败 { printf("rm aaa11 success!n"); } else printf("rm aaa11 failedn"); if(remove("bbb")==0)//bbb是空文件夹名 成功 printf("rm bbb success!n"); }
1. mkdir创建多级目录
#include#include #include #include 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 existn",path); return -1; } } else { //example:"temp/aaa/bbb/ccc/testfile.c" // 123456789 13 17 27 char * 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 . position if(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)); else strncpy(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=%dn",Customize_mkdir("temp1/aaa"));//创建两个文件夹 printf("res=%dn",Customize_mkdir("temp1/a.c"));//创建文件夹并创建文件 }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)