• Linux系统编程——基于文件描述符的文件操作(1)


    概要:

    • 打开、创建和关闭文件
    • 读写文件
    • 文件定位
    • 获取文件信息

    打开、创建和关闭文件

    函数原型:
    #include <sys/types.h> //头文件
    #include <sys/stat.h>
    #include <fcntl.h>
    int open(const char *pathname, int flags); //文件名 打开方式
    int open(const char *pathname, int flags, mode_t mode);//文件名 打开方式 权限

    flags和mode都是一组掩码的合成值,flags表示打开或创建的方式,mode表示文件的访问权限。

    flags 的选项:

    • O_CREAT参数:
    #include <func.h>
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDONLY|O_CREAT);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	return 0;
    }
    

    open()函数出错时返回-1,创建成功时返回未使用的最小文件描述符

    0 标准输入符

    1 标准输出符

    2 标准错误输出符

    故该代码中open()返回值为3

    • O_CREAT加自定义权限:

    当输入的文件名不存在时,自动创建文件,但该文件权限是有问题的,所以在open()函数后加上自定义权限参数

    #include <func.h>
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDONLY|O_CREAT,0600);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	return 0;
    }
    

    若文件已存在则跳出,否则创建文件:

    #include <func.h>
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDONLY|O_CREAT|O_EXCL,0600);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	return 0;
    }
    

    TRUNK参数:若文件已存在截断内容为0

    #include <func.h>
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDONLY|O_TRUNC,0600);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	return 0;
    }
    

    close用于文件的关闭:

    int close(int fd);//fd表示文件描述词,是先前由open或creat创建文件时的返回值。

    文件使用完毕后,应该调用close关闭它,一旦调用close,则该进程对文件所加的锁全都被释放,并且使文件的打开引用计数减1,只有文件的打开引用计数变为0以后,文件才会被真正的关闭。


    读写文件

    函数原型:

    #include <unistd.h>

    ssize_t read(int fd, void *buf, size_t count);//文件描述词 缓冲区 长度

    ssize_t write(int fd, const void *buf, size_t count);

    对于read和write函数,出错返回-1,读取完了之后,返回0, 其他情况返回读写的个数

    read.c

    #include <func.h>
    int main(int argc, char* argv[])
    {
        ARGS_CHECK(argc, 2);
        int fd;
        fd = open(argv[1], O_RDONLY);
        ERROR_CHECK(fd, -1, "open");
        printf("fd = %d
    ", fd);
        int ret;
        ret = read(fd, buf, sizeof(buf));
        ERROR_CHECK(ret, -1, "read");
        printf("buf = %s
    ", buf);
        return 0;
    }
    

    write.c

    #include <func.h>
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDWR);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd = %d
    ",fd);
    	int arr[5]={1,2,3,4,5};
    	int ret;
    	ret=write(fd,arr,sizeof(arr));
    	ERROR_CHECK(fd,-1,"write");
    	lseek(fd,0,SEEK_SET);   //从文件头开始计算
    	memset(arr,0,sizeof(arr));
    	ret=read(fd,arr,sizeof(arr));
    	ERROR_CHECK(fd,-1,"read");
    	printf("ret = %d,arr[0] = %d,arr[3] = %d
    ",ret,arr[0],arr[3]);
    	return 0;
    }
    
    

    文件定位

    函数lseek将文件指针设定到相对于whence,偏移值为offset的位置

    #include <sys/types.h>
    #include <unistd.h>
    off_t lseek(int fd, off_t offset, int whence);//fd文件描述词

    whence 可以是下面三个常量的一个
    SEEK_SET 从文件头开始计算
    SEEK_CUR 从当前指针开始计算
    SEEK_END 从文件尾开始计算

    • 文件空洞——通常用于多进程间通信的时候的共享内存
    #include <func.h>
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDWR);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	int ret;
    	ret=lseek(fd,1024,SEEK_SET);
    	printf("lseek ret=%d
    ",ret);
    	char c='H';
    	write(fd,&c,sizeof(c));
    	close(fd);
    	return 0;
    }
    

    • 改变文件大小
    #include <func.h>
    
    int main(int argc,char* argv[])
    {
    	ARGS_CHECK(argc,2);
    	int fd;
    	fd=open(argv[1],O_RDWR);
    	ERROR_CHECK(fd,-1,"open");
    	printf("fd=%d
    ",fd);
    	int ret;
    	ret=ftruncate(fd,1024);
    	ERROR_CHECK(ret,-1,"ftruncate");
    	close(fd);
    	return 0;
    }
    
    获取文件信息

    fstat和stat函数获取文件信息,调用完毕后,文件信息被填充到结构体struct stat变量中,函数原型为:

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <unistd.h>

    int stat(const char *file_name, struct stat *buf); //文件名 stat结构体指针

    int fstat(int fd, struct stat *buf); //文件描述词 stat结构体指针

    stat结构体:

    struct stat {
    dev_t st_dev; /* 如果是设备,返回设备表述符,否则为0 */
    ino_t st_ino; /* i节点号 */
    mode_t st_mode; /* 文件类型  无符号短整型 */
    nlink_t st_nlink; /* 链接数 */
    uid_t st_uid; /* 属主ID */
    gid_t st_gid; /* 组ID */
    dev_t st_rdev; /* 设备类型 */
    off_t st_size; /* 文件大小,字节表示 */
    blksize_t st_blksize; /* 块大小 */
    blkcnt_t st_blocks; /* 块数 */
    time_t st_atime; /* 最后访问时间 */
    time_t st_mtime; /* 最后修改时间 */
    time_t st_ctime; /* 最后权限修改时间 */
    };
    

    EXAMPLE:获得文件的大小

    • 用stat实现
        #include<sys/stat.h> 
        #include<unistd.h> 
        int main() 
        {
            struct stat buf; 
            stat (“/etc/passwd”,&buf);
            printf(“/etc/passwd file size = %d 
    ”,buf.st_size);//st_size可以得到文件大小
        }
    
    • 用fstat实现
    int fd = open (“/etc/passwd”,O_RDONLY); //先获得文件描述词 fstat(fd, &buf); 实例:
    #include <func.h>
    int main()
    {
        int fd = open("/home/a.txt", O_RDONLY);
        if(fd == -1)
    	{
            perror("open error");
            exit(-1);
         }
        struct stat buf;
        int iRet = fstat(fd, &buf);
        if(iRet == -1)
        {
        	perror("fstat error");
        	exit(-1);
        }
        printf("the size of file is : %d
    ", buf.st_size);
        return 0;
    }
    
  • 相关阅读:
    CodeForces 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/Mered1th/p/10699085.html
Copyright © 2020-2023  润新知