1.获取当前工作目录
#include <unistd.h>
char *getcwd(char *buf, size_t size);
参数:
buf:缓冲区地址。
size:给出的最大路径名长度。
返回值:
如果当前工作目录的路径名长度大于给定的长度,则返回NULL并置errno为ERANGE。
函数调用成功时,返回指向路径名的指针;否则返回NULL
示例:
char pathname[256] = {0};
if(getcwd(pathname, sizeof(pathname))!=NULL) {
printf("current dir is: %s\n", pathanme);
}
2. stat结构体
#include <sys/stat.h>
struct stat {
mode_t st_mode; //文件类型和权限信息
ino_t st_ino; //i结点标识
dev_t st_dev; //device number (file system)
dev_t st_rdev; //device number for special files
nlink_t st_nlink; //符号链接数
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
off_t st_size; //size in bytes,for regular files
time_t st_st_atime; //最后一次访问的时间
time_t st_mtime; //文件内容最后一次被更改的时间
time_t st_ctime; //文件结构最后一次被更改的时间
blksize_t st_blksize; //best I/O block size
blkcnt_t st_blocks; //number of disk blocks allocated
}
获取文件stat结构体信息的三个函数
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int fstat(int fieldes, struct stat *buf);
int lstat(const char *path, struct stat *buf);
返回值:
成功则返回0,否则返回-1.
说明:
1. fstat的第一个参数int fields为文件描述符。
2. fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路径直接写就可以了。
3. stat与lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。可以这样记,lstat比stat多了一个l,因此它是有本事处理符号链接文件(link)本身的。
3.dirent结构体,可以只关注d_name字段
#include <dirent.h>
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 (null-terminated) 文件名,最长255字符 */
}
4.读取目录的操作
//可能用到的函数
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *dirname);
struct dirent *readir(DIR *dirp);
void rewinddir(DIR *dirp);
int closedir(DIR *dirp);
//一个完整的递归遍历目录下子目录及文件的函数
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
void printdir(char *dir, int depth)
{
DIR *dp;
struct direct *entry;
struct stat statbuf;
if((dp = opendir(dir)) != NULL) {
//changedir,进入dir目录
chdir(dir);
while( (entry = readdir(dp)) != NULL ) {
lstat(entry->d_name, &statbuf);
if( S_ISDIR(statbuf.st_mode) ) {
if(strcmp(".",entry->d_name)==0 || strcmp("..",entry->d_name) {
continue;
}
printf("%*s%s/\n",depth," ",entry->d_name);
printdir(entry->d_name,depth+4);
} else {
printf("%*s%s\n",depth," ",entry->d_name);
}
}
chdir("..");
closedir(dp);
} else {
fprintf(stderr,"cannot open directory: %s\n",dir);
return;
}
}
int main(int argc, char *argv[])
{
printf("Directory scan of /home:\n");
printdir("/home",0);
printf("Success!\n");
exit(0);
}
5.注意:判断文件是目录文件还是普通文件有两种方式
struct dirent *entry;
struct stat st;
entry = opendir(dir);
lstat(entry->d_name,&st);
S_ISDIR(st.st_mode); //是目录文件则函数返回true
S_ISREG(st.st_mode); //是普通文件则函数返回true
//S_ISDIR和S_ISREG均为宏定义,可参见sys/stat.h.
//或者用以下方式
(st.st_mode & S_IFMT)==S_IFDIR //目录文件为true
(st.st_mode & S_IFMT)==S_IFREG //普通文件为true
//其中S_IFMT在sys/stat.h中被定义为八进制数170000,通过与st_mode进行位的与操作可得类型,另有S_IFBLK、S_IFCHR、S_IFIFO类型