Linux系统编程(六)目录操作函数

目录操作函数

一、getcwd函数

getcwd函数

二、chdir函数

chdir函数

三、文件和目录权限

文件和目录权限

四、opendir函数

opendir函数

五、closedir函数

closedir函数

六、readdir函数

readdir函数
struct_dirent

示例1:实现ls命令

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
        DIR *dp;
        struct dirent *sdp;
        dp = opendir(argv[1]);
        if(dp == NULL)
        {
                perror("opendir error");
                exit(1);
        }
        while((sdp = readdir(dp)) != NULL)
        {
                printf("%s\t",sdp->d_name);
        }
        printf("\n");
        closedir(dp);
        return 0;
}

示例2:实现ls -R命令(递归遍历目录,同时显示文件大小)

//ls_R.c
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define PATH_LEN 256
//dir=/home/itcast/1110_linux    fcn=isfile

void fetchdir(const char *dir, void (*fcn)(char *)) //该函数被调用,既已被判定为目录
{
    char name[PATH_LEN];
    struct dirent *sdp;
    DIR *dp;

    if ((dp = opendir(dir)) == NULL) {     //打开目录失败
        //perror("fetchdir can't open");
        fprintf(stderr, "fetchdir: can't open %s\n", dir);
        return;
    }

    while ((sdp = readdir(dp)) != NULL) {
        if (strcmp(sdp->d_name, ".") == 0 || strcmp(sdp->d_name, "..") == 0) {    //防止出现无限递归
            continue; 
        }

        if (strlen(dir)+strlen(sdp->d_name)+2 > sizeof(name)) 
            fprintf(stderr, "fetchdir: name %s %s too long\n", dir, sdp->d_name);
        } else {
            sprintf(name, "%s/%s", dir, sdp->d_name);
            (*fcn)(name);                     //这是一个什么??  
        }
    }

    closedir(dp);
}

void isfile(char *name)          //处理目录/文件
{
    struct stat sbuf;

   if (stat(name, &sbuf) == -1) {   //文件名无效
        fprintf(stderr, "isfile: can't access %s\n", name);
        exit(1);
    }
    if ((sbuf.st_mode & S_IFMT) == S_IFDIR) {  //判定是否为目录
        fetchdir(name, isfile);                //回调函数,谁是回调函数呢?
    }

    printf("%8ld %s\n", sbuf.st_size, name);   //不是目录,则是普通文件,直接打印文件名
}
//./ls_R ~/1110_linux
int main(int argc, char *argv[])
{
    if (argc == 1) 
        isfile(".");
    else
        while (--argc > 0)          //可一次查询多个目录 
            isfile(*++argv);        //循环调用该函数处理各个命令行传入的目录

    return 0;
}

七、dup和dup2函数(重定向)

int dup(int oldfd);		文件描述符复制。

	oldfd: 已有文件描述符

	返回:新文件描述符。
int main(int argc, char* argv[])
{
        int fd = open("temp.txt", O_RDWR);
        if(fd == -1)
        {
                perror("open error");
                exit(1);
        }
        int fd2 = dup(fd);
        write(fd2, "aaaaaaaa", 7);
        close(fd);
        close(fd2);

        return 0;
}
int dup2(int oldfd, int newfd); 文件描述符复制。重定向(将newfd重定向给oldfd,即将newfd指向oldfd所指向的文件)
int main(int argc, char* argv[])
{
	int fd1 = open(argv[1], O_RDWR); //3
	int fd2 = open(argv[2], O_RDWR); //4
	
	int fdret = dup2(fd1, fd2);//返回新文件描述符fd2,将fd2指向fd1所指向的文件
	printf("fdret = %d\n", fdret);
	
	int ret = write(fd2, "1234567", 7);//将写入到fd1所指向的文件中
	printf("ret = %d\n", ret);
	
	dup2(fd1, STDOUT_FILENO);//将屏幕输入,重定向给fd1所指向的文件;
	printf("----------1234");//向屏幕输出的内容将写入到fd1所指向的文件中
}

示例:使用fcntl实现dup描述符

int fcntl(int fd, int cmd, ....)

cmd: F_DUPFD
int main(int argc, char* argv[])
{
	int fd1 = open(argv[1], O_REWR);
	printf("fd1 = %d\n", fd1);
	
	int newfd = fcntl(fd1, F_DUPFD, 0);//0被占用,fcntl使用文件描述符表中可用的最小文件描述符返回
	printf("newfd = %d\n", newfd);
	
	int newfd2 = fcntl(fd1, F_DUPFD, 7);//7未被占用,返回 >=7 的文件描述符
	printf("newfd2 = %d\n", newfd2);
	
	int ret = write(newfd2, "YYYYYYY", 7);//将写入到fd1所指向的文件中
	printf("ret = %d\n", ret);
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值