2.1 linux文件系统相关函数

stat

既是命令,也是同名的系统函数,用来获取文件的inode信息,stat跟踪符号链接,lstat不跟踪符号链接。

SYNOPSIS
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <unistd.h>

   int stat(const char *path, struct stat *buf);
   int fstat(int fd, struct stat *buf);
   int lstat(const char *path, struct stat *buf);
RETURN VALUE
   On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

函数相关参数:

       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 */
           };

The following flags are defined for the st_mode field:

           S_IFMT     0170000   bit mask for the file type bit fields
           S_IFSOCK   0140000   socket
           S_IFLNK    0120000   symbolic link
           S_IFREG    0100000   regular file
           S_IFBLK    0060000   block device
           S_IFDIR    0040000   directory
           S_IFCHR    0020000   character device
           S_IFIFO    0010000   FIFO
           S_ISUID    0004000   set UID bit
           S_ISGID    0002000   set-group-ID bit (see below)
           S_ISVTX    0001000   sticky bit (see below)
           S_IRWXU    00700     mask for file owner permissions
           S_IRUSR    00400     owner has read permission
           S_IWUSR    00200     owner has write permission
           S_IXUSR    00100     owner has execute permission
           S_IRWXG    00070     mask for group permissions
           S_IRGRP    00040     group has read permission
           S_IWGRP    00020     group has write permission
           S_IXGRP    00010     group has execute permission
           S_IRWXO    00007     mask for permissions for others (not in group)
           S_IROTH    00004     others have read permission
           S_IWOTH    00002     others have write permission
           S_IXOTH    00001     others have execute permission

例:通过stat取得的mode参数可以通过系统提供的相关掩码过滤出文件权限

#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    struct stat st; 
    if(argc < 2) {  //判断有没有跟文件
        printf("./a.out filename\n");
        return 0;
    }

    stat(argv[1], &st); //获取文件的inode信息
    if((st.st_mode&S_IFMT) == S_IFDIR) //通过st.st_mode与S_TFMT位与&运算,得到文件的flags,再和目录的文件类型flags比较
        printf("%s is dirctory\n", argv[1]);
    else
        printf("%s isn't dirctory\n", argv[1]);

    printf("file_size = %d\n", (int)st.st_size);//获取文件大小
    return 0;
}

注:&、| 和==的优先级,==的优先级比&、| 高,如果要st.st_mode&S_IFMT和S_IFDIR比较的话,一定要把st.st_mode&S_IFMT用括号括起来,确定执行顺序。

access

按执行该函数的用户,测试是否对文件有mode权限

SYNOPSIS
   #include <unistd.h>

   int access(const char *pathname, int mode);
RETURN VALUE
   On  success (all requested permissions granted), zero is returned.  On error (at     least one bit in mode asked for a permission that is denied, or some other error    occurred),  -1  is returned, and errno is set appropriately.

mode
    R_OK    是否有读权限    
    W_OK    是否有写权限
    X_OK    是否有执行权限
    F_OK    测试一个文件是否存在

例:测试执行该函数的用户对”hello”文件是否有读权限

    if(access("hello", R_OK) == 0)
        printf("you can read\n");
    else {
        printf("you can't read\n");
        perror("access");
    }  
注:可以通过返回的errno得知为什么不能读。这个函数是跟踪符号链接的

chmod

修改文件权限成为指定的权限,当然用户必须要先对文件有操作权限,

SYNOPSIS
   #include <sys/stat.h>

   int chmod(const char *path, mode_t mode);
   int fchmod(int fd, mode_t mode);

RETURN VALUE
   On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

例:把hello的权限改为只有所有者可以读,写,组用户可以读,其他用户都没有操作权限

    if(chmod("hello", S_IRUSR | S_IWUSR | S_IRGRP) == 0)
        printf("successful\n");
    else
        perror("chmod");

mode的具体值可以参考stat上的

用户ID(user_id)和组ID(gruop_id),对应的ID可以从从/etc/passwd下查看。

truncate

截断一个文件,可以设定截断的长度

SYNOPSIS
   #include <unistd.h>
   #include <sys/types.h>

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

RETURN VALUE
   On  success,  zero is returned.  On error, -1 is returned, and errno is set appropriately

例:把”hello”文件截断成12个字节

    if(truncate("hello", 12) < 0)
        perror("truncate");
    else
        printf("successful\n");

创建一个硬链接

SYNOPSIS
   #include <unistd.h>

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

RETURN VALUE
   On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

link("hello", "world");

创建一个软链接/符号链接

SYNOPSIS
   #include <unistd.h>

   int symlink(const char *oldpath, const char *newpath);

RETURN VALUE
   On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

symlink("hello", "cccccc");

读取软链接指向的文件的文件名,如果读成功返回值是这个文件名的长度,失败返回-1,并设置errno

SYNOPSIS
   #include <unistd.h>

   ssize_t readlink(const char *path, char *buf, size_t bufsiz);

RETURN VALUE
   On success, readlink() returns the number of bytes placed in buf.  On error, -1 is returned and errno is set to indicate the error.

例:

    len = readlink("link_stat", buf, sizeof(buf);
    printf("%d\t\s\n", len. buf);
  • 如果是符号链接,删除符号链接
  • 如果是硬链接,硬链接数减1,当减为0的时候,释放数据库块和inode
  • 如果文件硬链接数为0,但进程一打开该文件,并持有文件描述符,则等该进程关闭该文件时,kernel才真正去删除该文件
  • 利用该文件特性创建临时文件,先open或creat创建一个文件,然后马上unlink掉。
SYNOPSIS
    #include <unistd.h>
    int unlink(const char *pathname);

RETURN VALUE
    On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

例:创建一个文件,写入数据,再unlink掉,然后从文件中独处数据,并打印到屏幕上。

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUFFER "nihao\n"
int main(void)
{
    int fd, len;
    char buf[100] = "0";

    fd = open("temp.rar", O_CREAT | O_RDWR, 0644);  //创建文件

    write(fd, BUFFER, strlen(BUFFER));//写入数据
    unlink("temp.rar");//把硬链接减1
    lseek(fd, 0, SEEK_SET); //把指针重新指到文件开头
    len = read(fd, buf, sizeof(buf));//读出数据
    write(STDOUT_FILENO, buf, len);//打印出来
    close(fd);//关闭文件描述符
    return 0;   
}

注:再读文件之前,一定要把指针重新只会文件开头

chdir

运行该函数后,之后的程序跳转到该目录执行

SYNOPSIS
   #include <unistd.h>

   int chdir(const char *path);
   int fchdir(int fd);

RETURN VALUE
   On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

getcwd

获取当前工作目录,他的返回值就是buf的首地址

SYNOPSIS
   #include <unistd.h>

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

RETURN VALUE
   On success, these functions return a pointer to a string containing the pathname of the current working directory
   On failure, these functions return NULL, and errno is set to indicate the error. 

例:chdir和getcwd的具体实现

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    char buf[100] = "0";
    if(argc < 2) {  
        printf("./a.out path\n");
        exit(0);
    }   
    if(chdir(argv[1]) < 0)//修改当前路径
        perror("chdir");

    int fd = open("ggggggg", O_CREAT, 0644);、、在修改之后的路径生成一个文件ggggggg

    printf("PATH = %s\n", getcwd(buf, sizeof(buf)));//打印当前工作路径的目录
    return 0;
}

你可能感兴趣的:(文件系统,Linux编程)