• Linux—文件编程


    如何用代码操作文件,实现文件的创建,打开,编辑等自动化执行?
    操作系统提供了一系列的API。
    Linux系统
    打开:open
    读写:write/read
    光标定位:lseek
    关闭:close

    打开/创建文件:

    SYNOPSIS
    //头文件
    #include 
    #include 
    #include 
    
    int open(const char *pathname, int flags);//指针指向文件路径,int 权限
    int open(const char *pathname, int flags, mode_t mode);//
    /*pathname:要打开的文件名(含路径,缺省为当前路径)
    Flags:
    O_RDONLY只读打开  O_WRONLY只写打开  O_RDWR 可读可写打开
    (文件不存在,返回值为-1)
    
    O_CREAT:若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode,用其说明该文件的存取许可权限
    O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错:打开文件失败或者返回值为-1。
    O_APPEND:每次写时都加到文件尾端,j如不加O_APPEND则覆盖之前的内容。
    O_TRUNC:属性去打开文件时,如果文件本来是有内容的,而且为只读或只写成功打开,则其长度截短为0,把之前内容全部删除,重新写入.
    
    Mode:一定是在flagse中使用了O_CREAT标准,mode记录待创建的文件的访问权限
    
    */
    int creat(const char *pathname, mode_t mode);
    
    DESCRIPTION//描述
    Given a pathname for a file, open() returns a file descriptor,a small,nonnegative integer for use in subsequent system calls (read(2),write(2),lseek(2),fcntl(2),etc.),The file descriptor returned by a successful call will be the lowestnumbered file descriptor not currently open for the process.
    /*给定一个文件的路径名,open() 返回一个文件描述符,一个小的非负整数,用于后续的系统调用(read(2)、write(2)、lseek(2)、fcntl(2)等),成功调用返回的文件描述符将是当前未为进程打开的最低编号文件描述符。
    */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    例:

    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
    	int fd;
    	
    	fd = open("./file1",O_RDWR);
    	
    	if(fd == -1){
    		printf("open file1 failed\n");
    		fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
    		/*权限:					宏表示
    		可读:r			4		S_IRUSR
    		可写:w			2		S_IWUSR
    		执行:x			1		S_IXUSR
    		可读,写,执行		7		S_IRWXU
    		*/
    		if(fd > 0){
    			printf("create file1 success!\n");
    		}
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    文件的写入:

    #include 
    
    ssize_t write(int fd,const void *buf,size_t count);
    //fd文件描述符,缓冲区指针,大小(count字节)
    
    • 1
    • 2
    • 3
    • 4
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
    	int fd;
    	char *buf = "laowang hao bang!";
    	
    	fd = open("./file1",O_RDWR);//打开文件file1
    	
    	if(fd == -1){
    		printf("open file1 failed\n");
    		fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
    		/*权限:
    		可读:r		4
    		可写:w		2
    		执行:x		1
    		*/
    		if(fd > 0){
    			printf("create file1 success!\n");
    		}
    	}
    	
    	printf("open success:fd = %f\n",fd);
    	
    	write(fd,buf,sizeof(buf));//sizeof分配8个字节给buf
    	write(fd,buf,strlen(buf));//全部显示
    	
    	close(fd);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    文件读取:

    #include 
    
    ssize_t read (int fd,const void *buf,size_t count);
    //fd文件描述符,缓冲区指针,大小(count字节)
    
    • 1
    • 2
    • 3
    • 4

    > 光标重新定位:

    #include
    #include

    off_t lseek (int fd,off_t offset,int whence);
    fd文件描述符,偏移值,位置
    (seek_set,指向文件的头)
    (seek_end,指向文件的尾)
    (seek_cur,指向文件光标当前位置)

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
    	int fd;
    	char *buf = "laowang hao bang!";
    	
    	fd = open("./file1",O_RDWR);//打开文件file1
    	
    	if(fd == -1){
    		printf("open file1 failed\n");
    		fd = open("./file1",O_RDWR|O_CREAT,0600);//0600可读写权限(4+2)
    		/*权限:
    		可读:r		4
    		可写:w		2
    		执行:x		1
    		*/
    		if(fd > 0){
    			printf("create file1 success!\n");
    		}
    	}
    	
    	printf("open success:fd = %f\n",fd);
    	
    	int n_write = write(fd,buf,sizeof(buf));//sizeof分配8个字节给buf
    	int n_write =write(fd,buf,strlen(buf));//全部显示
    	if(n_write != -1){
    		printf("write %d byte to file\n",n_write);
    	}
    	//因为光标问题,需要重新打开文件才能读取。或者把光标重新定位
    	//close(fd);
    	//fd = open("./file1",O_RDWR);//重新打开文件file1
    	
    	char *readBuf;
    	readBuf = (char *)malloc(sizeof(char)*n_write + 1);//char的大小*文件大小+1
    	
    	lseek(fd,0,SEEK_SET);//光标重新定位
    	
    	int n_read = read(fd,readBuf,n_write);
    	
    	printf("read %d ,context:%s\n",n_read,readBuf);
    	close(fd);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    文件描述符 = open(文件,--------)是一个非负整数

    Linux系统中有默认的文件描述符:
    0 标准输入 STDIN_FILENO
    1 标准输出 STDOUT_FILENO
    2 标准错误 STDERR_FILENO

    文件有静态文件和动态文件
    动态文件 = open 静态文件 后在Linux内核产生一个结构体

    fd
    信息节点
    buf(内容)相当于内存

    用close之后存入磁盘静态文件

    练习1:实现Linux cp命令的代码
    参数argc:
    参数0 参数1 参数2
    cp 源文件(src) 目标文件(des)
    argv[0] argv[1] argv[2]

    思路:
    1.打开源文件
    2.读源文件到buf
    3.打开/创建目标文件
    4.将buf写入到目标文件
    5.close两个文件

    编译:gcc 文件 -o mycp
    ./mycp 源文件 目标文件

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc,char **argv)
    {
    	int fdSrc,fdDes;
    	char readBuf[1024] = {0};
    	
    	if(argc != 3){
    		printf("pararm error\n");
    		exit(-1);
    	}
    	
    	fdSrc = open(argv[1],O_RDWR);//打开文件
    	int n_read = read(fdSrc,readBuf,1024);
    	
    	fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
    	int n_write =write(fdDes,readBuf,strlen(readBuf));
    
    	close(fdSrc);
    	close(fdDes);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    练习2:实现配置文件的修改
    man strstr//查询strstr用法

    如:
    读取出来为:
    SPEED = 3
    LENG = 3
    SCORE = 9
    LEVEL = 5
    修改为:
    SPEED = 5
    LENG = 100
    SCORE = 90
    LEVEL = 95

    思路:
    1.找到修改位置的行
    2.在该行中找到需要修改的位置
    3.修改该位置

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc,char **argv)
    {
    	int fdSrc,fdDes;
    	char *readBuf = NULL;
    	
    	if(argc != 2){
    		printf("pararm error\n");
    		exit(-1);
    	}
    	
    	fdSrc = open(argv[1],O_RDWR);//打开文件
    	int size = lseek(fdSrc,0,SEEK_END);
    	lseek(fdSrc,0,SEEK_SET);
    	readBuf = (char *)malloc(sizeof(char)*size + 8);
    	
    	int n_read = read(fdSrc,readBuf,1024);
    	
    	char *p = strstr(readBuf,"LENG=");
    	if(p==NULL){
    		printf("not founf\n");
    		exit(-1);
    	}
    	p = p+strlen("LENG=");
    	*p = "100";
    	
    	lseek(fdSrc,0,SEEK_SET);//移动光标
    	int n_write =write(fdSrc,readBuf,strlen(readBuf));
    
    	close(fdSrc);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    java计算机毕业设计springboot+vue小微企业人才推荐系统
    Vue3-小兔鲜项目
    【C语言】进阶——文件操作
    MySQL字符串函数
    每天五分钟机器学习:支持向量机损失函数和互熵损失函数
    设计模式 -- 代理模式(Proxy Pattern)
    毕设 小区物业管理论文
    10-5 Skywalking基于nginx+jenkins服务的全链路数据收集
    请求转发 [JavaWeb][Servlet]
    Latex 写论文排版方法(vscode)
  • 原文地址:https://blog.csdn.net/weixin_48208102/article/details/132541642