一、文件编程概述
之前在windows中对文件的操作是:打开文档——>编辑文档——>保存文档——>关闭文档
我们的Linux文件编程主要是利用代码对文件进行操作:文件创建、打开、编辑等自动化执行等
在Linux我们要使用编程调用api函数的方式进行文档的编辑:
打开:open 读写:write/read 光标定位:lseek 关闭:close
一般使用最多的是:
O_APPEND 每次写时都添加到文件的尾端
O_TRUNC 把之前里面的内容去掉,写入新的
O_CREAT 如果文件不存在,就创建它(配合上面的两个使用)
文件描述符:
1、对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或者创建一个新文件时,内核向进程返回一个文件描述符。当读写一个文件时,用open和creat返回的文件描述符标识该文件,将其作为参数传递给read和write。按照惯例,NIX shell使用文件描述符0与进程的标准输入相结合,文件描述符1与标准输出相结合,文件描述符2与标准错误输出相结合。STDINLFILEN0、STDOUTFILENO、STDERR FILENO这几个宏代替了0、1、2这几个魔数。
2、文件描述符,这个数字在一个进程中表示一个特定含义,当我们open一个文件时,操作系统在内存中构建了一些数据结构来表示这个动态文件,然后返回给应用程序一个数字作为文件描述符,这个数字就和我们内存中维护的这个动态文件的这些数据结构绑定上了,以后我们应用程序如果要操作这个动态文件,只需要用这个文件描述符区分。
3、文件描述符的作用域就是当前进程,出了这个进程文件描述符就没有意义了 open函数打开文件,打开成功返回一个文件描述符,打开失败,返回-1。
文件的动静态文件:
1、在Linux中要操作一个文件,一般是先open打开一个文件,得到文件描述符,然后对文件进行读写操作(或其他操作),最后是close关闭文件即可。
2、强调一点:我们对文件进行操作时,一定要先打开文件,打开成功之后才能操作,如果打开失败,就不用进行后边的操作了,最后读写完成后,一定要关闭文件,否则会造成文件损坏。
3、文件平时是存放在块设备中的文件系统文件中的,我们把这种文件叫静态文件,当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存,并且将静态文件的内容从块设备中读取到内核中特定地址管理存放(叫动态文件)。 4、打开文件以后,以后对这个文件的读写操作,都是针对内存中的这一份动态文件的,而并不是针对静态文件的。当然我们对动态文件进行读写以后。此时内存中动态文件和块设备文件中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静 态文件。
5、为什么这么设计,不直接对块设备直接操作 块设备本身读写非常不灵活,是按块读写的,而内存是按字节单位操作的,而且可以随机操作,很灵活
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 可读可写打开
当没有这个文件的时候,返回值是-1,
文件写入:
写入:wirte
头文件:include <string.h>
最后要关闭:close
文件读取操作:
读取:read
lseek : 将文件读写指针相对whence移动offset个字节
SEEK_SET 指向文件头
SEEK_CUR 指向文件尾
SEEK_END 指向当前位置
光标定位:
同文件的多个文件一起读取
cp命令和使用:
具体参考下面的博客:
这个不是爆错,是正常的,只是我们人类觉得它是乱码,错误应该是在编译里面就爆错了:
文件记录结构体:文件记录结构体数组:open ----fopen read-----fread write ------ fwrite 的区别
就是一个是c语言的标准库,一个是linux里面的库
文件共享
文件描述符:
open和openat的区分:open是只可以打开当前工作目录;openat是可以打开工作在不同的目录中
原子操作:
在计算机科学中,原子操作是指不可分割的操作,要么完全执行,要么完全不执行,不会被中断或分割为更小的部分。原子操作通常用于多线程并发编程中,以确保对共享资源的访问是线程安全的,避免竞态条件和数据不一致性问题。
在多线程环境中,如果多个线程同时访问共享资源,并且对该资源的操作不是原子操作,可能导致以下问题:
- 竞态条件(Race Condition): 多个线程对同一共享资源进行读写操作,由于操作的不确定性,可能导致意外的结果。
- 数据不一致性(Data Inconsistency): 多个线程同时对同一数据进行读写操作,可能导致数据不一致的情况。
原子操作的特点包括:
- 不可分割性(Indivisibility): 原子操作要么全部执行成功,要么全部不执行,不会被中断或分割。
- 互斥性(Mutual Exclusion): 在原子操作执行期间,其他线程无法同时访问相同的资源,确保了操作的独占性。
- 同步性(Synchronization): 原子操作可以用来同步多个线程的执行顺序,确保线程之间的协调和顺序性。
在编程中,原子操作通常由硬件提供支持,也可以通过操作系统提供的原子指令或锁机制来实现。常见的原子操作包括原子加减、原子赋值、原子比较交换等。
在多线程编程中,正确使用原子操作可以帮助避免并发性问题,确保程序的正确性和稳定性。