UNIX环境高级编程——文件和目录

来源:互联网 发布:jy淘宝店网址是多少 编辑:程序博客网 时间:2024/05/18 02:56


一、获取文件/目录的属性信息

int stat(constchar *path, struct stat *buf);
int fstat(int fd,struct stat *buf);
int lstat(constchar *path, struct stat *buf);
struct stat {
dev_t     st_dev;     /* ID of device containing file */
ino_t     st_ino;     /* inode number */
mode_t    st_mode;    /* protection */
nlink_t   st_nlink;   /* number of hard links */
uid_t     st_uid;     /* user ID of owner */
gid_t     st_gid;     /* group ID of owner */
dev_t     st_rdev;    /* device ID (if special file) */
off_t     st_size;    /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
time_t    st_atime;   /* time of last access */
time_t    st_mtime;   /* time of last modification */
time_t    st_ctime;   /* time of last status change */
};
 
示例程序:
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

#define MAJOR(a) (int)((unsignedshort)a >> 8)  // 高8位,主设备号
#define MINOR(a) (int)((unsignedshort)a & 0xFF)

int filetype(struct stat*buf)
{
    int flag = 0;
    printf("Filetype:");
    mode_t mode;
    mode = buf->st_mode;
    switch (mode & S_IFMT)
    {

    case S_IFSOCK:
        printf("socket\n");
        break;
    case S_IFLNK:
        printf("symbolic link\n");
        break;
    case S_IFREG:
        printf("regular file\n");
        break;
    case S_IFBLK:
        printf("block device\n");
        flag = 1;
        break;
    case S_IFDIR:
        printf("directory\n");
        break;
    case S_IFCHR:
        printf("character device\n");
        flag = 1;
        break;
    case S_IFIFO:
        printf("FIFO\n");
        break;
    default:
        printf("unknown file type\n");
        break;
    }

    return flag;
}

void fileperm(struct stat*buf, char perm[])
{
    strcpy(perm, "----------");
    perm[0] ='?';
    mode_t mode;
    mode = buf->st_mode;
    switch (mode & S_IFMT)
    {

    case S_IFSOCK:
        perm[0] ='s';
        break;
    case S_IFLNK:
        perm[0] ='l';
        break;
    case S_IFREG:
        perm[0] ='-';
        break;
    case S_IFBLK:
        perm[0] ='b';
        break;
    case S_IFDIR:
        perm[0] ='d';
        break;
    case S_IFCHR:
        perm[0] ='c';
        break;
    case S_IFIFO:
        perm[0] ='p';
        break;
    }

    if (mode & S_IRUSR)
        perm[1] ='r';
    if (mode & S_IWUSR)
        perm[2] ='w';
    if (mode & S_IXUSR)
        perm[3] ='x';
    if (mode & S_IRGRP)
        perm[4] ='r';
    if (mode & S_IWGRP)
        perm[5] ='w';
    if (mode & S_IXGRP)
        perm[6] ='x';
    if (mode & S_IROTH)
        perm[7] ='r';
    if (mode & S_IWOTH)
        perm[8] ='w';
    if (mode & S_IXOTH)
        perm[9] ='x';
    perm[10] ='\0';
}


int main(int argc,char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage %s file\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    printf("Filename:%s\n", argv[1]);
    struct stat sbuf;
    if (lstat(argv[1],&sbuf) == -1)
        ERR_EXIT("stat error");

    printf("file in Dev number:major %d, minor %d\n",
           MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev));
    printf("File inode:%d\n", (int) sbuf.st_ino);

    if (filetype(&sbuf))
    {
        printf("Device number:major %d, minor %d\n",
               MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));
    }

    char perm[11]= {0};
    fileperm(&sbuf, perm);
    printf("File permission bits=%o %s\n", sbuf.st_mode& 07777, perm);

    return 0;
}
 
测试如下:
huangcheng@ubuntu:~$ ./a.out hc
Filename:hc
file in Dev number:major 8, minor 1
File inode:929485
Filetype:regular file
File permission bits=644-rw-r--r--
 
 
二、目录的访问

功能说明:打开一个目录
原型:DIR*  opendir(char*pathname);
返回值:
打开成功,返回一个目录指针
打开失败,则返回NULL



功能说明:访问指定目录中下一个连接的细节
原型:struct  dirent*  readdir(DIR  *dirptr);
返回值:
返回一个指向dirent结构的指针,它包含指定目录中下一个连接的细节;
没有更多连接时,返回NULL



功能说明:关闭一个已经打开的目录
原型:int closedir (DIR  *dirptr);
返回值:调用成功返回0,失败返回-1
struct dirent { ino_t     d_ino;       /* inode number */       off_t      d_off;       /* offset to the next dirent */       unsigned short d_reclen;    /* length of this record */       unsigned char  d_type;      /* type of file; not supported                                              by all file system types */       char      d_name[256]; /* filename */ };

 
 
三、目录的创建删除和权限设置

功能说明:用来创建一个称为pathname的新目录,它的权限位设置为mode
原型:int  mkdir(char*pathname,mode_t mode);
返回值:调用成功返回0,失败返回-1


功能说明:删除一个空目录
原型:int  rmdir(char*pathname);
返回值:调用成功返回0,失败返回-1


功能说明:用来改变给定路径名pathname的文件的权限位。 为了改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID,或者该进程必须具有超级用户的权限。
原型:int  chmod (char*pathname, mode_t mode);
int  fchmod (int  fd, mode_t mode);
返回值:调用成功返回0,失败返回-1


功能说明:用来改变文件所有者的识别号(owner id)或者它的用户组识别号(group ID), 如若两个参数owner或group中的任意一个为-1,则对应的ID不变。
原型:int  chown (char*pathname, uid_t owner,gid_t group);
int  fchown (int  fd, uid_t owner,gid_t group);
返回值:调用成功返回0,失败返回-1

示例代码:

#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>#include<dirent.h>#define ERR_EXIT(m) \    do { \        perror(m); \        exit(EXIT_FAILURE); \    } while(0)int main(int argc, char *argv[]){    DIR *dir = opendir(".");    struct dirent *de;    while ((de = readdir(dir)) != NULL)    {        if (strncmp(de->d_name, ".", 1) == 0)            continue; //忽略隐藏文件        printf("%s\n", de->d_name);    }    closedir(dir);    exit(EXIT_SUCCESS); // 等价于return 0}
 
四、文件长度stat结构成员st_size表示以字节为单位的文件长度。此字段只对普通文件、目录文件盒符号链接有意义。对于普通文件,其文件长度可以是0,在读这种文件时,将得到文件结束指示。对于目录,文件长度通常是一个数(例如512)的倍数。对于符号链接,文件长度是文件名中的实际字节数(即huangcheng的符号链接为10,不包括c语言用作名字结尾的null字符)


五、文件截短

int truncate(const char *path, off_t length);int ftruncate(int fd, off_t length);
这两个函数将把现有的文件长度截短length字节。如果该文件以前的长度大于length,则超过length以外的数据就被删除。


六、chdir、fchdir和getcwd函数

每个进程都有一个当前目录,此目录是搜索所有相对路径名的起点。当前工作目录是进程的一个属性,起始目录则是登陆名(/etc/passwd)的一个属性。

int chdir(constchar *path);
int fchdir(int fd);
这两个函数中,分别用path或打开文件描述符指定新的当前工作目录。



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

把当前目录的绝对地址保存到 buf 中,buf 的大小为 size
。如果 size太小无法保存该地址,返回 NULL 并设置 errno 为 ERANGE。

可以采取令 buf 为 NULL并使 size 为负值来使 getcwd 调用 malloc 动态给 buf 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。

原创粉丝点击