简明Linux教程-Linux下目录操作

7 Linux系统编程-目录操作

7.1 文件目录比较和rwx差异

获取进程当前工作目录:卷3 标准库函数

char *getcwd(char *buf, size_t size) 成功将buf保存当前进程工作目录的位置,失败将返回NULL

改变当前进程工作目录:

int chdir(const char *path); 成功:0 失败:-1设置errno的值

文件/目录权限

文件的内容是写到文件的内容,目录的内容是目录项

rwx
文件文件内容可以被查看 cat more less内容可以被修改可以运行产生一个进程./文件名
目录目录可以被浏览 ls tree创建 删除 修改文件 mv touch mkdir可以被打开,进入 cd

7.2 目录操作函数 5.12

(库函数) man 3 functionname

函数:DIR opendir(const char name)

描述:

The  opendir()  function  opens a directory stream corresponding to the directory name, and returns a pointer to  the  directory  stream.The stream is positioned at the first entry in the directory.
The  fdopendir()  function  is  like opendir(), but returns a directory stream for the directory referred to by the open  file  descriptor  fd.
After  a  successful  call to fdopendir(), fd is used internally by the implementation, and should not otherwise be used by the application.

头文件:#include<sys/types.h> #include <dirent.h>

参数:const char* name 文件夹名字

返回值:DIR* 返回一个目录流的指针,和FILE*类似

如果发生错误,将会返回一个空指针;并且设置erron;

函数:int closedir(DIR dirp)*

头文件:#include <sys/types.h> #include<dirent.h>

描述:关闭目录流,同样也会关闭目录文件的描述符

参数:DIR* dirp 一个文件流指针

返回值:int值,0代表成功,-1代表失败,并且设置erron

函数:struct dirent readdir(DIR dirp)

头文件:#include<dirent.h>

描述:

The  readdir()  function returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to  by      dirp.It  returns NULL on reaching the end of the directory stream or if an error occurred. In the glibc implementation, the dirent structure is  defined  as  follows:
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 */
             };

返回值:成功,返回一个结构体,结构体由目录的各种信息,如果读到文件结尾或者失败,都返回NULL,区别两者的方法是读到结尾,不会修改errno,而读取失败,会修改errno的值。

//一段实现ls功能的代码
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
    DIR* dir1=opendir(argv[1]);
    if(dir1==NULL){
        perror("open directory failed!\n");
        exit(1);
    }
    struct dirent* dir_info;
    while((dir_info=readdir(dir1))!=NULL){
        //消除显示中的"."".."选项
        if((!strcmp(dir_info->d_name,"."))||(!strcmp(dir_info->d_name,".."))){
            continue;
        }
        printf("%s\t",dir_info->d_name);
    }
    printf("\n");
    closedir(dir1);
    return 0;
}

7.3 递归遍历目录实现 5.13

linux可以用 ls -R filename实现

#include <stdio.h>
#include <unistd.h>
//使用文件操作的宏定义
#include <fcntl.h>
//使用exit函数
#include <stdlib.h>
//使用stat函数
#include <sys/stat.h>
//使用目录相关函数
#include <dirent.h>
#include <string.h>
void isFile(char *args);
void lsr(char *args, void (*fnp)(char *))
{
    char path[256];
    DIR *dir_fd;
    struct dirent *dir_info;
    dir_fd = opendir(args);
    {
        if (dir_fd == NULL)
        {
            perror("open dir error!\n");
            return;
        }
    }
    while ((dir_info = readdir(dir_fd)) != NULL)
    {
        if (!((strcmp(dir_info->d_name, ".") && strcmp(dir_info->d_name, ".."))))
            continue;
        else
        {
            //字符串拼接,也可以考虑使用strcat
            sprintf(path, "%s/%s", args, dir_info->d_name);
            (*fnp)(path);
        }
    }
    closedir(dir_fd);
}
//回调函数
void isFile(char *args)
{
    //定义传出参数
    struct stat statbuf;
    int ret = stat(args, &statbuf);
    if (ret == -1)
    {
        perror("open argv[1] failed!");
        exit(1);
    }
    //判断文件类型,文件类型是文件夹,递归调用lsr
    if ((statbuf.st_mode & __S_IFMT) == __S_IFDIR)
    {
        lsr(args, isFile);
    }
    //如果是普通文件,直接打印文件信息
    if ((statbuf.st_mode & __S_IFMT) == __S_IFREG)
    {
        printf("%8ld\t%s\n", statbuf.st_size, args);
    }
}
int main(int argc, char *argv[])
{
    //如果参数个数等于1,也就是没有变量输入,使用“."代替,即查看当前目录
    if (argc ==1)
    {
     	isFile(".");
    }
    else{
        isFile(argv[1]);
    }
    return 0;
}

7.4 重定向 dup和dup2 5.14

重定向:将写入标准输出的(STD_OUT)的内容写入一个文件

函数:int dup(int oldfd); int dup2(int oldfd, int newfd); int dup3(int oldfd, int newfd, int flags)

//dup2 dupto

dup主要实现文件描述符复制 dup2实现文件描述符重定向

描述:

 The  dup() system call creates a copy of the file descriptor oldfd, using the lowest-numbered unused file descriptor for the new descriptor.
       After a successful return, the old and new file descriptors may be used interchangeably.   They  refer  to  the same open file description (see       open(2)) and thus share file offset and file status flags; for example, if the file offset is modified by using lseek(2) on one of the file descriptors, the offset is also changed for the other.
       The two file descriptors do not share file descriptor flags (the closeon-exec  flag).The close-on-exec flag (FD_CLOEXEC; see fcntl(2)) for      the duplicate descriptor is off.

头文件:#define _GPU_SOURCE #include <fcntl.h>

#include <unistd.h>

参数:int dup (int oldfd) oldfd 旧的文件描述符

int dup(int oldfd, int newfd) oldfd 旧的文件描述符

返回值:如果成功,这些系统调用都返回新的文件描述符,失败返回-1,设置erron;

shell中的重定义:

#	使用>重定向到out文件
cat myls.c > out
#	使用>>追加到out文件
cat myls.c >>out

DEMO1:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if(argc!=2){
        printf("wrong args!\n");
    }
    int oldfd=open(argv[1],O_RDONLY);
    if(oldfd==-1){
        perror("open file failed!");
        exit(1);
    }
    int newfd=dup(oldfd);
    printf("oldfd=%d\n",oldfd);
    printf("newfd=%d\n",newfd);
    close(oldfd);
    close(newfd);
    return 0;
}
daniel@daniel-Vostro-5471:~/文档/OS/test/IO_test$ ./dup link.c
oldfd=3
#新的文件描述符是4
newfd=4

DEMO2:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    if(argc!=2){
        printf("args error!\n");
    }
    int fd1=open(argv[1],O_RDWR|O_CREAT,0664);
    if(fd1==-1){
        perror("open file failed!\n");
        exit(1);
    }
    //将标准输出重定向到fd1
    dup2(fd1,STDOUT_FILENO);
    //下面的打印不会打印到屏幕,而是输出到argv[1]的文件中
    printf("hello world!\n");
    close(fd1);
    return 0;
}

7.5 fcntl()实现dup功能 5.14

使用fcntl函数实现dup功能,fcntl函数的第二个参数是可调的,选择F_DUPFD 可以拷贝文件描述符

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
F_DUPFD (int)
Duplicate the  file  descriptor  fd  using  the  lowest-numbered
available file descriptor greater than or equal to arg.  This is
different from dup2(2), which uses exactly the  file  descriptor
specified.
On success, the new file descriptor is returned. 
See dup(2) for further details.
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if(argc!=2){
        printf("wrong args!\n");
    }
    int oldfd=open(argv[1],O_RDWR|O_APPEND);
    if(oldfd==-1){
        perror("open file failed!");
        exit(1);
    }
    //参数3可以指定文件描述符设置的起始位置
    //函数会从这个起始位置向上寻找最小的文件描述符作为返回参数
    int newfd=fcntl(oldfd,F_DUPFD,5);
    printf("oldfd=%d\n",oldfd);
    printf("newfd=%d\n",newfd);
    write(newfd,"//12345678\n",11);
    close(oldfd);
    close(newfd);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值