Linux系统编程:文件编程

news2025/1/9 12:31:17

一 常用API

打开、创建、关闭文件,读写文件,利用man指令查询相关说明

open & create

man 2 open

man 2 create

NAME
       open, creat - open and possibly create a file or device

SYNOPSIS
       #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);

       int creat(const char *pathname, mode_t mode);

close 

man 2 close

NAME
       close - close a file descriptor

SYNOPSIS
       #include <unistd.h>

       int close(int fd);

write

man 2 write

NAME
       write - write to a file descriptor

SYNOPSIS
       #include <unistd.h>

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

DESCRIPTION
       write()  writes  up  to  count bytes from the buffer pointed buf to the
       file referred to by the file descriptor fd.

man strlen 

NAME
       strlen - calculate the length of a string

SYNOPSIS
       #include <string.h>

       size_t strlen(const char *s);

read

man 2 read

NAME
       read - read from a file descriptor

SYNOPSIS
       #include <unistd.h>

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

DESCRIPTION
       read()  attempts to read up to count bytes from file descriptor fd into
       the buffer starting at buf.

       If count is zero, read() returns zero and has  no  other  results.   If
       count is greater than SSIZE_MAX, the result is unspecified.

man malloc

NAME
       malloc, free, calloc, realloc - Allocate and free dynamic memory

SYNOPSIS
       #include <stdlib.h>

       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);

 综合应用:创建、打开、写、读 最后关闭文件

写一个demo.c 

先打开文件,文件不存在open返回-1,

然后创建这个文件 利用 fd = open("./file1",O_RDWR|O_CREAT,0600);

因为 6 = 4 + 2 ,4和2表示权限可读可写

然后write进去字符串

此时直接read,什么也读不到,因为光标位于字符串尾部,从光标往后读取自然为空

简单粗暴的办法就是关闭文件再打开,光标自动从头部开始

然后就可以读取到写入的内容了,

最后关闭文件。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	int fd;
	char *buf = "Zhong Guo Wan Sui!";

	fd = open("./file1",O_RDWR);

	if(fd>0)
	{
		printf("open file success,fd = %d\n",fd);
	}
	else if(fd == -1)
	{
		printf("open file fail,fd = %d\n",fd);

		fd = open("./file1",O_RDWR|O_CREAT,0600);
		if(fd>0)
		{
			printf("create file success,fd = %d\n",fd);
		}
	}

	int n_write = write(fd,buf,strlen(buf));

	if(n_write != -1)
		printf("write file success,n_write = %d\n",n_write);

	close(fd);
	fd = open("./file1",O_RDWR);

	char *read_buf;
	read_buf = (char *)malloc(sizeof(char) * n_write + 1);

	int n_read = read(fd,read_buf,sizeof(char) * n_write + 1);

	printf("read %d,context:%s\n",n_read,read_buf);
	close(fd);

	return 0;
}

 运行一下

CLC@Embed_Learn:~/part1$ gcc demo.c
CLC@Embed_Learn:~/part1$ ls
a.out  demo.c
CLC@Embed_Learn:~/part1$ ./a.out
open file fail,fd = -1
create file success,fd = 3
write file success,n_write = 18
read 18,context:Zhong Guo Wan Sui!

光标 lseek

上面这个demo处理光标的方法太low,让我们正经处理一下光标

man 2 lseek

NAME
       lseek - reposition read/write file offset

SYNOPSIS
       #include <sys/types.h>
       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);

DESCRIPTION
       The lseek() function repositions the offset of the open file associated
       with the file descriptor fd to the argument  offset  according  to  the
       directive whence as follows:

       SEEK_SET
              The offset is set to offset bytes.

       SEEK_CUR
              The offset is set to its current location plus offset bytes.

       SEEK_END
              The offset is set to the size of the file plus offset bytes.

 修改代码,将关闭重新打开换为直接将光标移动到头部。

//	close(fd);
//	fd = open("./file1",O_RDWR);

	lseek(fd,0,SEEK_SET);

拓展:利用lseek巧算文件大小

	lseek(fd,0,SEEK_SET);
	int fileSize = lseek(fd,0,SEEK_END);
	printf("fileSize = %d\n",fileSize);

二 文件编程应用

1.实现CP操作

测试:参数传入main函数,运行指令拆分为二维数组

#include <stdio.h>


int main(int argc,char **argv)
{
	printf("total params : %d\n",argc);
	printf("No.1 params : %s\n",argv[0]);
	printf("No.2 params : %s\n",argv[1]);
	printf("No.3 params : %s\n",argv[2]);

	return 0;
}
CLC@Embed_Learn:~/part1$ ./a.out One Two
total params : 3
No.1 params : ./a.out
No.2 params : One
No.3 params : Two

实现:CP指令效果

传入两个目标文件,打开目标1,计算文件大小,读目标1文本,打开目标2,将文本写入目标2。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char **argv)
{
	int fd,fd1;
	fd = open(argv[1],O_RDWR);

	int fileSize = lseek(fd,0,SEEK_END);
	lseek(fd,0,SEEK_SET);
	
	char *read_buf = (char *)malloc(fileSize);
	read(fd,read_buf,fileSize);

	fd1 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
	write(fd1,read_buf,fileSize);

	close(fd);
	close(fd1);

	return 0;
}

编译运行

CLC@Embed_Learn:~/part1$ gcc demo_cp.c -o mycp
CLC@Embed_Learn:~/part1$ ls
a.out  demo.c  demo_cp.c  demo_cp.c~  file1  mycp  test.c
CLC@Embed_Learn:~/part1$ ./mycp file1 file2
CLC@Embed_Learn:~/part1$ ls
a.out  demo.c  demo_cp.c  demo_cp.c~  file1  file2  mycp  test.c

2.实现修改程序配置文件功能

将BBB由3改为8。

步骤:读出文本字符串,找到对应参数的位置,修改读出字符串的内容,将内容覆写进文件 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char **argv)
{
	int fd;
	fd = open(argv[1],O_RDWR);

	int fileSize = lseek(fd,0,SEEK_END);
	lseek(fd,0,SEEK_SET);
	
	char *read_buf = (char *)malloc(fileSize);
	read(fd,read_buf,fileSize);

	char *p = strstr(read_buf,argv[2]);
	if(p == NULL)
	{
		printf("%s not found\n",argv[2]);
		exit(-1);
	}

	p += strlen(argv[2]) + 1;
	*p = '8';

	lseek(fd,0,SEEK_SET);
	write(fd,read_buf,fileSize);

	close(fd);

	return 0;
}

运行

CLC@Embed_Learn:~/part1$ gcc  demo_turn.c -o TurnData
CLC@Embed_Learn:~/part1$ ./TurnData DataFile BBB

注意:

不要陷入buf只能是字符串的误区,buf是指针,写整型、数组、结构体等等都可以正常读写,但是vi查看可能是乱码,人类看不懂,但是不影响读写使用。

例如:读写结构体

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

struct Test
{
	int a;
	char c;

};

int main()
{
	int fd;
	
	struct Test data[2] = {{100,'a'},{101,'b'}};
	struct Test data2[2];

	fd = open("./file1",O_RDWR);

	int n_write = write(fd,&data,sizeof(struct Test)*2);

	lseek(fd,0,SEEK_SET);

	int n_read = read(fd, &data2, sizeof(struct Test)*2);
	
	printf("read %d,%c \n",data2[0].a,data2[0].c);
	printf("read %d,%c \n",data2[1].a,data2[1].c);
	close(fd);

	return 0;
}

三 标准C库

总结open与fopen的区别 - NickyYe - 博客园 (cnblogs.com)

fopen fwrite fclose fread fseek ... ... 

NAME
       fopen, fdopen, freopen - stream open functions

SYNOPSIS
       #include <stdio.h>

       FILE *fopen(const char *path, const char *mode);

       FILE *fdopen(int fd, const char *mode);

       FILE *freopen(const char *path, const char *mode, FILE *stream);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
//=========================================================================

NAME
       fread, fwrite - binary stream input/output

SYNOPSIS
       #include <stdio.h>

       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

       size_t fwrite(const void *ptr, size_t size, size_t nmemb,
                     FILE *stream);
//=========================================================================
NAME
       fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream

SYNOPSIS
       #include <stdio.h>

       int fseek(FILE *stream, long offset, int whence);

       long ftell(FILE *stream);

       void rewind(FILE *stream);

       int fgetpos(FILE *stream, fpos_t *pos);
       int fsetpos(FILE *stream, fpos_t *pos);

"r"           文件只读
"w"           创建文字文件只写
"a"           增补, 如果文件不存在则创建一个
"r+"          打开一个文字文件读/写
"w+"          创建一个文字文件读/写
"a+"          打开或创建一个文件增补
"b"           二进制文件(可以和上面每一项合用)
"t"           文这文件(默认项)

例1: 

#include <stdio.h>
int main() {
    FILE *fp;
    int ret;
    /* 打开文件 */
    fp = fopen("123.txt", "r");
    if (fp == NULL)
        puts("打开失败!");
    else
        puts("打开成功!");
    /* 关闭文件 */
    ret = fclose(fp);
    if (ret == 0)
        puts("关闭成功!");
    else
        puts("关闭失败!");
    return 0;
}

例2: 

#include <stdio.h>
#include <string.h>

int main()
{
	//FILE *fopen(const char *path, const char *mode);

	FILE *fp;
	char *str = "Hello World";
	char readBuf[128] = {0};

	fp = fopen("./file1.txt","w+");

	//size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
	//ptr  buf
	//size  sizeof char   
	// geshu 
	// which file
	int nwrite = fwrite(str,sizeof(char),strlen(str),fp);
//	fwrite(str,sizeof(char)*strlen(str),1,fp);
	fseek(fp,0,SEEK_SET);
//	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
	int nread = fread(readBuf,sizeof(char),strlen(str),fp);
	
	printf("read data: %s\n",readBuf);
    printf("read=%d,write = %d\n",nread,nwrite);

    fclose(fp);

	return 0;
}

fputc fgetc feof ... ...li

NAME
       fputc,  fputs,  putc,  putchar,  puts  -  output  of characters and
       strings

SYNOPSIS
       #include <stdio.h>

       int fputc(int c, FILE *stream);

       int fputs(const char *s, FILE *stream);

       int putc(int c, FILE *stream);

       int putchar(int c);

       int puts(const char *s);
//=========================================================================
NAME
       clearerr, feof, ferror, fileno - check and reset stream status

SYNOPSIS
       #include <stdio.h>

       void clearerr(FILE *stream);

       int feof(FILE *stream);

       int ferror(FILE *stream);

       int fileno(FILE *stream);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       fileno(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

例1:

#include <stdio.h>
#include <string.h>

int main()
{
	FILE *fp;
	int i;
	char *str = "chenlichen hen shuai o!";
	int len = strlen(str);

	fp = fopen("./test.txt","w+");
	for(i=0;i<len;i++){

		fputc(*str,fp);
		str++;
	}
	fclose(fp);
	return 0;
}

例2:

#include <stdio.h>
#include <string.h>

int main()
{
	FILE *fp;
	int i;
	char c;

	fp = fopen("./test.txt","r");

	while(!feof(fp)){// nonezero if reach end of file
		
		c = fgetc(fp);
		printf("%c",c);
	}
	fclose(fp);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/999638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海外专线网络费用

在企业海外扩展和开展业务时&#xff0c;建立可靠的网络连接是至关重要的。而海外SD-WAN专线网络作为一种优化广域网连接的解决方案&#xff0c;提供更好的连接质量和性能。本文将介绍海外SD-WAN专线网络的费用组成&#xff0c;帮助企业更好地了解和规划网络投资。 1. 专线租用…

python趣味编程-恐龙克隆游戏

Python 中使用 Turtle 的恐龙克隆游戏免费源代码 使用 Turtle 的恐龙克隆游戏是一个用Python编程语言编码的桌面游戏应用程序。该项目包含在 Chrome 浏览器中克隆实际恐龙游戏的多种功能。该项目可以使正在修读 IT 相关课程的学生受益。这个应用程序非常有趣,可以帮助您学习创…

博客之QQ登录功能(一)

流程图 上图spring social 封装了1-8步需要的工作 1、新建包和书写配置文件 public class QQProperties {//App唯一标 识private String appId "100550231";private String appSecret "69b6ab57b22f3c2fe6a6149274e3295e";//QQ供应商private String…

1688API接入说明(1688商品详情+关键词搜索商品列表)商品详情数据,商品sku数据

1688商家订单详情API接口可以帮助你开拓新的业务机会。通过API&#xff0c;你可以将自己的业务系统与1688平台连接起来&#xff0c;利用1688平台丰富的资源和渠道优势&#xff0c;扩大你的业务范围。此外&#xff0c;1688商家订单详情API接口还支持多种语言和格式&#xff0c;如…

Docker入门,Docker是什么?有什么用?该怎么用?

目录 1. 项目部署时的复杂性&#xff1f; 2. Docker是如何解决依赖兼容问题的&#xff1f; 3. 众多Linux操作系统发行版的区别 4. Docker 是如何实现跨系统运行的&#xff1f; 5. Docker与虚拟机的差别 6. 镜像(Image)与容器(Container) 7. DockerHub 8. Docker 架构 …

Python 操作 CSV

使用过 CSV 文件都知道&#xff1a;如果我们的电脑中装了 WPS 或 Microsoft Office 的话&#xff0c;.csv 文件默认是被 Excel 打开的&#xff0c;那么什么是 CSV 文件&#xff1f;CSV 文件与 Excel 文件有什么区别&#xff1f;如何通过 Python 来操作 CSV 文件呢&#xff1f;带…

创建开机自启的脚本

在启动许多ros节点时有多种方式&#xff0c;我推荐使用launch来启动所有的节点&#xff0c;这也是一种规范的方式。以后会慢慢向这个方向靠。 除此之外还可以通过创建的脚本来启动&#xff1a; 脚本位置不限&#xff0c;只需要&#xff1a; sudo gedit xxx.sh在里面添加相应的…

网站框架识别方法

cms一般有dedecms(织梦&#xff09;&#xff0c;dzcms&#xff0c;phpweb&#xff0c;phpwind&#xff0c;phpcms&#xff0c;ecshop&#xff0c;dvbbs&#xff0c;siteweaver&#xff0c;aspcms&#xff0c;帝国&#xff0c;zblog&#xff0c;wordpress等。 一般cms都有特定的…

ES6——知识点记录

这里写目录标题 1.字符串支持1.codePointAt——根据字符串码元的位置得到其码点2.includes——判断字符串中是否包含指定的子字符串3.startsWith——判断字符串中是否以指定的字符串开始4.endsWith——判断字符串中是否以指定的字符串结尾5.repeat——将字符串重复指定的次数&a…

AB试验(二)统计基础

AB试验&#xff08;二&#xff09;统计基础 随机变量 均值类指标&#xff1a;如用户的平均使用时⻓、平均购买金额、平均购买频率等 概率类指标&#xff1a;如用户点击的概率(点击率)、转化的概率(转化率)、购买的概率 (购买率)等 经验结论&#xff1a;在数量足够大时&#…

Vibro-meter VM600 200-510-041-021数字量控制板卡

Vibro-meter VM600 200-510-041-021 数字量控制模块通常用于振动监测和机械设备的控制系统中&#xff0c;以执行振动数据采集、分析和控制任务。以下是通常情况下数字量控制模块的一些产品特点&#xff1a; 多通道输入&#xff1a;这些模块通常配备多个输入通道&#xff0c;以接…

浅析数字孪生在科学研究中的作用和优势

在科学研究领域&#xff0c;数字孪生技术正迅速崭露头角&#xff0c;为研究人员提供了前所未有的工具和资源&#xff0c;以更深入、更全面地理解复杂的自然现象和系统。本文带大家探讨数字孪生对科学研究的作用&#xff1a; 1. 精准建模和仿真 数字孪生技术允许科学家创建真实…

【Minecraft】Lucky Block(幸运方块)mod介绍

文章目录 mod介绍支持版本mod作者合成方式幸运值使用方法总结 mod介绍 幸运方块模组虽然只是添加了一个方块&#xff0c;两种武器&#xff0c;一种药水&#xff0c;但拥有超过一百种可能性&#xff01; 简单地打破幸运方块&#xff0c;它将开出意想不到的东西&#xff01; 你可…

云原生安全性:构建可信任的云应用的最佳实践

文章目录 云原生安全性的重要性1. 数据隐私2. 恶意攻击3. 合规性要求4. 业务连续性 构建可信任的云应用的最佳实践1. 安全开发2. 身份验证与授权3. 容器安全性4. 监控与审计5. 持续集成与持续交付&#xff08;CI/CD&#xff09;6. 安全培训和教育 未来趋势&#xff1a;服务网格…

Swagger 使用教程

Swagger 官网&#xff1a; API Documentation & Design Tools for Teams | Swagger 整合swagger 依赖&#xff1a; springfox-swagger2 springfox-swagger-ui <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</a…

气象站:从气候预测到环境监测

在我们的日常生活中&#xff0c;气象站的存在可能并不显眼&#xff0c;但实际上&#xff0c;它对我们的生活产生了重要的影响。气象站是一种用于收集和监测天气数据的设施&#xff0c;通过它&#xff0c;我们可以获得各种关于气候和天气的宝贵信息。那么&#xff0c;气象站可以…

Selenium自动化测试框架常见异常分析及解决方法

01 pycharm中导入selenium报错 现象: pycharm中输入from selenium import webdriver, selenium标红 原因1: pycharm使用的虚拟环境中没有安装selenium, 解决方法: 在pycharm中通过设置或terminal面板重新安装selenium 原因2: 当前项目下有selenium.py,和系统包名冲突导致, …

飞行动力学 - 第20节-横向静稳定性 之 基础点摘要

飞行动力学 - 第20节-横向静稳定性 之 基础点摘要 1. 横向静稳定性2. 横向静稳定准则3. 横向静稳定性的组成4. 参考资料 1. 横向静稳定性 2. 横向静稳定准则 对于横向静稳定性飞机&#xff0c;右滚转扰动会产生正侧滑&#xff0c;飞机产生左滚恢复力矩(负)&#xff0c;即 Δ …

Python之数据库(MYSQL)连接

一&#xff09;数据库SQL语言基础 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database…