Linux系统调用(二)—目录和文件

发布于 2022-07-25 18:05:08 字数 15899 浏览 16 评论 0

1.
名称:        opendir
目标:         打开一个目录。
头文件:        #include <sys/types.h>
#include < dirent.h>
函数原形:        DIR *opendir(const char *name)
参数:         name      目录名
返回值:         NULL     遇到错误
            DIR *     打开成功
opendir用于打开一个目录,其功能和open相似。只不过open用于打开一个文件,而opendir用于打开一个目录。如果opendir可以成功打开一个目录,它就返回一个指向目录的指针,我们可以通过opendir的联机帮助知道这些内容。
首先在命令提示符后面键入[root@LINUX root]#man –k opendir来查找和opendir相关的联机帮助。我们可以得到以下内容:
opendir            (3)         -open a directory
这正是我们想要的。
然后我们可以键入[root@LINUX root]#man 3 opendir 来查看opendir[3]的联机帮助。
在帮助文档中我们可以看到这样一段话:
The opendir() function opens a directory stream correspondig to the directory name,and returns a pointer to the directory stream. The stream is positioned at the first entry in the directory.
The opendir() function rerurns a poin to the directory stream or NULL if an error occurred.
这些正是我们要找的信息. 除了这些信息我们还可以从帮助中获取诸如函数头文件,函数功能,函数原形,返回值,出错处理,相关函数等信息。大家试着用同样的方法来学习这些相关函数,达到举一返三的目的。
2
名称:        readdir
目标:         读取目录内容。
头文件:        #include <unistd.h>
#include <lixux/dirent.h>
#include < linux/unistd.h>
函数原形:        int readdir(unsigned int fd ,struct dirent *dirp,unsigned int count)
参数:         fd        文件描述符
dirp       用于存放读入数据的数组
count      
返回值:         -1    遇到错误
            0     打开成功
同样readdir的功能也和read相似,用于读取目录中内容。其实用open,read,close等函数也可以对目录目录操作的,但不是一个好的办法,因为Linux支持多种的目录类型,如Apple,HFS,ISO9600,VFAY,NFS,如果用read来读,需要了解这些不同类型目录各自的结构细节。
3.
名称:        closedir
目标:         关闭一个目录.
头文件:        #include <sys/types.h>
#include < dirent.h>
函数原形:        int closedir(DIR *dir)
参数:         dir       指向目录的指针
返回值:         -1        遇到错误
            0         打开成功,返回指向目录的指针。

利用这些函数我们可以编写不加参数的ls 命令,下面是代码。

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. void show_dir(char dirname[]);
  4. main(int ac,char *av[])
  5. {
  6. if(ac==1)
  7.     show_dir(“.”);    / *读当前目录*/
  8. else
  9.     while(--ac)      
  10. {
  11.           printf(“%s:n”,*++av);
  12.           show_dir(*av);    /*读指定目录*/
  13.      }
  14. }
  15. void show_dir(char dirname[])
  16. {
  17. DIR *dir_ptr;     /*定义目录类型的指针*/                  
  18. struct dirent *direntp;       /*定义用于读目录的缓冲区*/
  19. if((dir_ptr=opendir(dirname))==NULL)
  20.     printf(“Can’t open!”);
  21. else
  22. {
  23.     while((direntp=readdir(dir_ptr))!=NULL)
  24.     printf(“%sn”,direntp->d_name);
  25.     closedir(dir_ptr);
  26. }
  27. }

复制代码

4.
名称:        mkdir
目标:         创建目录
头文件:        #include < sys/stat.h>
#include <sys/types.h>
函数原形:        int result=mkdir(char *pathname,mode_t mode)
参数:         pathname   新建目录名
mode      权限位的掩码
返回值:         -1        遇到错误
            0         成功创建

5.
名称:        rmdir
目标:         删除一个目录,此目录必须为空
头文件:        #include <unistd.h>
函数原形:        int result=rmdir(comst char *path);
参数:         path      目录名
返回值:         -1        遇到错误
            0         成功删除

6.
名称:        link
目标:         创建一个文件的新链接
头文件:        #include < unistd.h>
函数原形:        int link(const char *oldpath,const char *newpath);
参数:         oldpath    原始链接名称
newpath   新建链接名称
返回值:         -1        遇到错误
            0         成功创建
实例:

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main(int argc,char *argv[])
  4. {
  5. if(link(argv[1],argv[2])=0)
  6.     printf(“link sccessn”);
  7. else
  8.     printf(“limk errorn”);

复制代码

7.
名称:        unlink
目标:         删除一个链接
头文件:        #include <unistd.h>
函数原形:        int unlink(const char *pathname);
参数:         pathname    目录名
返回值:         -1          遇到错误
            0           成功删除

8.
名称:        rename
目标:         重命名或删除一个链接
头文件:        #include < stdio.h.h>
函数原形:        int rename(const char* foldoath, const char* newpath);
参数:         oldpath    原始连接名称
newpath    新建连接名称
返回值:         -1      遇到错误
            0       成功返回

9.
名称:        chdir/fchdir
目标:         改变所调用进程的当前目录
头文件:        #include < unistd.h>
函数原形:        int chdir(const char *path);
int fchdir(int fd);
参数:         path      要达到的目录
fd        文件描述符
返回值:         -1        遇到错误
            0         成功改变

10
名称:        stat/fstat/lstat
目标:         得到文件的属性。
头文件:        #include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
函数原形:        int stat(const char *file_name,struct stat *buf)
int fstat(int filedes, struct stat *buf)
int lstat(const char *file_name,struct stat *buf)
参数:         file_name    文件名
filedes      
buf         指向buffer的指针
返回值:         -1          遇到错误
            0          成功返回

Stat把文件fname 的信息复制到指针bufp所指的结构中。Stat包括的信息有
st_mode                  文件类型和许可权限
st_uid         用户所有者ID
st_gid         所属组ID
st_size        所占字节数
st_nlink       文件链接数
st_mtime      文件最后修改时间
st_atime       文件最后访问时间
st_actime      文件属性最后改变时间

下面的程序得到这些属性,并显示它们。

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys.stat.h>
  4. int main(int ac, char *av[ ])
  5. {
  6. struct stat info;
  7. if(ac>1)
  8.     if(stat(av[1],&info)1=-1)
  9.     {
  10.         show_stat_info(av[1],&info);
  11.         return 0;
  12.     }
  13. else
  14.     perror(av[1]);
  15. return 1;
  16. }
  17. show stat_info(char *fname,struct stat *buf)
  18. {
  19.       printf(“mode : %on”,buf->st_mode);     /*显示文件模式字段*/
  20.       printf(“links : %dn”,buf->st_nlink);      /*显示链接数*/
  21. printf(“user : %dn”,buf->st_uid);        /*显示用户名ID*/
  22. printf(“group : %dn”,buf->st_gid);       /*显示组ID*/
  23. printf(“size : %dn”,buf->st_size);        /*显示文件大小*/
  24. printf(“modtime : %dn”,buf->st_mtime);  /*显示文件的最后修改时间*/
  25. printf(“name:%sn”,fname);        /*显示文件名*/
  26. }

复制代码

fstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接饮用的文件的信息。

编译并运行fileinfo.c:

  1. [root@LINUX root]#cc –o fileinfo fileinfo.c
  2. [root@LINUX root]#./fileinfo fileinfo.c
  3. mode:100664
  4. links: 1
  5. user:500
  6. group:120
  7. size:1106
  8. modtime:965158604
  9. name:fileinfo.c

复制代码

这个程序就是ls –l 命令实现代码的一部分,但是会和ls –l的输出有些不同,比如说时间的表示,用户和组ID的表示,文件权限的表示。涉及到了Linux编码的问题,这里不作介绍,大家可以查阅相关质料。

11.
名称:        access
目标:         确定文件的可存取性
头文件:        #include < unistd.h>
函数原形:        int access(const char *pathname ,int mode);
参数:         pathname  文件名
mode     新的所有权和特殊属性。
返回值:         -1       遇到错误
            0        成功返回
其中,mode是表4-5中所列常数的逐位或运算。
access函数的mode常数有:
R_OK                测试读许可权
W_OK                测试写许可权
X_OK                测试执行许可权
  F_OK                测试文件是否存在
当用open函数打开一个文件时,内核以进程的有效用户ID和有效组ID为基础执行其存取许可权测试。有时,进程也希望按区实际用户ID和实际组ID来测试其存取能力。例如当一个进程使用设置用户ID,或设置组ID特征作为另一个用户(或组)运行时,就可能需要。
access函数是按实际用户ID和实际组ID进行存取许可权测试的。下面是程序例子。

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. int main(int argc,char *argv[])
  6. {
  7. if(access(argv[1],R_OK)<0)
  8.     printf(“access error for %sn”,argv[1];
  9. else
  10.     printf(“read access OKn”);
  11. if(open(argv[1],O_RDONLY)<0)
  12.     printf(“open for reading OKn”);
  13. else
  14.     printf(“open for reading OKn”);
  15. }

复制代码
12.
名称:        chmod/fchmod
目标:         修改文件的所有权限和特殊属性。
头文件:        #include < sys/types.h>
#include <sys/stat.h>
函数原形:        int chmod(const char *path,mode_t  mode);
int fchmod(in fildes,mode_t mode);
参数:         path     文件名
mode    新的所有权和特殊属性。
fildes    文件描述符
返回值:         -1       遇到错误
            0        成功返回

程序可以通过系统调用chmod来改变文件的所有权和特殊属性,如:
chmod(“/tmp/myfie”,04764);
chmod(“/tmp/myfie”,S_ISUID|S_IRWXU|S_IRGRP|S_IWGRP|S_IROTH);
上述两条指令的作用相同,第一条是八进制来表示,第二条是用<sys/stat.h>中定义的符号来表示。后者有明显的优点,当系统定义的许可位的值改变时,无需修改程序。
每个文件都有9个存取许可权位,他们是:
        S_IRUSR                用户-读
        S_IWUSR                用户-xie
        S_IXUSR                用户-执行
        S_IRGRP                组-读
        S_IWGRP                组-写
        S_IXGRP                组-执行
        S_IROTH                其他-读
        S_IWOTH                其他-写
        S_IXOTH                其他-执行

13.
名称:        chown/fchown/lchown
目标:         修改文件所有者和组
头文件:        #include <sys/types.h>
#include < unistd.h>
函数原形:        int chown(const char *path,uid_t owner,gid_t group);
int fchown(int fd,uid_t owner,gid_t group);
int lchown(const char *path,uid_t owner,gid_t group);
参数:         path     文件名
fp       文件描述符
owner    新的文件所有者ID。
group    新的组ID。
返回值:         -1       遇到错误
            0        成功返回
chown通过修改文件属性来修改文件所有者和组的ID。例如:
chown(“file1“,200,40);
将文件file1的用户ID改为200,组ID改为40。

14.
名称:        utime
目标:         修改文件最后修改时间和最后访问时间。
头文件:        #include <utime.h>
#include <sys/types.h>
函数原形:        int utime(char *filename,struct timeval *tvp);
参数:         path     文件名
tvp      指向结构变量utimbuf的指针。
返回值:         -1       遇到错误
            0        成功返回

15.
名称:        rename
目标:         修改文件名或文件的位置。
头文件:        #include < stdio.h>
函数原形:        int rename (const char *oldpath,const char *newpath);
参数:         oldpath      原来文件名或目录名。
newpath     新的文件名或目录名。
返回值:         -1       遇到错误
            0        成功返回

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文