1. 目录操作相关的系统调用
    1.1 mkdir和rmdir系统调用
    1.1.1 实例
    1.2 chdir, getcwd系统调用
    1.2.1 实例
    1.3 opendir, closedir, readdir,
    1.3.1 实例:递归便利目录

1. 目录操作相关的系统调用

1.1 mkdir和rmdir系统调用

[code]
filename: mk_rm_dir.c
#include <sys/stat.h>
int mkdir(const char *path, mode_t mode);
return:
    S    0
    F    -1
note:
    mode权限至少要有执行权限。
[/code]
[code]
#include <unistd.h>
int rmdir(const char *pathname);
return:
    S    0
    F    -1
note:
    pathname目录必须是空目录。

1.1.1 实例

#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <assert.h>
#define MODE (S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH)
int main(int argc, char *argv[])
{
char *pname;
assert(argc == );
pname = argv[];
assert(mkdir(pname, MODE) == );
printf("create %s successful!\n", pname);
assert(rmdir(pname) == );
printf("rm %s\n", pname);
return ;
}

测试:

[qtlldr@qtldr editing]$ ./mk_rm_dir  testdir

create testdir successful!

rm testdir

[qtlldr@qtldr editing]$

1.2 chdir, getcwd系统调用

#include <unistd.h>

int chdir(const char *pathname);

return:

S    0

F    -1

#include <unistd.h>

char *getpwd(char *buf, size_t size);

return:

S    buf

F    NULL

buf是缓冲地址,size是buf的长度。该缓冲必须有足够的长度以容纳绝对路径名加上一个null终止符。

1.2.1 实例

[code]

filename:ch_get_dir.c

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define BUFSIZE (50)
int main(void)
{
char buf[BUFSIZE];
memset((void *)buf, '\0', sizeof buf);
assert(chdir("/tmp") == );
printf("chdir to /tmp successful\n");
assert(getcwd(buf, BUFSIZE) != NULL);
printf("now the directory is %s\n", buf);
return ;
}

测试:

[qtlldr@qtldr editing]$ ./ch_get_dir

chdir to /tmp successful

now the directory is /tmp

[qtlldr@qtldr editing]$

1.3 opendir, closedir, readdir,

#include <sys/type.s>

#include <dirent.h>

DIR *opendir(const char *dirname);

return:

S    DIR指针

F    NULL

note:

DIR是一种目录结构,类似FILE。

#include <sys/types.h>

#include <dirent.h>

struct dirent *readir(DIR *dirp);

return:

S    一个指向保存目录流下一个目录项的dirent指针

F    NULL

note:

struct dirent {

char    d_name[NAME + 1]; /* \0结尾的文件名 */

}

到达目录尾或出错返回NULL,但是到达目录尾不会设置errno,出错则设置。

如果在readir的同时有其他进程在目录中创建或者删除文件爱你,readdir不保证能列处该目录中所有文件。

#include <sys/types.h>

#include <dirent.h>

int closedir(DIR *dirp);

return:

S    0

F    -1

1.3.1 实例:递归便利目录

filename:help.txt 帮助文档

本程序只为学习linux目录操作而写

printdir

输出目录文件或者统计目录中的文件数目

语法:

printdir [option] <files...>

选项:

-l

输出目录下的文件名

-c

统计目录下的文件

-d n

指定最大层次,最大为30

默认行为:

如果没有指定选项,那么只输出该目录下的文件名

BUG:

-l与 -c选项不能同时使用,如果同时使用统计出错。(以后会修正)

本程序只为学习linux目录操作而写

filename:printdir.c

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define INDENT_DEPTH (4) /* 列举文件时的缩进数 */
#define DEPTH_MAX (30) /* 递归便利的最大层次 */
#define HELPFILE ("help.txt")
typedef int count_t;
struct nfiletype {
count_t ndir;
count_t nreg;
count_t nchr;
count_t nfifo;
count_t nsock;
count_t nchar;
count_t nblock;
count_t nlink;
count_t ntotol;
count_t nunknow;
};/*记录各个类型文件的数目*/
int DEPTH = ; /* 递归层级限制 */
int idepth_count = ;
int idepth_print = ; static struct nfiletype *count_files(const char *pathname,
struct nfiletype *nfile); static void printdir(const char *pathname, int indent);
int main(int argc, char **argv)
{
int opt;
int depth_opt;
int count_flag = ;
int print_flag = ;
char *parg = NULL;
struct nfiletype nfiles = {};
int fd_help;
char buf_help[BUFSIZ];
int nread_help;
char *filename_help = HELPFILE;
while ((opt = getopt(argc, argv, "lhd:c")) != -) {
switch (opt) {
case 'l':
print_flag = ;
break;
case 'c':
count_flag = ;
break;
case 'd':
depth_opt = strtol(optarg, NULL, );
DEPTH = depth_opt <= DEPTH_MAX ? depth_opt: DEPTH;
break;
case ':':
printf("option needs a value\n");
break;
case '?':
printf("unknown option :%c\n", optopt);
break;
case 'h':
fd_help = open(filename_help, O_RDONLY);
if (fd_help != -) {
while ((nread_help = read(fd_help, buf_help, BUFSIZ)) > ) {
write(, buf_help, nread_help);
}
close(fd_help);
} else {
fprintf(stderr, "open %s failed!\n", filename_help);
}
return ;
}
}
/* 如果没有选项,那么默认是打印目录 */
if (!print_flag && !count_flag)
print_flag = ;
for( ; optind < argc; optind++) {
parg = argv[optind];
if (print_flag) {
//printf("DEBUG-- printdir --%s\n", parg);
printdir(parg, );
}
if (count_flag) {
memset((void *)&nfiles, '\0', sizeof nfiles);
//printf("DEBUG-- count_files--%s\n", parg);
count_files(parg, &nfiles);
printf("In the %s there are :\n", parg);
printf(" directory %d\n", nfiles.ndir);
printf(" regular file %d\n", nfiles.nreg);
printf(" specal character file %d\n", nfiles.nchr);
printf(" special block file %d\n", nfiles.nblock);
printf(" fifo file %d\n", nfiles.nfifo);
printf(" sock file %d\n", nfiles.nsock);
printf(" link file %d\n", nfiles.nlink);
printf(" unknown file %d\n", nfiles.nunknow);
printf("Total %d\n", nfiles.ntotol);
}
}
return ;
}
/*
*function: 对该目录下的文件类型进行统计
* input arg:
* pathname:目录名指针
* nfile:记录文件类型数目的结构体指针
* return:
* 记录文件类型数目的结构体指针
*/ static struct nfiletype *count_files(const char *pathname,
struct nfiletype *nfile)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
//printf("DEBUG-- in count_files -- %s\n", pathname);
/* 层次控制 */
if (idepth_count > DEPTH)
return NULL;
idepth_count++;
if ((dp = opendir(pathname)) == NULL) {
fprintf(stderr, "can not open %s\n", pathname);
return NULL;
}
chdir(pathname);
while ((entry = readdir(dp)) != NULL) {
/* 跳过 . 和 .. */
if (strcmp(entry->d_name, ".") == || strcmp(entry->d_name, "..") == )
continue;
/* 取得文件信息 */
if (lstat(entry->d_name, &statbuf) == -) {
fprintf(stderr, "can not test the %s's type\n", entry->d_name);
return NULL;
}
/* 统计文件数目 */
if (S_ISDIR(statbuf.st_mode)) { /* 是目录就递归吧 */
//printf("DEBUG -- directory %s\n", entry->d_name);
count_files(entry->d_name, nfile);
nfile->ndir++;
}
else if (S_ISREG(statbuf.st_mode)) {
//printf("DEBUG -- regular file %s\n", entry->d_name);
nfile->nreg++;
}
else if (S_ISCHR(statbuf.st_mode))
nfile->nchr++;
else if (S_ISBLK(statbuf.st_mode))
nfile->nblock++;
else if (S_ISLNK(statbuf.st_mode))
nfile->nlink++;
else if (S_ISFIFO(statbuf.st_mode))
nfile->nfifo++;
else if (S_ISSOCK(statbuf.st_mode))
nfile->nsock++;
else nfile->nunknow++;
nfile->ntotol++;
}
chdir("..");
closedir(dp);
return nfile;
}
/*
nblock; *function:列出目录中的文件
nlink; *input arg:
ntotol; * pathname: 目录名
*return:
* void
*/ static void printdir(const char *pathname, int indent)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
/* 层次控制 */
if (idepth_print > DEPTH)
return ;
idepth_print++;
if ((dp = opendir(pathname)) == NULL) {
fprintf(stderr, "can not open %s\n", pathname);
return ;
}
chdir(pathname);
while ((entry = readdir(dp)) != NULL) {
/* 跳过 . 和 .. */
if (strcmp(entry->d_name, ".") == || strcmp(entry->d_name, "..") == )
continue;
if (lstat(entry->d_name, &statbuf) == -) {
fprintf(stderr, "can not test the %s's type\n", entry->d_name);
return ;
}
if (S_ISDIR(statbuf.st_mode)) { /* 是目录就递归吧 */
printf("%*s%s/\n", indent," ", entry->d_name);
printdir(entry->d_name, indent + INDENT_DEPTH);
}
else {
printf("%*s%s\n", indent," ", entry->d_name);
}
}
chdir("..");
closedir(dp);
}

注:本文转自:http://blog.chinaunix.net/uid-26242642-id-2779802.html

linux系统编程之文件与IO(四):目录访问相关系统调用的更多相关文章

  1. linux系统编程之文件与io(四)

    今天继续学习文件与io,主要是学习文件共享及文件.复制文件描述符,有点抽象,主要是概念上的理解,但是很重要,下面一一来分解: 文件共享: 回顾一下,在linux系统调用中,是通过文件描述符来访问文件的 ...

  2. linux系统编程之文件与IO(二):系统调用read和write

    read系统调用 一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节 函数原型: #include &l ...

  3. linux系统编程之文件与io(一)

    经过了漫长的学习,C语言相关的的基础知识算是告一段落了,这也是尝试用写博客的形式来学习c语言,回过头来看,虽说可能写的内容有些比较简单,但是个人感觉是有史起来学习最踏实的一次,因为里面的每个实验都是自 ...

  4. linux系统编程之文件与io(五)

    上一节中已经学习了文件描述符的复制,复制方法有三种,其中最后一种fcntl还并未使用到,关于这个函数,不光只有复制文件描述符的功能,还有其它一些用法,本节就对其进行一一剖析: fcntl常用操作: 这 ...

  5. linux系统编程之文件与IO(一):文件描述符、open,close

    什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...

  6. linux系统编程之文件与io(二)

    今天继续学习文件与io,话不多说,开始进入正题: 文件的read和write系统调用: 说明:函数中出现在size_t和ssize_t是针对系统定制的数据类型:     下面以一个实现文件简单拷贝的示 ...

  7. linux系统编程之文件与IO(七):时间函数小结

    从系统时钟获取时间方式 time函数介绍: 1.函数名称: localtime 2.函数名称: asctime 3.函数名称: ctime 4.函数名称: difftime 5.函数名称: gmtim ...

  8. linux系统编程之文件与IO(三):利用lseek()创建空洞文件

    一.lseek()系统调用 功能说明: 通过指定相对于开始位置.当前位置或末尾位置的字节数来重定位 curp,这取决于 lseek() 函数中指定的位置 函数原型: #include <sys/ ...

  9. linux系统编程之文件与io(三)

    上次我们利用文件的read和write来实现了简易的cp命令,其中将源文件拷贝到目标文件时,我们给目标文件的权限是写死的,而非根据源文件的权限生成的,如下: 今天就来解决这个问题,来学习获取文件权限相 ...

随机推荐

  1. 深入浅出parallelStream

    援引:http://blog.csdn.net/u011001723/article/details/52794455 感谢作者的分享!感谢作者为JDK8的学习所做的努力. about Stream ...

  2. Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default

    sudo vim /etc/xorg.conf copy: Section "Monitor" Identifier "Monitor0" VendorName ...

  3. keras—神经网络CNN—MNIST手写数字识别

    from keras.datasets import mnist from keras.utils import np_utils from plot_image_1 import plot_imag ...

  4. K组翻转链表 · Reverse Nodes in k-Group

    [抄题]: 给你一个链表以及一个k,将这个链表从头指针开始每k个翻转一下.链表元素个数不是k的倍数,最后剩余的不用翻转. [思维问题]: [一句话思路]: // reverse head->n1 ...

  5. haproxy 学习

    https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4-option%20tcp-check https://www.hapro ...

  6. 批量去重URL地址并剔除打不开网址

    #coding=utf-8 import os import httplib import socket dictlist ={}; def ReadHost(): hosts = []; obn = ...

  7. Paxos Made Simple

    Paxos一致性算法——分布式系统中的经典算法,论文本身也有一段有趣的故事.一致性问题是分布式系统的根本问题之一,在论文中,作者一步步的加强最初一致性问题(2.1节提出的问题)的约束条件,最终导出了一 ...

  8. Vmware迁移以后eth0消失,无法上网

    一个再普通不过的大神帮助小菜做虚拟机镜像的事情: 小张:帮我做个Vmware下的Ubuntu镜像吧,大神. 小黄:好啊,等我一下,下午发给你. 经过一番操作,小黄顺利的做出了一个虚拟机操作系统 小黄: ...

  9. cmake重新编译

    删除文件夹下的文件 rm CMakeCache.txt 重新编译即可 安装g++ yum install gcc-c++

  10. debian中默认不存在sudo命令解决方法

    原创 2016年09月04日 21:44:14 5664 1.使用su安装sudo $su #apt-get install sudo 1 2 2.给账户设置管理员权限 #vim /etc/sudoe ...