`
brxonline
  • 浏览: 64249 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

UNIX编程(4)-文件和目录

    博客分类:
  • C
阅读更多
1.stat,fstat,lstat函数
#include <sys/stat.h>

int stat(const char *restrict pathname, struct
stat *restrict buf);

int fstat(int filedes, struct stat *buf);

int lstat(const char *restrict pathname, struct
stat *restrict buf);

当命名文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用文件的信息。

stat 结构体说明
struct stat {
       mode_t    st_mode;      /* file type & mode (permissions) */
       ino_t     st_ino;       /* i-node number (serial number) */
       dev_t     st_dev;       /* device number (file system) */
       dev_t     st_rdev;      /* device number for special files */
       nlink_t   st_nlink;     /* number of links */
       uid_t     st_uid;       /* user ID of owner */
       gid_t     st_gid;       /* group ID of owner */
       off_t     st_size;      /* size in bytes, for regular files */
       time_t    st_atime;     /* time of last access */
       time_t    st_mtime;     /* time of last modification */
       time_t    st_ctime;     /* time of last file status change */
       blksize_t st_blksize;   /* best I/O block size */
       blkcnt_t  st_blocks;    /* number of disk blocks allocated */
     };

2.文件类型
文件类型包括:
普通文件
目录文件
块特殊文件
字符特殊文件
FIFO
套接字
符号链接

例:
打印文件类型
#include "apue.h"

int
main(int argc, char *argv[])
{

    int         i;
    struct stat buf;
    char        *ptr;

    for (i = 1; i < argc; i++) {
        printf("%s: ", argv[i]);
        if (lstat(argv[i], &buf) < 0) {
            err_ret("lstat error");
            continue;

         }
         if (S_ISREG(buf.st_mode))
            ptr = "regular";
         else if (S_ISDIR(buf.st_mode))
            ptr = "directory";
         else if (S_ISCHR(buf.st_mode))
            ptr = "character special";
         else if (S_ISBLK(buf.st_mode))
            ptr = "block special";
         else if (S_ISFIFO(buf.st_mode))
            ptr = "fifo";
         else if (S_ISLNK(buf.st_mode))
            ptr = "symbolic link";
         else if (S_ISSOCK(buf.st_mode))
            ptr = "socket";
         else
            ptr = "** unknown mode **";
         printf("%s\n", ptr);
  }
   exit(0);
}
3.用户ID和设置组ID
与一个进程相关联的ID有6个或更多:
实际用户ID
实际组ID
有效用户ID
有效组ID
附件组ID
保存的设置用户组ID
保存的设置组ID


4.文件访问权限

st_mode包含了针对文件的访问权限位,每个文件有9个访问权限位,如下:
S_IRUSR  用户读
S_IWUSR  用户写
S_IXUSR  用户执行
S_IRGRP  组读
S_IWGRP  组写
S_IXGRP  组执行
S_IROTH  其他读
S_IWOTH  其他写
S_IXOTH  其他执行


5.access函数
access函数按实际用户ID和实际组ID进行访问权限测试
#include <unistd.h>

int access(const char *pathname, int mode);


#include "apue.h"
#include <fcntl.h>

int
main(int argc, char *argv[])
{
    if (argc != 2)
        err_quit("usage: a.out <pathname>");
    if (access(argv[1], R_OK) < 0)
        err_ret("access error for %s", argv[1]);
    else
        printf("read access OK\n");
    if (open(argv[1], O_RDONLY) < 0)
        err_ret("open error for %s", argv[1]);
    else
        printf("open for reading OK\n");
    exit(0);
}

6.umask函数

umask函数为进程设置文件模式创建屏蔽字,并返回以前的值

#include <sys/stat.h>

mode_t umask(mode_t cmask);

#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

int
main(void)
{
    umask(0);
    if (creat("foo", RWRWRW) < 0)
        err_sys("creat error for foo");
    umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if (creat("bar", RWRWRW) < 0)
        err_sys("creat error for bar");
    exit(0);
}

7.chmod和fchmod函数
修改文件的权限位。进程的有效用户ID必须等于文件所有者ID,或者该进程必须具有超级用户权限
#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);

int fchmod(int filedes, mode_t mode);


#include "apue.h"

int
main(void)
{
     struct stat      statbuf;

     /* turn on set-group-ID and turn off group-execute */

     if (stat("foo", &statbuf) < 0)
         err_sys("stat error for foo");
     if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
         err_sys("chmod error for foo");

     /* set absolute mode to "rw-r--r--" */

     if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
         err_sys("chmod error for bar");

     exit(0);
}

8.粘住位
S_ISVTX称为粘住位,对一个目录设置了粘住位以后,则只有对该目录具有写权限的用户在满足下列条件之一的情况下,才能删除或更名该目录下的文件:
拥有此文件
拥有此目录
是超级用户

9.chown,fchown和lchown函数
更改文件用户所有者ID 或组ID
#include <unistd.h>

int chown(const char *pathname, uid_t owner, gid_t
group);

int fchown(int filedes, uid_t owner, gid_t group);

int lchown(const char *pathname, uid_t owner,
gid_t group);

10.文件截短
将现有的文件长度截短为length字节
#include <unistd.h>

int truncate(const char *pathname, off_t length);

int ftruncate(int filedes, off_t length);

11.link,unlink,remove和rename函数
#include <unistd.h>

int link(const char *existingpath, const char
*newpath);

#include <unistd.h>

int unlink(const char *pathname);

#include "apue.h"
#include <fcntl.h>

int
main(void)
{
    if (open("tempfile", O_RDWR) < 0)
        err_sys("open error");
    if (unlink("tempfile") < 0)
        err_sys("unlink error");
    printf("file unlinked\n");
    sleep(15);
    printf("done\n");
    exit(0);
}


#include <stdio.h>

int remove(const char *pathname);

重命名文件
#include <stdio.h>

int rename(const char *oldname, const char *newname);

12.symlink和readlink函数
symlink创建一个符号链接
#include <unistd.h>
int symlink(const char *actualpath, const char
*sympath);

readlink 打开符号链接文件本身
#include <unistd.h>
ssize_t readlink(const char* restrict pathname,
char *restrict buf,
                 size_t bufsize);

13.utime函数
#include <utime.h>

int utime(const char *pathname, const struct
utimbuf *times);
函数使用的结构体为:
  struct utimbuf {
      time_t actime;    /* access time */
      time_t modtime;   /* modification time */
    }

#include "apue.h"
#include <fcntl.h>
#include <utime.h>

int
main(int argc, char *argv[])
{
    int             i, fd;
    struct stat     statbuf;
    struct utimbuf  timebuf;

    for (i = 1; i < argc; i++) {
        if (stat(argv[i], &statbuf) < 0) { /* fetch current times */
            err_ret("%s: stat error", argv[i]);
            continue;
        }
        if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) { /* truncate */
            err_ret("%s: open error", argv[i]);
            continue;

        }
        close(fd);
        timebuf.actime  =  statbuf.st_atime;
        timebuf.modtime =  statbuf.st_mtime;
        if (utime(argv[i], &timebuf) < 0) {     /* reset times */
            err_ret("%s: utime error", argv[i]);
            continue;
        }
    }
    exit(0);
}

14.mkdir和rmdir函数
mkdir函数创建目录,rmdir删除目录

#include <sys/stat.h>

int mkdir(const char *pathname, mode_t mode);

#include <unistd.h>

int rmdir(const char *pathname);

15.读目录




#include <dirent.h>

DIR *opendir(const char *pathname);



Returns: pointer if OK, NULL on error


struct dirent *readdir(DIR *dp);



Returns: pointer if OK, NULL at end of directory or error


void rewinddir(DIR *dp);

int closedir(DIR *dp);



Returns: 0 if OK, 1 on error


long telldir(DIR *dp);



Returns: current location in directory associated with dp


void seekdir(DIR *dp, long loc);

递归遍历目录结构并按文件类型计数

#include "apue.h"
#include <dirent.h>
#include <limits.h>

/* function type that is called for each filename */
typedef int Myfunc(const char *, const struct stat *, int);

static Myfunc     myfunc;
static int        myftw(char *, Myfunc *);
static int        dopath(Myfunc *);

static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

int
main(int argc, char *argv[])
{
    int     ret;

    if (argc != 2)
        err_quit("usage: ftw <starting-pathname>");

    ret = myftw(argv[1], myfunc);        /* does it all */

    ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
    if (ntot == 0)
        ntot = 1;       /* avoid divide by 0; print 0 for all counts */
    printf("regular files  = %7ld, %5.2f %%\n", nreg,
      nreg*100.0/ntot);
    printf("directories    = %7ld, %5.2f %%\n", ndir,
      ndir*100.0/ntot);
    printf("block special  = %7ld, %5.2f %%\n", nblk,
      nblk*100.0/ntot);
    printf("char special   = %7ld, %5.2f %%\n", nchr,
      nchr*100.0/ntot);
    printf("FIFOs          = %7ld, %5.2f %%\n", nfifo,
      nfifo*100.0/ntot);
    printf("symbolic links = %7ld, %5.2f %%\n", nslink,
      nslink*100.0/ntot);
    printf("sockets        = %7ld, %5.2f %%\n", nsock,
      nsock*100.0/ntot);

    exit(ret);
}

/*
* Descend through the hierarchy, starting at "pathname".
* The caller's func() is called for every file.
*/
#define FTW_F   1       /* file other than directory */
#define FTW_D   2       /* directory */
#define FTW_DNR 3       /* directory that can't be read */
#define FTW_NS  4       /* file that we can't stat */

static char *fullpath;      /* contains full pathname for every file */

static int                  /* we return whatever func() returns */
myftw(char *pathname, Myfunc *func)
{

    int len;
    fullpath = path_alloc(&len);    /* malloc's for PATH_MAX+1 bytes */
                                        /* (Figure 2.15) */
    strncpy(fullpath, pathname, len);       /* protect against */
    fullpath[len-1] = 0;                    /* buffer overrun */

    return(dopath(func));
}
/*
* Descend through the hierarchy, starting at "fullpath".
* If "fullpath" is anything other than a directory, we lstat() it,
* call func(), and return. For a directory, we call ourself
* recursively for each name in the directory.
*/
static int                  /* we return whatever func() returns */
dopath(Myfunc* func)
{
    struct stat     statbuf;
    struct dirent   *dirp;
    DIR             *dp;
    int             ret;
    char            *ptr;

    if (lstat(fullpath, &statbuf) < 0) /* stat error */
        return(func(fullpath, &statbuf, FTW_NS));
    if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */
        return(func(fullpath, &statbuf, FTW_F));

     /*
      * It's a directory. First call func() for the directory,
      * then process each filename in the directory.
      */
    if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
        return(ret);

    ptr = fullpath + strlen(fullpath);      /* point to end of fullpath */
    *ptr++ = '/';
    *ptr = 0;

     if ((dp = opendir(fullpath)) == NULL)     /* can't read directory */
         return(func(fullpath, &statbuf, FTW_DNR));

     while ((dirp = readdir(dp)) != NULL) {
         if (strcmp(dirp->d_name, ".") == 0 ||
             strcmp(dirp->d_name, "..") == 0)
                 continue;        /* ignore dot and dot-dot */

         strcpy(ptr, dirp->d_name);   /* append name after slash */

         if ((ret = dopath(func)) != 0)          /* recursive */
              break; /* time to leave */
     }
     ptr[-1] = 0;    /* erase everything from slash onwards */

     if (closedir(dp) < 0)
         err_ret("can't close directory %s", fullpath);

     return(ret);
}

static int
myfunc(const char *pathname, const struct stat *statptr, int type)
{
    switch (type) {
    case FTW_F:
        switch (statptr->st_mode & S_IFMT) {
        case S_IFREG:    nreg++;    break;
        case S_IFBLK:    nblk++;    break;
        case S_IFCHR:    nchr++;    break;
        case S_IFIFO:    nfifo++;   break;
        case S_IFLNK:    nslink++;  break;
        case S_IFSOCK:   nsock++;   break;
        case S_IFDIR:
            err_dump("for S_IFDIR for %s", pathname);
                    /* directories should have type = FTW_D */
        }
        break;

    case FTW_D:
        ndir++;
        break;

    case FTW_DNR:
        err_ret("can't read directory %s", pathname);
        break;

    case FTW_NS:
        err_ret("stat error for %s", pathname);
        break;

    default:
        err_dump("unknown type %d for pathname %s", type, pathname);
    }

    return(0);
}

16.chdir,fchdir和getcwd函数
chdir和fchdir 改变当前工作目录

#include <unistd.h>

int chdir(const char *pathname);

int fchdir(int filedes);

#include "apue.h"

int
main(void)
{

     if (chdir("/tmp") < 0)
         err_sys("chdir failed");
     printf("chdir to /tmp succeeded\n");
     exit(0);
}

getcwd获得当前的全路径
#include <unistd.h>

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



#include "apue.h"

  int
  main(void)
  {

      char    *ptr;
      int     size;

      if (chdir("/usr/spool/uucppublic") < 0)
          err_sys("chdir failed");

      ptr = path_alloc(&size); /* our own function */
      if (getcwd(ptr, size) == NULL)
          err_sys("getcwd failed");

      printf("cwd = %s\n", ptr);
      exit(0);
  }


17.设备特殊文件

设备号所用的存储类型是dev_t,通常用major和minor这两个宏来访问主次设备号。
系统中于每个文件名关联的st_dev值是文件系统的设备号,只有字符特殊文件和块特殊文件才有st_rdev值.
例:打印st_dev和st_rdev值
#include "apue.h"
#ifdef SOLARIS
#include <sys/mkdev.h>
#endif

int
main(int argc, char *argv[])
{

    int         i;
    struct stat buf;

    for (i = 1; i < argc; i++) {
        printf("%s: ", argv[i]);
        if (stat(argv[i], &buf) < 0) {
            err_ret("stat error");
            continue;
         }

         printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
         if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) {
             printf(" (%s) rdev = %d/%d",
                     (S_ISCHR(buf.st_mode)) ? "character" : "block",
                     major(buf.st_rdev), minor(buf.st_rdev));

         }
         printf("\n");
    }

    exit(0);

}





分享到:
评论

相关推荐

    unix环境高级编程--第章 文件和目录.doc.doc

    " Unix 环境高级编程 - 文件和目录" 在 Unix 环境高级编程中,文件和目录是两个基本概念。本章将详细介绍文件和目录的属性、stat 函数、fstat 函数、lstat 函数等知识点,并且对目录进行操作的函数进行详细的解释。...

    UNIX编程哲学-中文版

    - **哲学核心**:《UNIX编程哲学》一书深入探讨了UNIX系统背后的深层次思考,强调了一种独特的文化、艺术和设计哲学,这些元素共同构成了UNIX的核心价值。作者Henry Spencer在Usenet上的签名:“不懂Unix的人注定...

    UNIX编程艺术 - 扫描版 - 书签

    UNIX采用了一种层次结构的文件系统模型,其中所有的文件和目录都组织在一个树状结构中,根目录位于树的顶部。这种结构使得文件管理和访问变得非常直观和高效。此外,UNIX还提供了一套强大的权限管理系统,包括文件的...

    unix环境高级编程--第章 文件和目录(下).doc

    在UNIX环境中,高级编程涉及许多核心概念,其中文件和目录的管理是至关重要的。在“UNIX环境高级编程--第4章 文件和目录(下)”中,主要探讨了文件截短、文件系统以及inode等关键概念。 文件截短是一个实用功能,...

    Unix编程艺术--完整书签版

    《Unix编程艺术》解释了Unix的用户和组概念,以及如何通过chmod、chown等命令控制文件和目录的访问权限。同时,书中也讨论了如何避免常见的安全风险,如缓冲区溢出和权限滥用。 最后,书中还介绍了版本控制系统Git...

    Unix系统编程---makefile的编写

    在Unix系统编程中,`Makefile`是一种自动化构建工具,用于编译和链接源代码,执行测试等任务。它的核心作用是简化重复的构建过程,提高开发效率。本篇文章将深入探讨`Makefile`的编写及其在Unix环境中的应用。 首先...

    unix高级编程---apue.h 错误解决

    在Unix系统中,进行高级编程时,我们可能会遇到与`apue.h`相关的错误。`apue.h`是《Advanced Programming in the UNIX Environment》...同时,通过学习和使用`apue.h`,你将更深入地了解Unix编程的实践技巧和最佳实践。

    UNIX环境高级编程-pdf

    《UNIX环境高级编程》是一本深受程序员和系统管理员喜爱的经典之作,主要针对那些希望深入理解UNIX操作系统,并能熟练进行...无论是自学还是作为参考手册,这本书及其相关资料都能为你的UNIX编程之路提供强大的支持。

    UNIX高级编程5-6(大师著作)

    通过学习《UNIX高级编程》,程序员不仅可以掌握UNIX编程的核心技术,还能培养出系统级别的思维,从而能够设计和编写更高效、更稳定、更健壮的软件系统。无论是对初学者还是经验丰富的开发者,这都是一本极具价值的...

    Unix编程艺术中文版(非加密,带目录)

    根据提供的标题“Unix编程艺术中文版(非加密,带目录)”及描述“Unix编程艺术中文版”,可以推测这是一本介绍Unix系统编程原理、技巧和最佳实践的书籍。本书可能涵盖Unix系统的背景知识、核心概念、编程工具和技术...

    UNIX----系统编程

    - **POSIX标准**:提供了跨平台的UNIX编程接口,如pthread库用于线程编程。 通过深入学习和实践以上知识点,你将能够熟练地进行UNIX系统编程,开发出高效、稳定的应用程序。记得结合《UNIX系统编程》这样的参考...

    Java网络编程--Unix域协议:实现

    `domain`结构体(如图17-4所示)存储了关于协议家族的信息,包括协议族的标识(PF_UNIX)、名字(unix)以及协议转换数组`unix_sw`。`protosw`结构体(如图17-5所示)则包含了每个协议的操作函数指针,用于处理各种...

    Unix编程艺术/Unix环境高级编程(第二版)/Unix网络编程(第二版)

    《Unix编程艺术》、《Unix环境高级编程(第二版)》和《Unix网络编程(第二版)》是三本在IT领域中具有深远影响力的经典著作,涵盖了Unix操作系统的核心概念、系统调用、进程管理、文件操作、网络通信等多个重要主题...

    UNIX环境高级编程 -- PDF格式

    《UNIX环境高级编程》是一本深受程序员喜爱的经典教程,它深入介绍了在UNIX操作系统环境下进行系统级编程的各种技术和方法。这本书不仅适用于C++开发者,也对任何想要深入理解UNIX系统的程序员都极具价值。以下是对...

    shell编程和UNIX命令21-30

    2. **文件和目录操作**:在UNIX命令中,`cd`用于切换目录,`ls`列出目录内容,`mkdir`创建目录,`rm`删除文件或目录,`cp`和`mv`用于文件和目录的复制与移动。了解这些基本命令对于日常操作至关重要。 3. **文本...

    unix环境高级编程----------------------------------

    《Unix环境高级编程》一书详细讲解了以上所有内容,通过阅读和实践,读者可以深入理解Unix系统的运作原理,提高在Unix平台上的编程能力。无论是系统管理员、软件开发者还是研究人员,都能从中受益。

    unix环境高级编程--第章 UNIX基础知识.doc

    《UNIX环境高级编程》第一章主要介绍了UNIX操作系统的基础知识,包括登录、文件和目录等方面的知识。 1. **登录(Logging ln)** - **登录名**:登录到UNIX系统时,需要输入登录名和口令。登录名在系统口令文件...

    Linux编程接口 - Linux和UNIX系统编程手册

    - **系统管理员与高级用户**:希望深入了解Linux/UNIX编程接口及系统软件实现原理的人员。 #### 三、核心知识点概览 ##### 1. 标准兼容性与可移植性 - **POSIX标准**:本书重点关注Linux编程接口的同时,也非常...

    UNIX环境高级编程(第三版)-完整目录清晰版

    《UNIX环境高级编程》(第三版) 是...虽然提供的PDF版本仅包含前几章,但已足够作为了解和学习UNIX编程基础的参考资料。对于想要深入理解和开发UNIX系统级软件的工程师来说,《UNIX环境高级编程》是一本不可多得的宝典。

    UNIX环境高级编程--原始代码

    4. **文件系统**:介绍文件系统的基本概念,如文件类型、权限、硬链接和软链接,以及如何进行文件操作(mkdir(), unlink(), rename(), chmod()等)。 5. **信号处理**:阐述信号的概念,包括信号的发送(kill())、...

Global site tag (gtag.js) - Google Analytics