Linux 文件与目录

文件与目录

常用函数

stat()

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

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

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

    • 功能: 返回一个与pathname 或fd 指定的文件属性信息,存储在结构体buf,lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息。
  • 返回: 若成功则为0 ,若出错则为-1

access()

  • int access(const char *pathname, int mode);
  • 功能: 检查是否可以对指定文件进行某种操作,即检查文件访问的权限mode
    • R_OK 判断文件是否有读权限
    • W_OK 判断文件是否有写权限
    • X_OK 判断文件是否有可执行权限
    • F_OK 判断文件是否存在
  • 返回:成功执行时返回0 ,若出错为-1

umask()

  • mode_t umask(mode_t mode);
  • 功能:为进程设置文件方式创建屏蔽字,并返回以前的值
  • 返回:以前的文件模式创建屏蔽字

chmod()

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

    int fchmod(int fd, mode_t mode);

  • 功能:更改现存文件的权限。chmod函数在指定的文件上进行操作,而fchmod则对已打开的文件进行操作。
  • 返回:成功返回0 ,出错返回-1

truncate()

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

    int ftruncate(int fd, off_t length);

  • 功能:文件截短,length:文件截短后的长度
  • 返回:成功返回0 ,出错返回-1

utime()

  • int utime(const char *pathname, const struct utimbuf *times);
  • 功能:更改文件的存取和修改时间
  • 返回:成功返回0 ,出错返回-1
struct utimbuf {
    time_t actime;       /* access time */
    time_t modtime;      /* modification time */
};
字段说明例子ls 选项
st_atime文件数据最后访问时间read-u
st_mtime文件数据最后修改时间write默认
st_ctimei 节点最后更改时间chmod, chown-c
  • int link(const char *existingpath, const char *newpath);
  • 功能: 创建一个指向现存文件连接( 硬链接),类似与linux系统的ln
  • 返回: 成功返回0 ,出错返回-1

  • int unlink(const char *pathname);
  • 功能: 删除pathname 指定的硬链接,并将由pathname所引用的文件链接计数减1
  • 返回: 成功返回0 ,出错返回-1

  • 硬链接创建条件
    • 针对文件创建链接
    • 必须是同一个分区
    • 只用超级用户才能对目录建立链接
  • 文件删除条件
    • 链接计数为0
    • 无其他进程打开该文件

remove() 与 rename()

  • int remove(const char *pathname);
  • 功能: 解除对一个文件或目录的连接
  • 返回: 成功返回0 ,出错返回-1

  • int rename(const char *oldname, const char *newname);
  • 功能: 文件或目录更名
  • 返回: 成功返回0 ,出错返回-1

  • 对于文件,remove的功能与unlink相同。
  • 对于目录,remove的功能与rmdir相同。
  • int symlink(const char *actualpath, const char *sympath);
  • 功能: 创建一个符号连接( 软连接),与linux系统的ln -s类似
  • 返回: 成功返回0 ,出错返回-1

  • int readlink(const char *restrict pathname,char *restrict buf, size_t bufsize);
  • 功能: 打开该连接本身,并读该链接中的名字。
  • 返回: 成功返回读到的字节数,出错返回-1

  • 符号链接创建
    • 创建符号链接并不要求actualpath存在
    • 可以跨文件系统建立符号链接

目录操作

mkdir() 与 rmdir
  • int mkdir(const char *pathname, mode_t mode);
  • 功能: 创建目录
  • 返回: 成功返回0 ,出错返回-1

  • int rmdir(const char *pathname);
  • 功能: 删除目录
  • 返回: 成功返回0 ,出错返回-1
opendir(), readdir(), rewinddir(), closedir()
  • DIR *opendir(const char *pathname);
  • 功能: 打开目录
  • 返回: 成功返回目录指针,出错返回NULL

  • struct dirent *readdir(DIR *dp);
  • 功能: 读取目录
  • 返回: 成功返回指针,若在目录结尾或者出错返回NULL

  • void rewinddir(dir(DIR *dp);
  • 功能: 重新定位从头开始读取
  • 返回: 成功返回0 ,出错返回-1

  • int closedir(DIR *dp);
  • 功能: 关闭目录
  • 返回: 成功返回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 */
           };

d_type表示档案类型:

类型英文说明中文说明
DT_BLKThis is a block device.块设备文件
DT_CHRThis is a character device.字符设备文件
DT_DIRThis is a directory.普通目录
DT_FIFOThis is a named pipe (FIFO).命名管道或FIFO
DT_LNKThis is a symbolic link.链接文件
DT_REGThis is a regular file.普通文件
DT_SOCKThis is a UNIX domain socket.本地套接口
DT_UNKNOWNThe file type is unknown.未知的类型
enum{ 
    DT_UNKNOWN = 0, 
    # define DT_UNKNOWN DT_UNKNOWN 
    DT_FIFO = 1, 
    # define DT_FIFO DT_FIFO 
    DT_CHR = 2, 
    # define DT_CHR DT_CHR 
    DT_DIR = 4, 
    # define DT_DIR DT_DIR 
    DT_BLK = 6, 
    # define DT_BLK DT_BLK 
    DT_REG = 8, 
    # define DT_REG DT_REG 
    DT_LNK = 10, 
    # define DT_LNK DT_LNK 
    DT_SOCK = 12, 
    # define DT_SOCK DT_SOCK 
    DT_WHT = 14 
    # define DT_WHT DT_WHT 
}; 

获取地址

  • int chdir(const char *pathname);

    int fchdir(int fd);

  • 功能: 分别用pathname 或fd 来指定新的当前工作目录
  • 返回: 成功返回0 ,出错返回-1

  • char *getcwd(char *buf, size_t size);
  • 功能: 获得当前工作目录的绝对路径名,类似与linux的pwd
  • 返回: 成功返回buf ,出错返回NULL

函数详解

stat函数

  • 包含在struct stat中,可以通过stat函数获得:
struct stat{
    mode_t      st_mode;        /file type & permission/
    ino_t       st_ino;         /i-node 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/
    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/
  };
  • 文件类型,通过调用文件类型判断宏运算文件属性结构体中的st_mode获得文件类型
    • 普通文件(regular file) S_ISREG()
    • 目录文件(directory file) S_ISDIR()
    • 块特殊文件(block special file) S_ISBLK()
    • 字符特殊文件(chatacter special file) S_ISCHR()
    • FIFO(named pipe) S_ISFIFO()
    • 套接字(socket) S_ISSOCK()
    • 符号链接(symbolic link) S_ISLNK()
  • 文件权限,文件权限通过按位或方式构造,有9种文件访问权限位
    • 用户权限:S_IRUSR, S_IWUSR, S_IXUSR
    • 组权限:S_IRGRP, S_IWGRP, S_IXGRP
    • 其它权限:S_IROTH, S_IWOTH, S_IXOTH
  • 程序示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
void show_time(time_t t)
{
    struct tm* p = NULL;
    p = localtime(&t);
    printf("%d-%d-%d %d:%d:%d\n",p->tm_year+1900,p->tm_mon+1,p->tm_mday,\
                        p->tm_hour,p->tm_min,p->tm_sec);
}
int main(int argc,char *argv[])
{
    //1.参数验证
    if (argc != 2){
        perror("输入的参数错误!");
        exit(1);
    }
    //2.获取文件属性
    struct stat buf;
    memset(&buf,0,sizeof(buf));
    if(stat(argv[1],&buf) < 0){
        printf("%s",strerror(errno));
        exit(-1);
    }
    //3.判断文件类型
    if(S_ISREG(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"普通文件");
    if(S_ISDIR(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"目录文件");
    if(S_ISBLK(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"快特殊文件");
    if(S_ISCHR(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"字符特殊文件");
    if(S_ISFIFO(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"FIFO(named pipe)");
    if(S_ISSOCK(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"套接字(socket)");
    if(S_ISLNK(buf.st_mode))
        printf("%s file mode is %s\n",argv[1],"符号链接");
    //4.文件inode,UID,Time of last acess
    printf("inode:%ld\nUID:%d\n",buf.st_ino,buf.st_uid);
    printf("time of last acess:");
    show_time(buf.st_atime);
    return 0;
}

chmod函数权限

  • mode:文件权限(按位或操作)
    • S_ISUID, S_ISGID, S_ISVTX
    • S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR
    • S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP
    • S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>       
#include <fcntl.h>
int main(int argc ,char *argv[])
{
    if(argc < 2){   
        perror("参数不对\n");
        exit(1);
    }
    if(access(argv[1],F_OK) == 0){
        perror("文件已存在\n");
        exit(1);
    }
    mode_t save_mask=umask(0555);
    int fp = open(argv[1],O_RDWR|O_CREAT,0613);
    if(fp < 0){
        perror("打开文件失败\n");
        exit(1);
    }
    struct stat buff;
    if(stat(argv[1],&buf) == -1){
        perror("get informaintion of file fail");
        exit(1);
    }
    if(access(argv[1],W_OK) == -1){
        perror("文件没有写权限\n");
    }
    else{ 
        if(chmod(argv[1],buf.st_mode & (~S_IWUSR)) == -1){
            perror("更改失败\n");
            exit(1);
        }
    }
    umask(save_mask);
    close(fp);
    return 0;
}

access与umask函数示例

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(void)
{
    int save_mask = umask(0333);
    int fd = creat("pig.txt",0777);
    if(access("pig.txt",F_OK) < 0){
        perror("creat file fail");
    }
    system("touch 1.c");
    umask(save_mask);
    return 0;
}

utime函数示例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <utime.h>
void show_time(time_t t)
{
    struct tm* p = NULL;
    p = localtime(&t);
    printf("%d-%d-%d %d:%d:%d\n",p->tm_year+1900,p->tm_mon+1,p->tm_mday,\
                        p->tm_hour,p->tm_min,p->tm_sec);
    }
int main(int argc,char *argv[])
{
    if(argc != 2){
        perror("参数不对!");
        exit(-1);
    }
    struct stat buf;
    struct stat save_buf;
    memset(&buf,0,sizeof(buf));
    memset(&save_buf,0,sizeof(save_buf));
    if(lstat(argv[1],&buf) < 0){
        printf("%s\n",strerror(errno));
        exit(0);
    }
    save_buf = buf;
    printf("time of last access:");
    show_time(buf.st_atime);
    printf("time of last modification:");
    show_time(buf.st_mtime);
    sleep(3);
    int fd = open(argv[1],O_RDWR);
    char buffer[1024] = " ";
    read(fd,buffer,1024);
    write(fd,"hello world\n",sizeof("hello world\n"));
    sleep(3);
    memset(&buf,0,sizeof(buf));
    if(lstat(argv[1],&buf) < 0){
        printf("%s\n",strerror(errno));
        exit(0);
    }
    printf("time of last access:");
    show_time(buf.st_atime);
    printf("time of last modification:");
    show_time(buf.st_mtime);
    close(fd);
    struct utimbuf ubuf;
    ubuf.actime = save_buf.st_atime;
    ubuf.modtime = save_buf.st_mtime;
    sleep(3);
    if(utime(argv[1],&ubuf) < 0){
        perror("modfiy time fail\n");
        exit(1);
    }
    memset(&buf,0,sizeof(buf));
    if(lstat(argv[1],&buf) < 0){
        printf("%s\n",strerror(errno));
        exit(0);
    }
    printf("time of last access:");
    show_time(buf.st_atime);
    printf("time of last modification:");
    show_time(buf.st_mtime);
    return 0;
}

目录操作,实现ls -R的功能

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>  
void List(char *path)  
{  
    struct dirent *file = NULL;  
    DIR *pDir;
    char fileName[256][256];
    int i = 0, len = 0;
    if((pDir = opendir(path)) != NULL){  
        while(NULL != (file = readdir(pDir))){  
            if(strcmp(file->d_name,".") == 0){  //排除隐藏目录
                printf(".  ");
                continue;
            }
            else if(strcmp(file->d_name,"..") == 0){
                printf("..  ");
                continue;
            }
            else if(file->d_type == DT_DIR){  //查找到子目录并将其放在数组fileName中
                printf("\033[32;49m%s  \033[0m", file->d_name);  
                sprintf(fileName[len++],"%s%s%s",path,"/",file->d_name);
            }
            else{ 
                printf("%s  ", file->d_name);  
            }
        }
        printf("\n\n");
        for(i=0 ; i < len ; ++i){
            printf("%s:\n",fileName[i]);    //递归调用显示子目录内容
            List(fileName[i]);
        }
        closedir(pDir);  
    }  
    else{ 
        printf("Open Dir-[%s] failed.\n\n", path);
    }
}  
int main(int argc,char *argv[])   
{           
    char buf[256] = " ";
    int i = 0;
    if(argc < 2){   //入参判断
        getcwd(buf,sizeof(buf));
        List(buf);  
    }
    else{
        for(i=1 ; i < argc ; ++i){
            List(argv[i]);  
        }
    }
    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值