linux系统文件函数

2+K

vim模式下按完2,再按K,即可跳转到man-page

lseek实现文件拓展

点击查看代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

int main()
{
	//打开一个已经存在的文件
	int fd = open("aa",O_RDWR);
	if(fd==-1)
	{
		perror("open");
		exit(1);
	}
	//文件拓展
	int ret = lseek(fd,0,SEEK_END);
	printf("file length %d\n",ret);

	ret = lseek(fd,2000,SEEK_END);
	printf("return value %d\n",ret);

	//使用lseek实现文件拓展,需要在最后做一次写操作
	write(fd,"a",1);
	close(fd);

	return 0;
}

stat函数

image

st_mode结构体剖析

image
image
image

交换空间

image

stat ,st_mode结合使用的例子

点击查看代码
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("./a.out filename\n");
        exit(1);
    }

    struct stat st;
    int ret = stat(argv[1], &st);
    if(ret == -1)
    {
        perror("stat");
        exit(1);
    }

    // 存储文件类型和访问权限
    char perms[11] = {0};
    // 判断文件类型
    switch(st.st_mode & S_IFMT)
    {
        case S_IFLNK:
            perms[0] = 'l';
            break;
        case S_IFDIR:
            perms[0] = 'd';
            break;
        case S_IFREG:
            perms[0] = '-';
            break;
        case S_IFBLK:
            perms[0] = 'b';
            break;
        case S_IFCHR:
            perms[0] = 'c';
            break;
        case S_IFSOCK:
            perms[0] = 's';
            break;
        case S_IFIFO:
            perms[0] = 'p';
            break;
        default:
            perms[0] = '?';
            break;
    }
    // 判断文件的访问权限
    // 文件所有者
    perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';
    perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';
    perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';
    // 文件所属组
    perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';
    perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';
    perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';
    // 其他人
    perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';
    perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';
    perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';

    // 硬链接计数
    int linkNum = st.st_nlink;
    // 文件所有者
    char* fileUser = getpwuid(st.st_uid)->pw_name;
    // 文件所属组
    char* fileGrp = getgrgid(st.st_gid)->gr_name;
    // 文件大小
    int fileSize = (int)st.st_size;
    // 修改时间
    char* time = ctime(&st.st_mtime);
    char mtime[512] = {0};
    strncpy(mtime, time, strlen(time)-1);

    char buf[1024];
    sprintf(buf, "%s  %d  %s  %s  %d  %s  %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);

    printf("%s\n", buf);

    return 0;
}

上述代码使用示例

image

lstat使用示例

点击查看代码
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
    if(argc < 2) {
        printf("a.out filename\n");
        exit(1);
    }    
    struct stat buf_st;
    int ret = lstat(argv[1], &buf_st);
    if(ret == -1)  {
        perror("stat");
        exit(1);
    }
    printf("file size = %d\n", (int)buf_st.st_size);
    return 0;
}

stat和lstat的区别:当文件是一个符号链接时,lstat返回的是
该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。
(似乎有些晕吧,这样记,lstat比stat多了一个l,因此它是有本事
处理符号链接文件的,因此当遇到符号链接文件时,lstat当然不会放过。
而stat系统调用没有这个本事,它只能对符号链接文件睁一只眼
闭一只眼,直接去处理链接所指文件喽)
**简而言之,stat具有追踪功能,lstat不具有追踪功能**

image

access函数

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
    if(argc < 2)    {
        printf("a.out filename\n");
        exit(1);
    }

    int ret = access(argv[1], W_OK);
    if(ret == -1)    {
        perror("access");
        exit(1);
    }
    printf("you can write this file.\n");
    return 0;
}

chmod函数

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(int argc, char* argv[])
{
    if(argc < 2) {
        printf("a.out filename\n");
        exit(1);
    }
    int ret = chmod(argv[1], 0755);
    if(ret == -1) {
        perror("chmod");
        exit(1);
    }
    return 0;
}

chown函数

// 测试未成功

truncate函数

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        printf("a.out filename 111\n");
        exit(1);
    }

    long int len = strtol(argv[2], NULL, 10); 
    int  aa = truncate(argv[1], len);
    if(aa == -1)
    {
        perror("truncate");
        exit(1);
    }
    return 0;
}

image

link函数:创建硬链接

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        printf("a.out oldpath newpath\n");
        exit(0);
    }

    int ret = link(argv[1], argv[2]);
    if(ret == -1)
    {
        perror("link");
        exit(1);
    }
    return 0;
}

symlink函数,创建软链接

点击查看代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if(argc < 3)
    {
        printf("a.out oldpath newpath\n");
        exit(1);
    }

    int ret = symlink(argv[1], argv[2]);
    if(ret == -1)
    {
        perror("symlink");
        exit(1);
    }

    return 0;
}

unlink函数:

实现创建临时文件并删除改临时文件

image

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int fd = open("tempfile", O_CREAT | O_RDWR, 0755);
    if(fd == -1)
    {
        perror("open");
        exit(1);
    }
    //删除临时文件
    int ret = unlink("tempfile");
    if(ret == -1)
    {
        perror("unlink");
        exit(1);
    }

    char buf[512];
    //write file
    write(fd, "hello,world\n",12 );
    
    //重置文件指针,这样才能进行读文件,
    //不然文件指针在文件末尾,当然就读不了哈
    lseek(fd, 0, SEEK_SET);
    //read file
    int len = read(fd, buf, sizeof(buf));

    //将读出的内容写到公屏上
    write(STDOUT_FILENO, buf, len);

    close(fd);

    return 0;
}

目录操作

image

chdir,getcwd函数

点击查看代码
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("a.out dir\n");
        exit(1);
    }

    int ret = chdir(argv[1]);
    if(ret == -1)
    {
        perror("chdir");
        exit(1);
    }

    int fd = open("chdir.txt", O_CREAT | O_RDWR, 0777);
    if(fd == -1)
    {
        perror("open");
        exit(1);
    }
    close(fd);

    char buf[128];
    getcwd(buf, sizeof(buf));
    printf("current dir: %s\n", buf);

    return 0;
}

opendir,readdir

image
image

读取目录下的文件个数

点击查看代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>

int get_file_count(char* root)
{
    DIR* dir;
    struct dirent* ptr = NULL;
    int total = 0;
    char path[1024];

    dir = opendir(root);
    if(dir == NULL)
    {
        perror("opendir");
        exit(1);
    }

    while((ptr = readdir(dir)) != NULL)
    {
        if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
        {
            continue;
        }
        if(ptr->d_type == DT_DIR)
        {
            sprintf(path, "%s/%s", root, ptr->d_name);
            total += get_file_count(path);
        }
        if(ptr->d_type == DT_REG)
        {
            total ++;
        }
    }
    closedir(dir);
    return total;
}

int main(int argc, char* argv[])
{
    if(argc < 2) {
        printf("a.out path\n");
        exit(1);
    }

    int total = get_file_count(argv[1]);
    printf("%s has %d files!\n", argv[1], total);

    return 0;
}

点击查看代码
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int getFileNum(char* root)
{
    // 打开目录
    DIR* dir = opendir(root);
    if(dir == NULL)
    {
        perror("opendir");
        exit(0);
    }

    // 读目录
    int total = 0;
    char path[1024] = {0};
    struct dirent* ptr = NULL;
    while((ptr = readdir(dir)) != NULL)
    {
        // 跳过 . 和 ..
        if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
        {
            continue;
        }
        // 判断是不是文件
        if(ptr->d_type == DT_REG)
        {
            total ++;
        }
        // 如果是目录
        if(ptr->d_type == DT_DIR)
        {
            // 递归读目录
            sprintf(path, "%s/%s", root, ptr->d_name);
            total += getFileNum(path);
        }
    }
    closedir(dir);
    return total;
}

int main(int argc, char* argv[])
{
    // 读目录, 统计文件个数
    int total = getFileNum(argv[1]);
    // 打印
    printf("%s has file number: %d\n", argv[1], total);
    return 0;
}

posted @ 2022-10-26 20:18  mnst  阅读(73)  评论(0)    收藏  举报