目录操作总共有以下几个函数:
1.创建目录 int mkdir(const char *pathname, mode_t mode);
2.删除目录 int rmdir(const char *pathname);
3.查看目录状态 int stat(const char *path, struct stat *buf);
4.打开目录 DIR *opendir(const char *name);
5.关闭目录 int closedir(DIR *dirp);
6.读目录 struct dirent *readdir(DIR *dirp);
7.获取当前目录路径及可执行文件路径
下面开始一一介绍函数和使用方法:
(1)创建目录
#include <sys/stat.h>
#include <sys/types.h>
int mkdir(const char *pathname, mode_t mode);
参数介绍:
pathname是你要创建的目录名,它可以是绝对路径,不指定绝对路经默认就是当前路径
mode是创建目录时需要指定的目录属性,每个系统mode含义不同,需要用man查看mkdir
返回值:
0成功
-1失败
例如我的系统man 2 mkdir之后如下:
那么,最终的目录属性就是mode & ~umask & 0777
实例:
#include <stdio.h>
#include <errno.h>
int main(int argc, char** argv) {
if (mkdir(argv[1], 0666) == -1) {
printf("------- mkdir err no = %d,str=%s\n", errno, strerror(errno));
}
return 0;
}
执行结果:
gcc test.c -o test
./test mymkdir
ls查看当前目录会多出mymkdir这个目录,ls -l可以查看属性,我设置的是0666,但是实际却是0644,由此可以大致推算出umask
(2)删除目录
#include <unistd.h>
int rmdir(const char *pathname);
参数介绍:
pathname要删除的目录路径
返回值:
0成功
-1失败
实例:
#include <stdio.h>
#include <errno.h>
int main(int argc, char** argv) {
if (rmdir(argv[1]) == -1) {
printf("------- rmdir err no = %d,str=%s\n", errno, strerror(errno));
}
return 0;
}
执行结果:
gcc test.c -o test
./test mymkdir
ls查看当前目录中mymkdir这个目录就没有了。
注意,rmdir这个函数只能删除空目录,及目录中没有任何其他文件和目录,否则删除失败。
(3)查看目录状态
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf); //查看目录或文件状态信息
参数介绍:
path目录或文件路径
buf存储着模块或文件的状态信息
struct stat {
dev_t st_dev; /* ID of device containing file /
ino_t st_ino; / inode number /
mode_t st_mode; / protection /
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; / blocksize for file system I/O /
blkcnt_t st_blocks; / number of 512B blocks allocated /
time_t st_atime; / time of last access /
time_t st_mtime; / time of last modification /
time_t st_ctime; / time of last status change */
};
st_mode记录了文件类型和访问权限,可用以下宏来判断文件类型,如下:
S_ISREG(mode) //判断是否为普通文件
S_ISDIR(mode) //判断是否为目录文件
S_ISCHR(mode) //判断是否为字符设备文件
S_ISBLK(mode) //判断是否为块设备文件
S_ISFIFO(mode) //判断是否为管道设备文件
S_ISLNK(mode) //判断是否为符号链接
也可以直接用“与”运算来判断,st_mode特征位如下:
02.S_IFSOCK 0140000 socket
03.S_IFLNK 0120000 符号链接(symbolic link)
04.S_IFREG 0100000 一般文件
05.S_IFBLK 0060000 区块装置(block device)
06.S_IFDIR 0040000 目录
07.S_IFCHR 0020000 字符装置(character device)
08.S_IFIFO 0010000 先进先出(fifo)
09.S_ISUID 0004000 文件的(set user-id on execution)位
10.S_ISGID 0002000 文件的(set group-id on execution)位
13.S_IRUSR 00400 文件所有者具可读取权限
14.S_IWUSR 00200 文件所有者具可写入权限
15.S_IXUSR 00100 文件所有者具可执行权限
16.S_IRWXG 00070 用户组的遮罩值(即所有权限值)
17.S_IRGRP 00040 用户组具可读取权限
18.S_IWGRP 00020 用户组具可写入权限
19.S_IXGRP 00010 用户组具可执行权限
20.S_IRWXO 00007 其他用户的遮罩值(即所有权限值)
21.S_IROTH 00004 其他用户具可读取权限
22.S_IWOTH 00002 其他用户具可写入权限
23.S_IXOTH 00001 其他用户具可执行权限
返回值:
0成功
-1失败
实例:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char** argv) {
struct stat st;
int err = stat(argv[1], &st);
if (err == -1)
return -1;
if (S_ISDIR(st.st_mode))
printf("%s is dir\n", argv[1]);
else if (S_ISREG(st.st_mode))
printf("%s is file\n", argv[1]);
return 0;
}
执行结果:
gcc test.c -o test
./test mymkdir
mymkdir/ is dir
./test test.c
test.c is file
实例:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char** argv) {
struct stat st;
int err = stat(argv[1], &st);
if (err == -1)
return -1;
if (st.st_mode & S_IFREG)
printf("%s is file\n", argv[1]);
else if (st.st_mode & S_IFDIR)
printf("%s is dir\n", argv[1]);
return 0;
}
执行结果:
gcc test.c -o test
./test mymkdir
mymkdir/ is dir
./test test.c
test.c is file
int fstat(int filedes, struct stat *buf); //查看已打开文件状态信息
参数介绍:
filedes为open打开的文件描述符
buf存储着模块或文件的状态信息
返回值:
0成功
-1失败
(4)打开目录
#include <sys/types.h>
#include <dirent.h>
typedef int ino_t;
struct dirent{
ino_t d_ino; //目录文件的节点编号
off_t d_off; //目录文件开始到目录进入点的位移
unsigned short d_reclen; //d_name的长度(字符串长)
unsigned char d_type; //d_name的类型
char d_name[256]; //文件或目录名
};
DIR *opendir(const char *name);
参数介绍:
name 要打开的目录路径
返回值:
非空 正确,DIR *指针,目录句柄
NULL 错误
(5)关闭目录
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
参数介绍:
dirp opendir的返回值
返回值:
0成功
-1失败
(6)读目录
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
参数介绍:
dirp opendir返回值
返回值:
非空 struct dirent *结构体指针
NULL 目录结尾或者错误产生
实例(显示当前目录下的所有目录和文件):
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
void getdir(char* path, int n){
struct stat st;
char pathname[256];
int i;
DIR* fp = opendir(path);
if (fp == NULL)
return;
struct dirent* db;
while((db = readdir(fp)) != NULL){
if (db->d_name[0] != '.') {
for (i = 0 ; i < n ; i++)
printf(" ");
printf("%s\n", db->d_name);
}
sprintf(pathname, "%s/%s", path, db->d_name);
stat(pathname, &st);
if (S_ISDIR(st.st_mode) && (db->d_name[0] != '.'))
getdir(pathname, n+1);
}
closedir(fp);
}
int main(int argc, char** argv) {
getdir(argv[1], 0);
return 0;
}
执行结果:
gcc test.c -o test
./test .
sdk_ai_record.txt
capacity_cal.c
vol-48k.pcm
main
pcm_change_volume
print_music.c
rtc_test_uc
audiocapture.cpp
ai_record.pcm
pcm_change_volume.c
2pcm_to_1pcm.c
capacity_cal
say_48.pcm
pcm48k_to_32k
read_write-uc
say_32.pcm
main-glibc
read-efuse-chip-id
read_write.c
file.pcm
sample_ai_record.pcm
ai_record2.pcm
1.txt
rtc_test_gc
print_music
sample_ai_record.txt
audio_thread.h
read_write
mymkdir
test.c
audio_thread
main.c
sdk_ai_record.pcm
audio_thread.c
read-efuse-chip-id.c
test
say_16.pcm
mixer.pcm
read_write-gc
test.s
vol-8k.pcm
obj.s
read_write2
2pcm_to_1pcm
pcm48k_to_32k.c
7577.txt
read_write2.c
audiocapture.h
output16.txt
rtc_test.c
(7)获取当前目录路径及可执行文件路径
#include <unistd.h>
char *getcwd(char *buf, size_t size); //获取当前执行程序所在的目录
参数介绍:
buf 保存当前目录地址
size buf大小
返回值:
非空 所获取的地址值
NULL 失败
实例:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
void getdir(char* path, int n){
struct stat st;
char pathname[256];
int i;
DIR* fp = opendir(path);
if (fp == NULL)
return;
struct dirent* db;
while((db = readdir(fp)) != NULL){
if (db->d_name[0] != '.') {
for (i = 0 ; i < n ; i++)
printf(" ");
printf("%s\n", db->d_name);
}
sprintf(pathname, "%s/%s", path, db->d_name);
stat(pathname, &st);
if (S_ISDIR(st.st_mode) && (db->d_name[0] != '.'))
getdir(pathname, n+1);
}
closedir(fp);
}
int main(int argc, char** argv) {
char dir[256];
getcwd(dir, 256);
printf("----- %s\n", dir);
return 0;
}
执行结果:
gcc test.c -o test
./test .
----- /home_c/chsun/test
#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsiz); //获取可执行程序路径
参数介绍:
path 符号链接,在linux内执行程序都用"/proc/self/exe"符号连接
buf 可执行程序路径
bufsiz buf的大小
实例:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
void getdir(char* path, int n){
struct stat st;
char pathname[256];
int i;
DIR* fp = opendir(path);
if (fp == NULL)
return;
struct dirent* db;
while((db = readdir(fp)) != NULL){
if (db->d_name[0] != '.') {
for (i = 0 ; i < n ; i++)
printf(" ");
printf("%s\n", db->d_name);
}
sprintf(pathname, "%s/%s", path, db->d_name);
stat(pathname, &st);
if (S_ISDIR(st.st_mode) && (db->d_name[0] != '.'))
getdir(pathname, n+1);
}
closedir(fp);
}
int main(int argc, char** argv) {
char dir[256]={0};
int err=readlink("/proc/self/exe",dir,256);
if (err==-1) return -1;
int i;
for(i=strlen(dir)-1;i>=0 && dir[i]!='/';i--);
dir[i]=0;
char filename[256];
sprintf(filename,"%s/%s",dir,argv[1]);
printf("---- %s\n",filename);
FILE *fp=fopen(filename,"r");
if (fp==NUL=){
printf("---- %s\n",strerror(errno));
}
return 0;
}
执行结果:
gcc test.c -o test
cd ..
test/test 1.txt
---- /home_c/chsun/test/1.txt
下面是我的个人公众号,喜欢linux c,c++,嵌入式的欢迎加入:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)