使用ls-l命令可以得到一个目录下的所有文件(隐藏文件除外)的详细信息。
例:

使用ls-l得到的详细信息包括:
1.第一列 '-' 表示文件的类型,文件类型包括以下几种类型:
- (1)- 普通文件(图片,视频,音频, world文档, txt文档, c文件....)
- d目录文件(文件夹)
- c字符设备文件(驱动课程学习)
- b块设备文件(驱动课程学习)
- l链接文件(类似快捷方式- linux学习)
- p管道文件(进程时学习)
- s套接字文件(网络编程学习)
2.第二列9个字母表示文件使用权限,‘r’表示具有读的权限,‘w’表示具有写的权限,‘x’表示具有执行的权限,‘-’ 表示不具有该权限。前三个字母表示用户可使用的权限,第4~6个字母表示用户同组可使用的权限,第7~9个字母表示其他人可使用的权限。
3.第三列数字表示文件的硬链接数,新建的普通文件硬链接数默认为1 。
4.第四列表示用户名。在linux系统中为多用户共用同一系统,该组字符串标识某一用户。
5.第五列表示用户所在的组。
6.第六列表示文件的大小。文件的大小是以 字节为单位计算的。
7.第七、八列表示文件修改的月份和日期。
8.第九列表示最后一次修改文件的具体时间。
9.第十列表示目录下所有文件的文件名。
使用I/O编程实现ls-l功能用到的函数:
1.打开目录--opendir()
#include <sys/types.h>
#include <dirent.h>声明: DIR *opendir(const char *name);
参数:
name:打开的目录名
返回值:
成功返回目录流指针,失败返回NULL;
2.读取目录项--readdir()
#include <dirent.h>
声明: struct dirent *readdir(DIR *dirp);
参数:
dirp:目录流指针
返回值:
成功返回一个目录项的相关结构体指针,失败或者没有目录项可读返回NULL结构体:
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
3.获取文件属性--lstat()
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>声明: int lstat(const char *pathname, struct stat *statbuf);
参数:
pathname:文件名
statbuf:文件属性结构体首地址
返回值:
成功返回0,失败返回-1;3.1文件类型的获取:
所需要的结构体:
struct stat:
struct stat { nlink_t st_nlink; // 硬链接个数 uid_t st_uid; // 所有者用户ID gid_t st_gid; // 所有者组ID off_t st_size; // 总体尺寸,以字节为单位 blksize_t st_blksize; // 文件系统 I/O 块大小 blkcnt_t st_blocks; // 已分配 512B 块个数 time_t st_atime; // 上次访问时间 time_t st_mtime; // 上次更新时间 time_t st_ctime; // 上次状态更改时间 };struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
}以下为st_mode域定义:
S_IFMT 0170000 bit mask for the file type bit field //文件类型位字段的位掩码
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 //FIFO
st_mode -- 跟文件类型文件权限有关
st_mode & S_IFMT == 文件类型对应宏,则表示文件为对应类型
文件权限:st_mode & 权限宏 == 宏本身 表示具有该权限
S_IRUSR 00400 owner has read permission //所有者拥有读取权限
S_IWUSR 00200 owner has write permission //所有者有写权限
S_IXUSR 00100 owner has execute permission //所有者拥有执行权限
S_IRGRP 00040 group has read permission //组有读取权限
S_IWGRP 00020 group has write permission //组有写权限
S_IXGRP 00010 group has execute permission //组有执行权限
S_IROTH 00004 others have read permission //其他人拥有读取权限
S_IWOTH 00002 others have write permission //其他人拥有写权限
S_IXOTH 00001 others have execute permission //其他人拥有执行权限
使用I/O编程所需代码:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
int main(int argc, char *argv[])
{
int ret = 0;
struct dirent *info = NULL;
struct stat buf;
struct tm *t = NULL;
struct passwd *p = NULL;
struct group *g = NULL;
DIR * dfp = opendir("."); //打开目录
if(dfp == NULL)
{
perror("opendir");
return -1;
}
while((info = readdir(dfp)) != NULL) //循环读取目录项 -- 得到文件名
{
if(info->d_name[0] != '.') //不显示隐藏文件
{
ret = lstat(info->d_name, &buf); //获取指定文件的属性
if(ret < 0)
{
perror("lstat");
return -1;
}
p = getpwuid(buf.st_uid); //通过用户id得到用户名
g = getgrgid(buf.st_gid); // 通过用户组id得到用户组名
switch(buf.st_mode & S_IFMT) //得到文件类型 st_mode & 文件类型掩码 == 对应文件类型宏,则表示为该文件类型
{
case S_IFREG:
printf("-"); break;
case S_IFDIR:
printf("d"); break;
}
int i = 0;
for(i = 8; i >= 0; i--) //获取文件权限 st_mode & 权限宏 == 宏本身 表示具有该权限
{
if(buf.st_mode & (1<<i))
{
switch(i%3)
{
case 2:
printf("r"); break;
case 1:
printf("w"); break;
case 0:
printf("x"); break;
}
}
else
{
printf("-");
}
}
printf(" %ld ", buf.st_nlink); //得到文件硬链接数
printf("%s %s ", p->pw_name, g->gr_name);
printf("%-8ld ", buf.st_size); //得到文件大小
t = localtime(&buf.st_mtime); //将文件最后一次修改时间的秒数,转换为本地时间
printf("%d %d %02d:%02d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min);
printf("%s\n", info->d_name); //打印文件名
}
}
return 0;
}
结果:

初学者,有问题请指正!!