int chdir( const char *path ); /* 切换目录为path */
char *getcwd( char *Buf, size_t size ); /* 将当前路径及目录的信息写道Buf */
Dir * opendir( const char *name ); /* 打开名为name的目录流 */
struct dirent * readdir( Dir *dir ); /* 从dir的目录流中读取目录信息 */
off_t telldir( DIR *dir ); /* 返回目录指针在目录流中的当前位置 */
void seekdir( DIR * dir, off_t offset ); /* 设置目录指针在目录流中的位置 */
int closedir( DIR *dir ); /* 关闭一个打开的目录流并释放资源 */
int stat( char *pathname, struct stat *Buf ); /* 获取pathname文件的信息 */
int fstat( int filedes, struct stat *Buf ); /* 获取一个已经打开的文件的信息 */
int lstat( char *pathname, struct stat *Buf ); /* 可以检查普通文件和符号链接对应文件pathname的信息 */
文件信息结构:
{
dev_t st_dev; /* 文件的设备ID号 */
ino_t st_ino; /* 节点号 */
mode_t st_mode; /* 文件类型跟权限 */
nlink_t st_nlink; /* 硬链接的数目 */
uid_t st_uid; /* 所有者的使用ID */
gid_t st_gid; /* 所有者的组ID */
dev_t st_rdev; /* 设备ID */
off_t st_size; /* 文件的大小,按字节计算 */
blksize_t st_blksize; /* 文件系统的块大小 */
blkcnt_t st_blocks; /* 文件使用的块数 */
time_t st_atime; /* 最后访问文件的时间 */
time_t st_mtime; /* 最后修改文件的时间 */
time_t st_ctime; /* 最后修改文件状态的时间 */
};
文件类型:
S_ISREG( ) //是否是常规文件
S_ISDIR( ) //是否是目录文件
S_ISCHR( ) //是否是字符设备文件
S_ISBLK( ) //是否是块设备文件
S_ISFIFO( ) //是否是FIFO文件
S_ISLNK( ) //是否是链接文件
S_ISSOCK( )//是否是套接口文件
如果将struct stat 的st_mode分量传入上述的宏,返回值非0那就是什么文件了。
递归遍历目录文件:
#define PRINT( fmt, arg... ) printf( fmt, ##arg )
void PrintDirectory( char *DirName, int deepth )
{
DIR * DirPtr = NULL;
struct dirent * DirentPtr = NULL;
struct stat Status;
char Buf[ 40 ] = { 0 };
int deep = 1;
if( NULL == DirName )
{
PRINT( "param is illegal!\r\n" );
goto PrintDirOut;
}
DirPtr = opendir( DirName ); //打开目录流
if( NULL == DirPtr )
{
PRINT( "%s %d\r\n", strerror( errno ), __LINE__ );
goto PrintDirOut;
}
if( chdir( DirName ) < 0 ) //将路径切换到打开目录流的路径
{
PRINT( "%s, %d\r\n", strerror( errno ), __LINE__ );
}
while( ( DirentPtr = readdir( DirPtr ) ) != NULL )
{
if( lstat( DirentPtr->d_name, &Status ) ) //读取文件信息, 如果目录下没有链接文件可以用stat,但是有链接文件就会报错
{
PRINT( "%s %d\r\n", strerror( errno ), __LINE__ );
}
if( S_ISDIR( Status.st_mode ) )
{
if( ( 0 == strcmp( DirentPtr->d_name, "." ) ) || ( 0 == strcmp( DirentPtr->d_name, ".." ) ) ) //避开“.”跟".."目录
{
continue;
}
else
{
for( ; deep <= ( deepth - 1 ) ; deep++ )
{
PRINT( " " );
}
deep = 1;
PRINT( "D:%s\r\n", DirentPtr->d_name );
PrintDirectory( DirentPtr->d_name, deepth + 1 ); //如果是目录就递归调用
}
}
else
{
for( ; deep <= ( deepth - 1 ); deep++ )
{
PRINT( " " );
}
PRINT( "regular File: %s\r\n", DirentPtr->d_name ); //打印文件
deep = 1;
}
}
if( chdir( "../" ) < 0 ) //当前路径遍历完成后回到上级
{
PRINT( "%s, %d\r\n", strerror( errno ), __LINE__ );
}
closedir( DirPtr ); //关闭打开的目录流
PrintDirOut:
return;
}
int main(void)
{
PrintDirectory( "/", 1 );
return 0;
}