Linux的目录文件函数接口,链接文件函数接口,获得文件详细信息
目录
目录文件
目录文件的操作
(1)mkdir
(2) rmdir
(3)getcwd
(4)chdir
(5)chmod
目录文件的读取
(1)opendir
(2)closedir
(3)readdir
链接文件
1.软链接(符号链接)
(1)symlink
(2)readlink
2.硬链接
(1) link
(2)unlink
目录文件
目录文件的操作
(1)mkdir
mkdir
int mkdir(const char *pathname, mode_t mode);
功能:
创建目录
参数:
pathname:目录文件的路径
mode:目录文件的权限
返回值:
成功返回0
失败返回-1注意:
1.r 决定是否目录下可以查看其余文件信息
2.w 决定在目录下是否能够新建文件
3.x 决定是否能够进入该目录文件
(2) rmdir
rmdir
int rmdir(const char *pathname);
功能:
删除空目录文件
参数:
pathname:
目录文件的路径
返回值:
成功返回0
失败返回-1
(3)getcwd
getcwd
char *getcwd(char *buf, size_t size);
功能:
获得当前工作目录的绝对路径
参数:
buf:存放路径空间首地址
size:最大存放字符的长度
返回值:
成功返回存放路径字符串空间首地址
失败返回NULL
(4)chdir
chdir
int chdir(const char *path);
功能:
切换程序当前目录的工作路径
参数:
path:目的路径
返回值:
成功返回0
失败返回-1
本文所有代码的头文件
#ifndef __HEAD_H_
#define __HEAD_H_#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<dirent.h>
#include<time.h>
#include<sys/time.h>#endif
#include"../head.h"
int main()
{char str[200]={0};
//新建目录文件mkdir("diretory",0777);//获取当前工作目录绝对路径getcwd(str,sizeof(str));printf("%s\n",str);//切换当前目录工作路径chdir("/home/linux/Desktop");//打印改变后的文件路径getcwd(str,sizeof(str));printf("%s\n",str);/* rmdir("diretory"); 删除此文件*/return 0;
}
(5)chmod
chmod
int chmod(const char *pathname, mode_t mode);
chmod命令使用
chmod 0777 filename
chmod 0664 filename
chmod +/-r/w/x filename
功能:
修改文件权限
参数:
pathname:文件路径
mode:权限值 0777 0664
返回值:
成功返回0
失败返回-1
目录文件的读取
操作方法: 打开目录
读取目录项
关闭目录
(1)opendir
opendir
DIR *opendir(const char *name);
功能:
打开目录
参数:
name:目录文件路径
返回值:
成功返回目录流指针
失败返回NULL
(2)closedir
closedir
int closedir(DIR *dirp);
功能:
关闭目录流指针
参数:
dirp:目录流指针
返回值:
成功返回0
失败返回-1
(3)readdir
readdir
struct dirent *readdir(DIR *dirp);
功能:
读取目录项
参数:
dirp:目录流指针
返回值:
成功返回目录项指针
失败返回NULL
读到末尾返回NULL返回值类型
struct dirent {
ino_t d_ino; /* 节点编号 */
off_t d_off; /* 早期文件系统中,telldir返回文件在目录内的偏移 */
unsigned short d_reclen; /* 记录的实际长度 */
unsigned char d_type; /* 文件类型 */
char d_name[256]; /* 文件名 */
};
#include"../head.h"
/*显示输入目录路径下的文件,不包括隐藏文件*/
int List(char *dirname)
{DIR *dp=NULL;struct dirent *pp=NULL;dp=opendir(dirname);//打开目录if(dp==NULL){return -1;}while(1){pp=readdir(dp);//读取目录项if(pp==NULL){break;}if('.'==*pp->d_name)//跳过隐藏文件{continue;}printf("pp->d_name=%s/%s\n",dirname,pp->d_name);//打印目录项的文件名}closedir(dp);return 0;}
int main()
{char dirname[256]={0};printf("请输入目录路径\n");scanf("%s",dirname);List(dirname);return 0;
}
#include"../head.h"
/*查找输入目录路径下所有的文件,不包括隐藏文件,并显示查找耗费的时间*/
int Listdir(char *dirname)
{char filepath[1024]={0};DIR *dp=NULL;struct dirent *pp=NULL;dp=opendir(dirname);if(dp==NULL){return -1;}while(1){pp=readdir(dp);//接收目录项if(pp==NULL){return -1;}if('.'==*pp->d_name)//跳过隐藏文件{continue;}sprintf(filepath,"%s/%s",dirname,pp->d_name);//dirname是路径,pp->d_name是文件名,将绝对路径存入filepathprintf("%s\n",filepath);if(DT_DIR==pp->d_type)//如果文件是目录文件则递归查找里面的文件(标红是虚拟机的问题){Listdir(filepath);//递归调用List(filepath)}}closedir(dp);return 0;}
int main()
{char dirname[600]={0};struct timeval start;struct timeval end;long ts=0;struct tm *ptm=NULL; printf("请输入目录路径:\n");scanf("%s",dirname);gettimeofday(&start,NULL);//获得从1970.1.1到查找前的秒数,精确到微秒Listdir(dirname);gettimeofday(&end,NULL);//获得从1970.1.1到查找后的秒数,精确到微秒ts = (end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec);printf("耗时 %ld.%ld s\n", ts / 1000000, ts % 1000000);return 0;
}
链接文件
1.软链接(符号链接)
创建软链接文件的命令
ln -s 被链接的文件名 软链接文件名
ln -s b.txt a.txt
a.txt 链接b.txt通过文件名进行链接,(a.txt)软链接文件中保存的是被它连接文件(b.txt)的文件名,当删除b.txt,a.txt不能再打开,若是重新创建 b.txt 则 a.txt 又可以重新打开
文件打开方式
普通文件:
文件名 -> inode -> 数据块
软链接:
软连接文件名 -> inode -> 数据块 -> 链接向的文件名 -> inode -> 数据块
(1)symlink
int symlink(const char *target, const char *linkpath);
功能:
创建一个linkpath的软连接文件,里面存放target字符串
参数:
target:链接向的文件名
linkpath:软链接文件名
返回值:
成功返回0
失败返回-1
(2)readlink
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
功能:
读取软链接文件本身内容
参数:
path:软链接文件名
buf:存放软链接文件内容的缓冲区
bufsize:缓冲区的大小
返回值:
成功返回读取的字节数
失败返回-1
#include"../head.h"
int main()
{FILE *fp=NULL;char tmpbuf[32]={0};symlink("file.txt","a.txt");//建立一个链接向file.txt的链接文件a.txtfp=fopen("a.txt","r");if(fp==NULL){perror("failed to open");return -1;}fgets(tmpbuf,sizeof(tmpbuf),fp);//获得a.txt链接向的文件的内容printf("%s\n",tmpbuf);memset(tmpbuf,0,sizeof(tmpbuf));//将tmpbuf中的内容重置readlink("a.txt",tmpbuf,sizeof(tmpbuf));//获得a.txt中保存的内容(链接向的文件名即file.txt)printf("%s\n",tmpbuf);fclose(fp);return 0;}
2.硬链接
ln 被链接的文件名 硬链接文件名
ln b.txt a.txt
通过在磁盘中存放的inode节点进行链接,使用同一个inode节点,不同链接文件名类似于不同名字,删除文件链接关系断开a.txt和b.txt内容一致,当删除b.txt后,硬链接断开,a.txt还可以打开且内容保持不变,再重新创建b.txt后,b.txt不再使用之前的inode节点,即两文件没有关系
(1) link
link
int link(const char *oldpath, const char *newpath);
功能:
创建一个newpath的硬链接文件
参数:
oldpath:要链接的文件名
newpath:硬链接文件名
返回值:
成功返回0
失败返回-1
(2)unlink
unlink
int unlink(const char *pathname);
功能:
删除链接文件名,并让硬链接个数-1 ,如果一个磁盘空间硬链接个数为0,需要回收磁盘空间
参数:
pathname:链接文件名
返回值:
成功返回0
失败返回-1
include"../head.h"
int main()
{link("file.txt","a.txt");//创建硬链接unlink("file.txt"); //删除硬链接return 0;
}
获得文件详细信息
(1)lstat
int lstat(const char *pathname, struct stat *statbuf);
功能:
获得pathname对应文件的详细信息
参数:
pathname:文件路径
statbuf:存放文件详细信息空间的首地址
返回值:
成功返回0
失败返回-1
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
(2)getpwuid
getpwuid
struct passwd *getpwuid(uid_t uid);
功能:
根据uid获得用户信息
参数:
uid:用户的ID号
返回值:
成功返回包含用户信息的结构体指针
失败返回NULL
(3)getgrgid
2.getgrgid
struct group *getgrgid(gid_t gid);
功能:
根据组名获得组ID
参数:
gid:组的ID号
返回值:
成功返回包含组信息结构体指针
失败返回NULL
#include"../head.h"
int Listlstat(char *pdirname)
{struct stat buf;int ret=0;struct passwd *pwd=NULL;struct group *grp=NULL;char *mon[12]={"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec"};struct tm *ptm=NULL;ret=lstat(pdirname,&buf);//lstat获得文件详细信息if(ret==-1){return -1;}/*文件类型*/#if 0 方法一//001 000 000 110 110 100// 100 000 000 //001 111 000 000 000 000//001 000 000 000 000 000 printf("buf.st_mode = %#o\n", buf.st_mode);if (S_ISREG(buf.st_mode)){printf("-");}else if (S_ISDIR(buf.st_mode)){printf("d");}else if (S_ISCHR(buf.st_mode)){printf("c");}else if (S_ISBLK(buf.st_mode)){printf("b");}else if (S_ISFIFO(buf.st_mode)){printf("p");}else if (S_ISSOCK(buf.st_mode)){printf("s");}else if (S_ISLNK(buf.st_mode)){printf("l");}
#endif
//方法二switch(buf.st_mode&__S_IFMT){case __S_IFDIR:printf("d");break;case __S_IFCHR:printf("c");break;case __S_IFBLK:printf("b");break;case __S_IFREG:printf("-");break;case __S_IFIFO:printf("p");break;case __S_IFLNK:printf("l");break;case __S_IFSOCK:printf("s");break;}/*文件修改权限*//*拥有人*/buf.st_mode & S_IRUSR ? putchar('r') : putchar('-');buf.st_mode & S_IWUSR ? putchar('w') : putchar('-');buf.st_mode & S_IXUSR ? putchar('x') : putchar('-');/*同组使用者*/buf.st_mode & S_IRGRP ? putchar('r') : putchar('-');buf.st_mode & S_IWGRP ? putchar('w') : putchar('-');buf.st_mode & S_IXGRP ? putchar('x') : putchar('-');/*其他使用者*/buf.st_mode & S_IROTH ? putchar('r') : putchar('-');buf.st_mode & S_IWOTH ? putchar('w') : putchar('-');buf.st_mode & S_IXOTH ? putchar('x') : putchar('-');printf(" %ld",buf.st_nlink);//硬链接个数pwd=getpwuid(buf.st_uid);//根据uid获得用户名printf(" %s",pwd->pw_name);grp=getgrgid(buf.st_gid);//根据gid获得组名printf(" %s",grp->gr_name);printf(" %ld",buf.st_size);//文件大小ptm=localtime(&buf.st_mtime);//文件最后修改时间printf(" %s %d %d:%d",mon[ptm->tm_mon],ptm->tm_mday,ptm->tm_hour,ptm->tm_min);printf(" %s\n",pdirname);//文件名return 0;
}
int main()
{char dirname[32]={0};printf("请输入目录文件");scanf("%s",dirname);Listlstat(dirname);return 0;
}