Interfaz de operación de archivos de Linux

Cuando se utiliza el lenguaje para escribir servicios, hay muchos escenarios en los que es necesario manipular los archivos.El kernel de Linux está escrito en lenguaje C. Antes de comprender Linux, debe estar familiarizado con la interfaz de operación de archivos en lenguaje C para facilitar la comparación.

Interfaz de operación de archivos en lenguaje C

Descripción del archivo de lenguaje C

#ifndef _FILE_DEFINED
struct _iobuf {
    char *_ptr; //文件输入的下一个位置
    int _cnt; //当前缓冲区的相对位置
    char *_base; //指基础位置(即是文件的起始位置)
    int _flag; //文件标志
    int _file; //文件描述符id
    int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
    int _bufsiz; //文件缓冲区大小
    char *_tmpfname; //临时文件名
};
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

En una estructura de datos de este tipo existen los datos requeridos por el lenguaje C para las operaciones con archivos. Cuando el lenguaje C opera en archivos, se usa una estructura de datos para identificar de manera única un flujo de archivos.

fopen()

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

El valor devuelto es un puntero a la estructura del flujo de archivos, y se devuelve un puntero NULL cuando falla la apertura .
El archivo debe abrirse antes de operar en el archivo, y la interfaz fopen() se usa para abrir el archivo.

Parámetros:
ruta: ruta del archivo, que puede ser una ruta relativa o una ruta absoluta (la ruta predeterminada es la ruta cuando se abre el proceso)
modo: el método de apertura

modelo significado cuando el archivo no existe
r solo lectura informar error
w solo escribe crear un archivo
a agregar solo escritura crear un archivo
rb solo lectura binaria informar error
wb solo escritura binaria crear un archivo
abdominales agregar binario solo escribir crear un archivo
r+ Lee y escribe informar error
w+ Lee y escribe crear un archivo
un+ Agregar lectura y escritura crear un archivo
rb+ lectura y escritura binaria informar error
wb+ lectura y escritura binaria crear un archivo
ab+ Agregar binario leer y escribir crear un archivo

Todos los modos de apertura anteriores borrarán el archivo al abrirlo con la operación 'b' .

modo r para abrir el archivo

)
no se abre cuando el archivo no existe.

Se abre correctamente cuando el archivo existe.

modo w para abrir el archivo


Cree automáticamente archivos que deben abrirse.

Después de abrir, el archivo se vaciará

un modo para abrir el archivo

Abra el archivo en un modo y cree el archivo si no existe, y escriba el contenido al final del archivo si existe.

otros modos como

cerrar()

Los programadores del lenguaje C deben desarrollar un buen hábito de liberar cuando se agotan para evitar pérdidas de memoria tanto como sea posible.La interfaz fclose() se usa para cerrar el flujo de archivos.

 
 
int fclose(FILE *fp);

Los parámetros de la interfaz de cierre son simples, simplemente pase el puntero de la secuencia de archivos que debe cerrarse.

fwrite()

 
 
size_t fwrite(const void *ptr, size_t size, size_t number, FILE *stream);

Parámetros:
ptr: el contenido del archivo escrito
tamaño: el tamaño de la unidad de datos escrita (byte)
número: el número total de
flujo de datos escrito: el flujo de archivo

La operación de escritura pasa parámetros como se muestra en la figura.

miedo()

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

Los parámetros son similares a fwrite()
ptr es el contenedor para leer el contenido del archivo, el espacio debe abrirse con anticipación y el número no debe ser mayor que el espacio abierto real

La operación de lectura de archivos se muestra en la figura.

Interfaz de operación de archivos del sistema

descriptor de archivo fd

Un descriptor de archivo identifica de forma única una secuencia abierta por el proceso.

abierto()

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

Parámetros:
nombre de ruta: ruta del archivo, el valor predeterminado es la ruta cuando se crea el proceso
indicadores: determina el modo de apertura del archivo
modo: permisos de archivo al crear un archivo

Comprender el principio de marcar bits

Todos los datos en una computadora se componen de bits. Un número entero tiene 32 bits y un bit se usa como marca. Un tipo int puede llevar 32 marcas y se pueden combinar a voluntad.
De la siguiente manera, simplemente pase el marcado correspondiente para la operación que desea completar.

Banderas comunes para abrir ()

marca significado
O_RDONLY solo lectura
O_MAL solo escribe
O_RDWR Lee y escribe
O_APPEND suma
O_CREAR crear un archivo
O_TRUNC archivo vacio

Pase el indicador de solo lectura y el indicador de creación de archivos a la interfaz open() y cree el archivo como se muestra en la figura. El archivo se crea, pero se puede ver que sus permisos están desordenados.Se puede ver que esta interfaz no es suficiente para abrir el archivo como fopen().

Use otra interfaz para crear un archivo con permisos normales, pero los permisos no son los que imaginamos para establecer ningún código de permiso para crear cualquier archivo de permisos. Este problema está relacionado con la máscara de permisos umask

El código de permiso y umask se invierten y luego el código de permiso final se obtiene por adición bit a bit.Si necesita restablecer el umask solo en este programa, solo necesita usar la interfaz umask:

 
 
mode_t umask(mode_t mask);

La máscara de parámetros es la máscara de permiso que desea restablecer

Ahora los permisos de archivos creados son exactamente como los quiere el programador.

escribir()

Interfaz de operación de archivo de escritura del sistema

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

操作与fwrite() 基本一致,参数buf 类型为void* ,count 为要写入内容大小(byte)。

写入成功,但如上打开方式还有一个隐患:

后写入的内容并不会在空文件写入,而是会在已有内容上进行覆盖,这样的操作可不像C语言的w操作,针对此问题可以再加一个标志O_TRUNC

如此才可和C语言的fopen() 的 w 操作一致

read()

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

read()参数与write() 基本一致,与fread() 操作相差不多,需要buf 提前开好空间

当文件不存在时:

如此,效果与fread() 一致

close()

使用完文件后需得关闭文件,尽量防止内存泄漏,使用close()接口

 
 
int close(int fd);

两种操作接口联系

操作系统设计时为了安全任何高级语言操作文件都不能绕过操作系统,用户对文件操作只能通过操作系统提供的接口,而Linux操作系统内核主要用C语言编写,提供的接口也是用C语言编写的,C语言用户可以直接使用。C语言操作文件也需通过操作系统提供的接口,因此C语言的文件操作接口是对系统文件接口进行封装后暴露出来的。
但既然已经有系统接口了为什么还要C语言文件操作接口,此问题原因有几个:

  1. 使用不方便(对比之前的fopen()open())
  2. C语言是跨平台语言,若使用系统文件操作接口,同一份代码移植到其他平台将会编译不通过,使用封装后的接口,可以完美解决这个问题

高级语言都是用自己的语言特性封装系统接口来操作文件

系统接口 语言接口
open(const char* path, O_WRONLY | O_CREAT | O_TRUNC) fopen(const char* path, "w")
open(const char* path, O_RDONLY) fopen(const char* path, "r")
open(const char* path, W_WRONLY | O_CREAT |O_APPEND) fopen(const char* path, "a")
close(int fd) fclose(FILE* fStream)
write(fd, const void* buf, size_t count) fwrite(const void* ptr, size_t size, size_t number, FILE* fStream)
read(fd, void* buf, size_t count) fread(void* ptr, size_t size, size_t number, FILE* fStream)

C语言对封装的接口跨平台解决办法
条件编译 + 穷举

Supongo que te gusta

Origin blog.csdn.net/weixin_47367099/article/details/127486070
Recomendado
Clasificación