Linux C 文件操作

Linux C 文件编程

系统调用比标准库移植性差(不同OS接口不一定一致)
系统调用会进入内核态, 对程序运行的开销较大.
默认文件描述符 0:标准输入 1:标准输出 2:标准错误输出

文件常用API

  • open 打开文件, 返回文件描述符.
  • close 关闭文件
  • read 读取文件, 返回读取的字节.
  • write 写入文件, 返回写入的字节.
  • access 判断 文件/目录 是否存在及访问权限
  • fcntl 对文件描述符提供控制, 从而改变文件属性.
  • lseek 定位文件读写位置, 返回与原位置的差值.
  • dup 复制文件描述符, 返回新的文件描述符.
  • stat函数族 获取文件的元数据(状态)
    • stat 通过文件路径来获取文件元数据
    • fstat 通过文件描述符来获取文件元数据
    • lstat 获取软链接文件本身的元数据, 其他同stat.

目录常用API

  • getcwd 获取当前工作目录
  • chdir 改变当前目前工作目录到指定目录
  • chroot 改变根目录到指定目录
  • mkdir 创建目录
  • rmdir 删除目录(必须为空目录)
  • opendir 打开目录, 返回DIR*指针.
  • closedir 关闭目录
  • readdir 获取目录信息, 返回dirent*结构体.

其他常用API

  • umask 改变 文件/目录 默认权限掩码
  • chmod 改变 文件/目录 权限
  • chown 改变 文件/目录 属主和属组
  • link函数族 链接文件
    • link 硬链接文件
    • symlink 软链接文件
    • unlink 删除文件一次硬链接(删除文件)

文件复制

#include 
#include 
#include 

#include 
#include 

#define MAXLINE 80

void if_error(int stat_code, char *err_msg)
{
    if (stat_code < 0) {
        perror(err_msg);
        exit(errno);
    }
}

int main(int argc, char **argv)
{
    char *src, *dest;
    int fd_rd, fd_wr;
    int n_rd, n_wr;
    char buf[MAXLINE];

    if (argc != 3) return -1;

    /* set src, dest file by argv */
    src = argv[1];
    dest = argv[2];

    fd_rd = open(src, O_RDONLY);
    if_error(fd_rd, "open");

    fd_wr = open(dest, O_WRONLY|O_CREAT, 0664);
    if_error(fd_wr, "open");

    while (1) {
        n_rd = read(fd_rd, buf, MAXLINE);
        if_error(n_rd, "read");

        if (n_rd == 0) break;
        n_wr = write(fd_wr, buf, n_rd);
        if_error(n_wr, "write");
    }

    close(fd_rd);
    close(fd_wr);
    return 0;
}

获取文件元数据

access time: 访问文件内容时间
change time: 修改文件属性时间
modify time: 修改文件内容时间

#include 
#include 
#include 

#include 
#include 
#include 
#include 

void if_error(int stat_code, char *err_msg)
{
    if (stat_code < 0) {
        perror(err_msg);
        exit(errno);
    }
}

void get_type(char *path)
{
    int ret;
    struct stat info;
    mode_t mode;

    ret = lstat(path, &info);
    if_error(ret, "stat");

    mode = info.st_mode;

    if (S_ISREG(mode)) printf("type: file\n");
    else if (S_ISDIR(mode)) printf("type: dir\n");
    else if (S_ISLNK(mode)) printf("type: symbol link file\n");
    else if (S_ISCHR(mode)) printf("type: character device file\n");
    else if (S_ISBLK(mode)) printf("type: block device file\n");
    else if (S_ISFIFO(mode)) printf("type: fifo file\n");
    else if (S_ISSOCK(mode)) printf("type: socket file\n");
}

void get_perm(char *path)
{
    int ret;
    struct stat info;
    mode_t mode;

    ret = lstat(path, &info);
    if_error(ret, "stat");

    mode = info.st_mode;

    if (mode & S_IRUSR) printf("owner can read\n");
    if (mode & S_IWUSR) printf("owner can write\n");
    if (mode & S_IRGRP) printf("group can read\n");
    if (mode & S_IWGRP) printf("group can write\n");
    if (mode & S_IROTH) printf("others can read\n");
    if (mode & S_IWOTH) printf("others can write\n");
}

void get_time(char *path)
{
    int ret;
    struct stat info;

    ret = lstat(path, &info);
    if_error(ret, "stat");

    printf("access time: %s", ctime(&info.st_atime));
    printf("modify time: %s", ctime(&info.st_mtime));
    printf("change time: %s", ctime(&info.st_ctime));
}

int main(int argc, char **argv)
{
    char *path;

    if (argc != 2) return -1;

    path = argv[1];

    get_type(path);
    get_perm(path);
    get_time(path);
    return 0;
}

遍历目录下文件

#include 
#include 
#include 

#include 
#include 
#include 

#define MAXLINE 80

void if_error(int stat_code, char *err_msg)
{
    if (stat_code < 0) {
        perror(err_msg);
        exit(errno);
    }
}

void list_file(char *path)
{
    DIR *dir;
    struct dirent *entry;
    struct stat info;
    char buf[MAXLINE];
    int ret;

    dir = opendir(path);
    if (NULL == dir) exit(-1);

    while(1) {
        /* search file one by one */
        entry = readdir(dir);
        if (NULL == entry) break;

        /* ignone . and .. */
        if(!strncmp(entry->d_name, ".", 1) || !strncmp(entry->d_name, "..", 2))
            continue;

        sprintf(buf ,"%s/%s", path, entry->d_name);
        /* get file info */
        ret = lstat(buf, &info);
        if_error(ret, "lstat");

        /* recur if it is dir else print file name */
        if (S_ISDIR(info.st_mode)) {
            list_file(buf);
        } else {
            printf("%s\n", buf);
        }
    }
    closedir(dir);
}

int main(int argc, char **argv)
{
    char *path;

    if (argc != 2) return -1;

    path = argv[1];

    list_file(path);
    return 0;
}

你可能感兴趣的:(Linux,C)