[C Avanzado] Operaciones de archivo (2)

contenido

1. Lectura y escritura aleatoria de archivos.

(1) buscar

(2)decir

(3) rebobinar

2. Archivos de texto y archivos binarios

3. Sentencia de fin de lectura de expediente

(1) feof se usa incorrectamente

4. Búfer de archivos


1. Lectura y escritura aleatoria de archivos.

(1) buscar

Cree un archivo test.txt con cadenas como abcdef en él. Cuando estábamos leyendo el archivo, el primer puntero del archivo apuntaba a a, leía un carácter que apuntaba a b, y luego leía un carácter que apuntaba a c... En este tiempo, en orden Lectura, este tiempo es la lectura y escritura secuencial del archivo. Repasemos primero:

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	ch = fgetc(pf);
	printf("%c\n", ch); //b
	ch = fgetc(pf);
	printf("%c\n", ch); //c
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

¿Podemos leerlo de la forma que queramos, como leer directamente en d, lo que implica una función de posicionamiento del puntero del archivo: fseek

  • fseek: mueve un puntero de archivo a una ubicación específica

Ubique el puntero del archivo según la posición y el desplazamiento del puntero del archivo.

int fseek ( FILE * stream, long int offset, int origin );
  • Comprender tres parámetros:
  1. flujo: para qué flujo
  2. desplazamiento: desplazamiento
  3. origen: posición inicial
  • Hay tres opciones para la posición inicial:

  • BUSCAR_CUR: 

1. Desplace el archivo 1 byte hacia adelante desde la posición actual:

	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, -1, SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n", ch); //a
	ch = fgetc(pf);
	printf("%c\n", ch); //b

2. Desplace el archivo 2 bytes hacia atrás desde la posición actual :

	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, 2, SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n", ch); //d
	ch = fgetc(pf);
	printf("%c\n", ch); //e
  • BUSCAR_FIN:

Compensación de 2 bytes hacia adelante  desde el final del archivo

	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, -2, SEEK_END);
	ch = fgetc(pf);
	printf("%c\n", ch); //e
	ch = fgetc(pf);
	printf("%c\n", ch); //f
  • BUSCAR_ESTABLECER:

Compensación de 3 bytes desde el principio del archivo

	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, 3, SEEK_SET);
	ch = fgetc(pf);
	printf("%c\n", ch); //d
	ch = fgetc(pf);
	printf("%c\n", ch); //e

(2)decir

Devuelve el desplazamiento del puntero del archivo en relación con la posición inicial

long int ftell ( FILE * stream );
  • P.ej:
	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, 3, SEEK_SET);
	ch = fgetc(pf);
	printf("%c\n", ch); //d
	int ret = ftell(pf);
	printf("%d\n", ret);//4

(3) rebobinar

Devuelve la posición del puntero del archivo al principio del archivo.

void rewind ( FILE * stream );
  • P.ej:
	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch); //a
	//调整文件指针
	fseek(pf, -1, SEEK_END);
	ch = fgetc(pf);
	printf("%c\n", ch); //f
	//让文件回到起始位置
	rewind(pf);
	ch = getc(pf);
	printf("%c\n", ch); //a

2. Archivos de texto y archivos binarios

Dependiendo de cómo estén organizados los datos, los archivos de datos se denominan archivos de texto o archivos binarios .

Los datos se almacenan en forma binaria en la memoria y, si se envían a la memoria externa sin conversión, es un archivo binario .

Si es necesario almacenarlo en forma de código ASCII en la memoria externa, debe convertirse antes del almacenamiento. Un archivo almacenado en caracteres ASCII es un archivo de texto .

  • ¿Cómo se almacenan los datos en la memoria?

Los caracteres siempre se almacenan en formato ASCII y los datos numéricos se pueden almacenar en formato ASCII o binario.
Si hay un número entero de 10000, si se envía al disco en forma de código ASCII, ocupará 5 bytes en el disco (un byte para cada carácter), y si se envía en forma binaria, solo ocupará ocupan 4 bytes en el disco (prueba VS2013).

  • prueba: (almacenado en binario) 
#include <stdio.h>
int main()
{
	int a = 10000;
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fwrite(&a, sizeof(int), 1, pf);//二进制的形式写到文件中
	fclose(pf);
	pf = NULL;
	return 0;
}

Pongamos el contenido del archivo test.txt en el compilador VS2022 para ver:

  • 10000 en binario: 0000 0000 0000 0000 0010 0111 0001 0000
  • Convertirlo a hexadecimal: 00 00 27 10

3. Sentencia de fin de lectura de expediente

(1) feof se usa incorrectamente

Recuerde: durante el proceso de lectura del archivo, el valor de retorno de la función feof no se puede usar directamente para determinar si el archivo ha terminado.

feof se utiliza para juzgar si la lectura falla o si se encuentra el final del archivo cuando finaliza la lectura del archivo.

1. Si la lectura del archivo de texto ha terminado, determine si el valor de retorno es EOF (fgetc) o NULL (fgets)

  • P.ej:
  1. fgetc determina si es EOF.
  2. fgets determina si el valor de retorno es NULL.

2. Juzgar el final de la lectura del archivo binario, juzgar si el valor devuelto es menor que el número real que se va a leer.

  • P.ej:

fread juzga si el valor devuelto es menor que el número real que se va a leer.

  •  ejemplo:

Supongamos que ponemos un fragmento de código en el archivo test.txt

 Ahora escriba el código para copiar el archivo test.txt y generar el archivo test2.txt

#include<stdio.h>
int main()
{
	FILE* pfread = fopen("test.txt", "r");
	if (pfread == NULL)
	{
		return 1;
	}
	FILE* pfwrite = fopen("test2.txt", "w");
	if (pfwrite == NULL)
	{
		fclose(pfread);
		return 1;
	}
	//文件打开成功
	//读写文件
	int ch = 0;
	while ((ch = fgetc(pfread)) != EOF)
	{
		//写文件
		fputc(ch, pfwrite);
	}
	//判断是什么原因结束的
	if (feof(pfread))
	{
		printf("遇到文件结束标志,文件正常结束\n");
	}
	else if (ferror(pfread))
	{
		printf("文件读取失败结束\n");
	}
	//关闭文件
	fclose(pfread);
	pfread = NULL;
	fclose(pfwrite);
	pfwrite = NULL;
	return 0;
}

Exactamente igual que el contenido del archivo test.txt 

4. Búfer de archivos

Significa que el sistema abre automáticamente un "búfer de archivo" en la memoria para cada archivo que se utiliza en el programa. La salida de datos de la memoria al disco se enviará primero al búfer en la memoria y luego se enviará al disco una vez que el búfer esté lleno. Si los datos se leen del disco a la computadora, los datos se leen del archivo del disco y se ingresan en el búfer de memoria (búfer lleno), y luego los datos se envían al área de datos del programa (variables de programa, etc.) uno por uno del búfer. El tamaño del búfer está determinado por el sistema de compilación C.

  •  Propósito: Mejorar la eficiencia del sistema operativo.
  • Ejemplo:
#include <stdio.h>
#include <windows.h>
int main()
{
	FILE* pf = fopen("test.txt", "w");
	fputs("abcdef", pf);//先将代码放在输出缓冲区
	printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
	//注:fflush 在高版本的VS上不能使用了
	printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
	Sleep(10000);
	fclose(pf);
	//注:fclose在关闭文件的时候,也会刷新缓冲区
	pf = NULL;
	return 0;
}

 

  •  En conclusión:

Debido a la existencia del búfer, cuando el lenguaje C opera el archivo, necesita vaciar el búfer o cerrar el archivo cuando finaliza la operación del archivo. Si no lo hace, puede causar problemas para leer y escribir archivos.

Supongo que te gusta

Origin blog.csdn.net/bit_zyx/article/details/122861056
Recomendado
Clasificación