Linux系统文件编程及文件读、写操作

news2024/11/27 10:46:35

Linux 系统编程Day01

文章目录

  • Linux 系统编程Day01
    • 1.文件编程概述
      • 1.1 文件的打开及创建
        • 1.1.1 参数说明
        • 1.1.2 文件写入操作示例
        • 1.1.3 文件的权限
    • 2.文件操作
      • 2.1 写入文件
      • 2.2 文件读取操作
      • 2.3 文件的光标移动操作
    • 3.文件操作原理简述
      • 3.1文件描述符
        • 3.2 Linux文件操作流程

1.文件编程概述

为什么会用到文件操作?

  • 账单
  • 游戏进度读取
  • 配置文件等

以上操作在实际的应用中都会用得到

由此我们引出了如何实现文件的创建、打开编辑等的自动化执行操作

Windows手动编辑文件(以world为例):

1.打开/创建文档

2.编辑文档

3.保存文档

4.关闭文档

Linux手动同样类似

计算机如何帮我们自动化完成上述操作?

操作系统提供了一系列的API(以Linux系统为例):

open打开

read/write读写

lseek光标定位

close关闭

1.1 文件的打开及创建

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(cost char *pathname, int flags);
int open(cost char *pathname, int flags,mode_t mode);

int creat(const cahr *pathname, ,ode_t mode)

1.1.1 参数说明

  • pathname:要打开的文件名(含路径,缺省为当前路径)

  • flags:O_RDONLY(只读打开)、O_WRONLY(只写打开)、O_RDWR(可读可写打开)

权限选定以后我们打开的文件只能以选定的权限进行操作;边三个常数只能选择一个。

下面是可选的常数:

O_CREAT:若文件不存在则创建它,同时使用时常数的第三个参数mode也需要被说明,用来指示被创建文件的权限。

O_EXCL:在使用时如果同时使用了O_CREAT ,而文件已经存在,则会 报0错。
O_APPEND:每次写时都加到文件的末端。

O_TRUNC:使用该属性时,若文件有内容且权限为只读或只写成功打开,则将文件长度截断为0.

  • Mode一定是在使用了O_CREAT时,用mode记录待创建文件权限。

Creat创建文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;

        char *buf = "you are very preety!";

        fd = creat("./lianxi2",O_RDWR);

        return 0;

}

1.1.2 文件写入操作示例

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{

        int fd;
        fd = open("./20230619",O_RDWR);
        printf("fd =%d",fd);
        return 0;
}

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{

        int fd;
        fd = open("./20230619",O_RDWR);
        if(fd == -1){
                printf("file create faild\n");
                fd = open("./file1",O_RDWR|O_CREAT,06000);
                if(fd > 0){
                        printf("file create succeed!\n");
                        }

        }

        printf("fd =%d\n",fd);
        return 0;
}

1.1.3 文件的权限

  • 可读:r->4
  • 可写:w->2
  • 执行:x->1

0600:可读可写

0:

6:4+2

0:同组用户

0:其他组

用以给文件所有者权限

2.文件操作

Create函数:

int create (const *filename, mode_mode)

flie:要创建的文件名(包含路径、缺省为当前路径)

mode:创建模式 ///可读可写可执行

常见创建模式:、

  • S_IRSUR: 1 可读
  • S_IWUSR:2 可写
  • S_IXUSR: 1 可执行
  • S_IRWXU:7 可读、可写、可执行

2.1 写入文件

write:

#include <unistd.h>
write(int fd,const void *buf, size_t count)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
        int fd;

        char *buf = "you are very pretty~";

        fd = open("./lianxi",O_RDWR);//打开lainxi文件,若不存在就返回负数
		
        if(fd == -1){
                printf("open file faild \n");//不存在就创建文件
                fd=open("./lianxi",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("creat success!\n");
                }

        }

        printf("fd = %d\n",fd);
	//write(fd,buf,sizeof(buf));
	write(fd,buf,strlen(buf));//写入操作
        close(fd);
        return 0;

}

2.2 文件读取操作

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;

        char *buf = "you are very preety!";

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

        if(fd == -1){
                printf("open file faild \n");
                fd=open("./lianxi",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("creat success!\n");
                }

        }
  printf("fd = %d\n",fd);
        //write(fd,buf,strlen(buf));



        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){

                printf("write %d byte to \n",n_write);

        }

        close(fd);//由于文件的光标此时在最后所以,读取到的结果也是0,由此我们用关闭文件重新打开的方式读取文件
        fd =open("./lianxi",O_RDWR);
        char *redBuf;
        redBuf =(char *)malloc( sizeof(char)*n_write + 1 );
        int n_read = read(fd,redBuf,n_write);
        printf("read %d, context:%s\n",n_read,redBuf);
        close(fd);
        return 0;

}

2.3 文件的光标移动操作

在上边的例子中我们遇到了写入数据后进行读取操作时,读取不到文件的问题。我们采取的方式是关闭文件后再重新打开的方式;

由上我们引入了lseek函数

  • off_t lseek(int fd, off_t offset,int whence)
  • fd:文件描述符
  • offset:偏移值
  • whence:固定点的位置
  • seek_SET:指向文件头
  • seek_END:指向文件尾部
  • seek_CUR:指向当前光标位置

改进例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;

        char *buf = "you are very preety!";

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

        if(fd == -1){
                printf("open file faild \n");
                fd=open("./lianxi",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("creat success!\n");
                }

        }
  printf("fd = %d\n",fd);
        //write(fd,buf,strlen(buf));



        int n_write = write(fd,buf,strlen(buf));
        if(n_write != -1){

                printf("write %d byte to \n",n_write);

        }

        //close(fd);//由于文件的光标此时在最后所以,读取到的结果也是0,由此我们用关闭文件重新打开的方式读取文件
        fd =open("./lianxi",O_RDWR);
        char *redBuf;
        redBuf =(char *)malloc( sizeof(char)*n_write + 1 );
    
    	//读取之前重新定位光标
    	lseek(fd,0,SEEK_SET);
        int n_read = read(fd,redBuf,n_write);
        printf("read %d, context:%s\n",n_read,redBuf);
        close(fd);
        return 0;

}

注:关于偏移值,负数向前正数向后。

计算文件大小:这里我们需要知道的是,lseek成功执行后的的返回值是偏移值

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
        int fd;

        char *buf = "you are very preety!";



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

        int file_size = lseek(fd,0,SEEK_END);
        printf("file's size is :%d\n",file_size);
        close(fd);


        return 0;
}

3.文件操作原理简述

3.1文件描述符

  • 对于内核而言,所有打开文件都由文件描述符引用

  • 文件描述符是一个非负整数

当打开一个文件或创建一个新文件时,内核向进程返回一个文件描述符,当读写一个文件时,用open和creat返回的文件描述符标识该文件,将其作为参数传递给read和write.

按照惯例

  • UNIX shell使用文件描述符0与进程的标准输入相结合;
  • 文件描述符1与标准输出相结合;
  • 文件描述符2与标准错误输出相结合。

STDIN_FILRNO、STDOUT_FILENO、STDERR_FILENO这几个宏代替了0、1、2这几个数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    int fd;
    char readBuf[128];
    
    int n_read = read(0,readBuf,5);
    
    int n_write = write(1,readBuf,strlen(readBuf));
    return 0;
}

文件描述符这个数字在一个进程之中表示一个特定含义,当我们open一个文件时,操作系统在内存中构建了一些数据结构来表示这个动态文件,然后返回给应用一个数字作为这个文件的带表(文件描述符)这个数字就和我们内存中维护的这个动态文件的这些数据结构绑定上了,以后我们应用程序如果要操作这个动态文件只需要用这个文件描述符区分。

  • 文件描述符只在当前进程有效

  • open函数打开文件打开成功返回一个文件描述符,打开错误返回-1

3.2 Linux文件操作流程

1、在Linux中要操作一个文件,一般是先open打开一个文件,得到文件描述符,然后对文件进行读写操作(或其他操作),最后是close关闭文件即可。
2、强调一点:我们对文件进行操作时,一定要先打开文件,打开成功之后才能操作,如果打开失败,就不用进行后边的操作了,最后读写完成后,一定要关闭文件,否则会造成文件损坏。
3、文件平时是存放在块设备中的文件系统文件中的,我们把这种文件叫静态文件,当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存,并且将静态文件的内容从块设备中读取到内核中特定地址管理存放(叫动态文件)。
4、打开文件以后,以后对这个文件的读写操作,都是针对内存中的这一份动态文件的,而并不是针对静态文件的。当然我们对动态文件进行读写以后,此时内存中动态文件和块设备文件中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的睁态文件。
5、为什么这么设计,不直接对块设备直接操作。
块设备本身读写非常不灵活,是按块读写的,而内存是按字节单位操作的,而且可以随机操作,很灵活。
在这里插入图片描述

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

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

相关文章

【数据结构】二叉树的前中后序遍历(C语言)

文章目录 什么是二叉树树相关的概念树的表示形式特殊的二叉树如何创造出一棵二叉树二叉树的遍历先序遍历(前序遍历)中序遍历后序遍历 总结 什么是二叉树 [二叉树] 顾名思义就是有两个分支节点的树&#xff0c;不仅如此&#xff0c;除了叶子外的所有节点都具有两个分支节点&…

单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真

单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真 下面介绍单个电源模块给多个负载使用,并且电源后还经过了磁珠-二级电源直流压降仿真,常见于二级压降仿真,以下图为例

备战秋招 | 笔试强训5

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、在上下文和头文件均正常情况下&#xff0c;以下程序的输出结果是&#xff08;&#xff09; int x 1; do {printf("%2d\n",x); }while(x--); A. 1 B. 无任何输出 C. 2 D. 陷入死循环 …

三种智能算法优化PID参数软件,MATLABAPP开发

今天的主题是&#xff1a;三种智能算法优化常见传递函数的PID参数&#xff0c;采用MATLAB APP Designer 开发。提供代码源程序&#xff0c;可以自行修改源代码&#xff08;不是封装软件&#xff09; 这个软件基本涵盖了所有的传递函数类型&#xff0c;传递函数的参数简单易改。…

【Java反射机制详解】—— 每天一点小知识

&#x1f4a7; J a v a 反射机制详解 \color{#FF1493}{Java反射机制详解} Java反射机制详解&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算法》专栏的文章…

pytest 参数化进阶

目录 前言&#xff1a; 语法 参数化误区 实践 简要回顾 前言&#xff1a; pytest是一个功能强大的Python测试框架&#xff0c;它提供了参数化功能&#xff0c;可以帮助简化测试用例的编写和管理。 语法 本文就赶紧聊一聊 pytest 的参数化是怎么玩的。 pytest.mark.par…

week27

这周是磨难的一周不知道NT装了多少次系统&#xff0c;删除了多少数据好消息是把BIOS和ubuntu安装地很熟练了&#xff0c;而且经过爱上了心仪的Ubuntu23.04&#xff0c;就是她了坏消息是一个学期做的笔记全都没了&#xff0c;以后不好回忆了&#xff0c;好消息是不用考试了&…

总结929

今日做了一篇阅读题&#xff0c;差点全军覆没&#xff0c;通过这篇阅读&#xff0c;主要说明了两大问题&#xff0c;一个是单词&#xff0c;背的还不够牢固&#xff0c;其二&#xff0c;语法功底还不够扎实。但说实话&#xff0c;在语法方面&#xff0c;还是下了一番功夫&#…

linux 内网批量快速传输大文件 nc

使用nc工具 传输内网宽带拉满先运行接收端 开始监听使用 ansible 拷贝脚本到其它接收端服务器批量运行接收端脚本查看nc是否运行运行发送端运行发送端脚本开始传输文件 传输内网宽带拉满 先运行接收端 开始监听 接收端脚本 re.sh #!/bin/bash #Revision: 1.0 #Author:…

动态规划(一) —— 从背包系列问题看DP

前言 动态规划可以算是算法初学者的噩梦哈哈&#xff0c;这段时间荔枝在持续学习Java后端的同时也没有忘记刷题嘿嘿嘿&#xff0c;总算把代码随想录上给出的有关动态规划的题目刷完了。接下来的几篇文章荔枝将会对于刷过的动态规划问题做出总结并给出相应的个人体会和理解。在本…

compose之沉浸式(侵入式)状态栏(隐藏状态栏)

沉浸式(侵入式)状态栏 效果图&#xff1a; 1、代码加入&#xff1a;WindowCompat.setDecorFitsSystemWindows(window, false) ComposeTestTheme {WindowCompat.setDecorFitsSystemWindows(window, false)Greeting("Android")} 2、沉浸式(侵入式)主题&#xff1a; …

消息推送(websocket)集群化解决方案

目录 需求分析解决方案实现步骤架构图配置websocket请求地址配置websocket连接前置和连接关闭监听配置websocket处理程序配置redis交换机配置redis订阅监听配置redis发布监听需求分析 及时信息传递:消息推送功能能够确保网站向用户发送及时的重要信息,包括新闻更新、促销活动…

消息队列——rabbitmq的不同工作模式

目录 Work queues 工作队列模式 Pub/Sub 订阅模式 Routing路由模式 Topics通配符模式 工作模式总结 Work queues 工作队列模式 C1和C2属于竞争关系&#xff0c;一个消息只有一个消费者可以取到。 代码部分只需要用两个消费者进程监听同一个队里即可。 两个消费者呈现竞争关…

Redis进阶底层原理-主从复制

Redis的主从节点都会记录对方的信息&#xff0c;核心还包括ReplicationID 和 offset &#xff0c; ReplicationID &#xff1a; 主从节点实例的ID &#xff0c;redis内部就是通过这个id去识别主从节点。offset&#xff1a;数据同步偏移量&#xff0c;也就是从节点每次从主节点同…

3.6 Bootstrap 导航元素

文章目录 Bootstrap 导航元素表格导航或标签胶囊式的导航菜单基本的胶囊式导航菜单垂直的胶囊式导航菜单 两端对齐的导航禁用链接下拉菜单带有下拉菜单的标签带有下拉菜单的胶囊标签页与胶囊式标签页 Bootstrap 导航元素 本文将讲解 Bootstrap 提供的用于定义导航元素的一些选项…

使用thrift编写C++服务器、客户端

在上一节《Linux 下编译 thrift》中&#xff0c;我们成功编译出了thrift的库文件&#xff0c;本节我们来编写thrift的C服务器&#xff0c;客户端。 官网 https://thrift.apache.org/tutorial/cpp.html 有thrift的C例子。在我们之前下载下来的thrift 源码根目录的tutorial/cpp目…

MySQL高级管理

目录 一、指定主键的一种方式 1.1高级操作 1.2数据表高级操作,克隆表 1.2.1 克隆表名 1.2.2备份表内容 1.3复制表 1.4删除指令 方法一&#xff1a; 方法二&#xff1a; 删除速度 二、创建临时表 三、MySQL中6种常见的约束 3.1创建主表 3.2创建从表 3.3为主表test01添加…

[Docker异常篇]解决Linux[文件异常]导致开机Docker服务无法启动

文章目录 一&#xff1a;场景复现二&#xff1a;解决思路2.1&#xff1a; 对比其他节点docker配置2.2&#xff1a;试着修改为正常节点配置2.2&#xff1a;根据上面异常显示&#xff0c;不一定是配置不对&#xff0c;可能是文件系统有损坏 三&#xff1a;解决 -> 执行命令 mo…

【机器学习算法】奇异值分解(SVD)

文章目录 奇异值分解(SVD)1.理论部分1.1特征分解(ED)1.2 奇异值分解(SVD)求解U和V求解Σ 2.应用部分2.1图像压缩2.2图像数据集成分分析2.3 数据降维(PCA的一种解法) Reference 奇异值分解(SVD) 奇异值分解(Singular Value Decomposition) 是矩阵低秩分解的一种方法&#xff0c;…

太猛了!Web安全漏洞批量扫描框架

关注【Hack分享吧】公众号&#xff0c;回复关键字【230528】获取下载链接 工具介绍 一个应用于web安全领域的漏洞批量扫描框架&#xff0c;可被应用于但不限于如下场景&#xff1a; 0Day/1Day全网概念验证(在没有测试环境(各种商业、闭源软件)或懒得搭建测试环境的情况下&…