[C]带你了解C语言是如何操作文件的

news2024/11/19 22:38:46

文章目录

  • 一、认识文件
    • 1.1 为什么要使用文件
    • 1.2 什么是文件
    • 1.3 文件名
    • 1.4 文件指针
    • 1.5 文件的打开和关闭
  • 二、文件的顺序读写
    • 2.1 fgetc和fputc
    • 2.2 fgets和fputs
    • 2.3 fscanf和fprintf
    • 2.4 fread和fwrite
    • 2.5 对比一组函数
  • 三、文件的随机读写
    • 3.1 fseek
    • 3.2 ftell
    • 3.3 rewind
  • 四、文本文件和二进制文件
  • 五、文件读取结束的判定
    • 5.1 feof 和 ferror
  • 六、文件缓冲区

一、认识文件

1.1 为什么要使用文件

使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

1.2 什么是文件

电脑磁盘上的文件是文件,但是在程序设计当中,从文件功能的角度来看一般把文件分为两种:程序文件数据文件
程序文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

本文主要是讨论数据文件,在以前的学习中所处理数据的输入输出都是以终端为对象,现在我们来讨论如何把数据输出到磁盘上以及如何把磁盘上的数据读取到内存中。

1.3 文件名

一个文件要有一个唯一的文件标识,以便用户识别和使用。
文件名包含三部分:文件路径+文件名主干+文件后缀
为了方便起见,文件标识通常被称为文件名

1.4 文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
       };
typedef struct _iobuf FILE;

不同的C语言编译器,FILE类型包含的内容大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE*的指针变量:

FILE* pf;//文件指针变量

定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件
比如:
在这里插入图片描述

1.5 文件的打开和关闭

读写文件之前,先要打开文件,在使用结束之后关闭文件
在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。其函数原型如下:
在这里插入图片描述 在这里插入图片描述

FILE * fopen ( const char * filename, const char * mode );
//返回FILE的指针, filename表示文件名,mode是打开文件的方式
//例子
//打开文件
FILE * pf = fopen ( "test.txt", "w" );
//关闭文件
fclose ( pf );
pf = NULL;

打开方式如下:

文件使用方式含义如果指定文件不存在
“r” (只读)为了输入数据,打开一个已经存在的文本文件出错
“w” (只写)为了输出数据,打开一个文本文件建立一个新文件
“a” (追加)向文件尾添加数据建立一个新文件
“rb” (只读)为了输入数据,打开一个二进制文件出错
“wb” (只写)为了输出数据,打开一个二进制文件建立一个新文件
“ab” (追加)向一个二进制文件尾添加数据出错
“r+” (读写)为了读和写,打开一个文本文件出错
“w+” (读写)为了读和写,建立一个新文件建立一个新文件
“a+” (读写)打开一个文本文件,在文件尾进行读和写建立一个新文件
“rb+” (读写)为了读和写,打开一个二进制文件出错
“wb+” (读写)为了读和写,新建一个新的二进制文件建立一个新文件
“ab+” (读写)打开一个二进制文件,在文件尾进行读和写建立一个新文件

例子:

#include <stdio.h>

int main ()
{
  //打开文件,以只读的方式打开名字为 myfile.txt 的文件
  FILE * pFile = fopen ("myfile.txt","w");
  //文件操作
  if (pFile!=NULL)  //打开成功
 {
    fputs ("fopen example",pFile);//写
    //关闭文件
    fclose (pFile);   
    pFile = NULL; //置为空指针
 }
  return 0;
}

执行上述程序,可以再工程目录下找到名字为 myfile.txt 的文件,打开文件可以看到字符串"fopen example"。
在这里插入图片描述

二、文件的顺序读写

在C语言中提供了以下几种函数:

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

需要注意的是这些函数都是顺序读写的。

2.1 fgetc和fputc

fgetc是字符输入函数适用于所有输入流;
fputc是字符输出函数适用于所有输出流。

不管是fgetc(读)还是fputc(写)它们读或者写的对象都是单个的字符,并且都是按照顺序读写字符。
函数原型:
在这里插入图片描述 在这里插入图片描述

//例子
#include <stdio.h>

int main()
{
	//写文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//使用
	int i = 0;
	for (i = 'a'; i <= 'z'; i++)
	{
		fputc(i, pf);  //把a~z依次写入文件中
	}
	fclose(pf);
	pf = NULL;
	//读文件
	pf = fopen("test.txt", "r");
	for (i = 'a'; i <= 'z'; i++)
	{
		char ch = fgetc(pf);//把a~z依次读取,并赋值给c
		printf("%c ", ch);//打印
	}
	fclose(pf);
	pf = NULL;

	return 0;
}	

执行上述程序,可以再工程目录中看到新建了一个 test.txt 文件,在文件中可以看到顺序存放的a ~ z字母,并且程序会在屏幕上打印出a ~ z 26个字母。
在这里插入图片描述在这里插入图片描述

2.2 fgets和fputs

fgets是行输入函数,即在文件中顺序读取一个字符串。
fputs是行输出函数,即在文件中顺序写入一个字符串。

其函数原型如下:
在这里插入图片描述在这里插入图片描述

//例子
#include <stdio.h>

int main()
{
	//写文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//使用
	//int fputs ( const char * str, FILE * stream );
	//把str所指向的字符串写入stream所指向的文件流当中
	//写入成功返回非负值,写入失败返回eof
	fputs("The harder the luckier", pf);
	fclose(pf);
	pf = NULL;

	//读文件
	//char* fgets(char* str, int num, FILE * stream);
	//从stream指向的文件中读取长度最大为num的字符串并返回一个指向该字符串的指针
	//读取失败返回空指针
	pf = fopen("test.txt", "r");
	char arr[30] = { 0 };
	fgets(arr,20,pf);
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;

	return 0;
}

执行程序,可以再工程目录下看到test.txt文件中写入了"The harder the luckier",并且屏幕上会打印出来。
在这里插入图片描述在这里插入图片描述
需要注意的是:

1.fgets函数在读取字符串时,假设最大读取字符数是num,实际上fgets只会读取(num-1)个字符加上一个‘\0’。
2.如果想要fputs函数写入字符串不在同一行,再字符串后加‘\n’即可。

在这里插入图片描述

2.3 fscanf和fprintf

fsacnf是格式化输入函数适用于所有输入流;
fprintf是格式化输出函数适用于所有输出流。

其函数原型如下:
在这里插入图片描述在这里插入图片描述

//例子
#include <stdio.h>
struct S
{
	char name[20];
	int age;
	int score;
};

int main()
{
	//写文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//使用
	//int fprintf ( FILE * stream, const char * format, ... );
	//与printf()的使用非常类似,只不过在前面加了一个文件指针,表示写入到文件中
	struct S s1 = { "zhangsan",18,60 };
	fprintf(pf, "%s %d %d", s1.name, s1.age, s1.score);
	fclose(pf);
	pf = NULL;

	//读文件
	pf = fopen("test.txt", "r");
	//int fscanf ( FILE * stream, const char * format, ... );
	//与scanf()的使用非常类似,只不过在前面加了一个文件指针,表示从文件中读取
	struct S s2 = { 0 };
	fscanf(pf, "%s %d %d", s2.name, &(s2.age), &(s2.score));
	printf("%s %d %d\n", s2.name, s2.age, s2.score);
	fclose(pf);
	pf = NULL;

	return 0;
}

执行程序,可以再工程目录下看到 test.txt 文件中写入了s1的信息,并且屏幕上会打印出来。
在这里插入图片描述在这里插入图片描述

2.4 fread和fwrite

fread是二进制输入函数只适用于文件;
fwrite是二进制输出函数只适用于文件。

其函数原型如下:
在这里插入图片描述在这里插入图片描述

//例子
#include <stdio.h>
struct S
{
	char name[20];
	int age;
	int score;
};

int main()
{
	//写文件
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");//打印错误信息
		return 1;
	}
	//使用
    //size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
	//把ptr所指向的空间count个大小为size字节的数据写入到stream当中去
	//返回成功写入数据的个数
	struct S s1 = { "zhangsan",18,60 };
	fwrite(&s1,sizeof(struct S),1,pf);
	fclose(pf);
	pf = NULL;

	//读文件
	pf = fopen("test.txt", "rb");
	//size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
	//从stream所指向的文件中读取count个大小为size字节的数据放到ptr所指向的空间中
	//返回成功读取数据的个数
	struct S s2 = { 0 };
	fread(&s2, sizeof(struct S),1,pf);
	printf("%s %d %d\n", s2.name, s2.age, s2.score);
	fclose(pf);
	pf = NULL;

	return 0;
}

执行程序,可以看到下图所示结果:
在这里插入图片描述
在工程目录下找到 test.txt 文件,打开 test.txt 文件发现有些东西我们是看不懂的,因为此时数据是以二进制的形式放进去的。而因为“zhangsan”以文本的形式和以二进制的形式放进去内容是一样的,所以我们能看懂。
在这里插入图片描述
而当我们以二进制的形式打开test.txt文件时,可以看到里面存放的是二进制的数据。
在这里插入图片描述

2.5 对比一组函数

scanf/fscanf/sscanf
printf/fprintf/sprintf

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

//这是一个例子
#include <stdio.h>
struct S
{
	char name[20];
	int age;
	int score;
};

int main()
{
	//int sscanf(const char* s, const char* format, ...);
	struct S s = { 0 };
	char arr[] = "zhangsan 18 60"; //字符串
	sscanf(arr,"%s %d %d",s.name,&(s.age),&(s.score));//把arr中字符串转换成一个格式化数据
	printf("%s %d %d\n", s.name, s.age, s.score);
	
	//int sprintf ( char * str, const char * format, ... );
	char arr1[20] = { 0 };
	sprintf(arr1, "%s %d %d", s.name, s.age, s.score);//把s中格式化数据转换成字符串
	printf("%s \n", arr);
	
	return 0;
}

在这里插入图片描述

三、文件的随机读写

3.1 fseek

根据文件指针的位置和偏移量来定位文件指针。

其函数原型如下:
在这里插入图片描述
origin取值如下:
在这里插入图片描述

例子:

//例子
#include <stdio.h>

//int fseek ( FILE * stream, long int offset, int origin );
//offset表示偏移量
int main()
{
	//写文件
	FILE* pf = fopen("example.txt", "w");
	fputs("abcdef", pf);
	fclose(pf);
	pf = NULL;

	//读文件
	pf = fopen("example.txt", "r");

	char ch = fgetc(pf);
	printf("%c\n", ch); //第一次读肯定是a

	//不改变文件指针的位置再读一次
	ch = fgetc(pf);
	printf("%c\n", ch); //b

	//改变文件指针的位置再读一次
	fseek(pf, 0, SEEK_SET);    
	//从文件头开始偏移量为0
	ch = fgetc(pf);
	printf("%c\n", ch); //会是什么呢?

	fseek(pf, 3, SEEK_SET);
	//从文件头开始偏移量为3
	ch = fgetc(pf);
	printf("%c\n", ch); //会是什么呢?

	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
可以看到打印的依次是a b a d。
在这里插入图片描述

3.2 ftell

返回文件指针相对于起始位置的偏移量。

其函数原型如下:
在这里插入图片描述

#include <stdio.h>

int main()
{
	//写文件
	FILE* pf = fopen("example.txt", "w");
	fputs("abcdef", pf);
	fclose(pf);
	pf = NULL;

	//读文件
	pf = fopen("example.txt", "r");


	fseek(pf, 3, SEEK_SET);
	char ch = fgetc(pf);
	printf("%c\n", ch); //d
	//当我们改变文件指针频繁时,
	//可能会忘记文件指针当前所指向的位置
	//long int ftell ( FILE * stream );
	//使用ftell会把偏移量返回给我们
	int i = ftell(pf);
	printf("%d\n", i); 
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

3.3 rewind

让文件指针的位置回到文件的起始位置

其函数原型如下:
在这里插入图片描述

#include <stdio.h>


int main()
{
	//写文件
	FILE* pf = fopen("example.txt", "w");
	fputs("abcdef", pf);
	fclose(pf);
	pf = NULL;

	//读文件
	pf = fopen("example.txt", "r");
	fseek(pf, 3, SEEK_SET);
	char ch = fgetc(pf);
	printf("%c\n", ch); //d

	//void rewind ( FILE * stream );
	//让文件指针的位置回到文件的起始位置
	rewind(pf); 
	ch = fgetc(pf);
	printf("%c\n", ch); //a
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

四、文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件

  • 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件
  • 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

一个数据在内存中是怎么存储的呢?

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节。
在这里插入图片描述

五、文件读取结束的判定

5.1 feof 和 ferror

在这里插入图片描述
牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
    例如:
    • fgetc 判断是否为 EOF .
    • fgets 判断返回值是否为 NULL.
  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
    例如:
    • fread判断返回值是否小于实际要读的个数。

ferror
在这里插入图片描述

ferror是检查错误指示器,用来判断是否读取时遇到错误而导致读取文件结束。

文本文件的例子

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int c; 
    FILE* fp = fopen("test.txt", "r");
    if (!fp) 
    {
        perror("File opening failed");
        return EXIT_FAILURE;
    }
    //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 读取文件循环
    {
        putchar(c);
    }
    //判断是什么原因结束的
    if (ferror(fp))     //如果ferror(fp)为真,则是读取失败结束
        puts("I/O error when reading");
    else if (feof(fp)) //如果feof(fp)为真,则是遇到文件结尾结束
        puts("End of file reached successfully");
    fclose(fp);
    fp = NULL;
}

在这里插入图片描述
二进制文件的例子

#include <stdio.h>
enum { SIZE = 5 };
int main(void)
{
    double a[SIZE] = { 1.,2.,3.,4.,5. };
    FILE* fp = fopen("test.bin", "wb"); 
    fwrite(a, sizeof * a, SIZE, fp); // 写 double 的数组
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin", "rb");
    size_t ret_code = fread(b, sizeof * b, SIZE, fp); // fread返回读取到double数据的个数

    if (ret_code == SIZE) //判断是否读到SIZE个数据
    {
        puts("Array read successfully, contents: ");
        for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
        putchar('\n');
    }
    else 
    { 
        // 判断结束原因
        if (feof(fp))   //feof(fp)为真,遇到文件结尾结束
            printf("Error reading test.bin: unexpected end of file\n");
        else if (ferror(fp))  //ferror(fp)为真,则是读取文件失败结束
        {
            perror("Error reading test.bin");
        }
    }
    fclose(fp);
    fp = NULL;
    return 0;
}

在这里插入图片描述

六、文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
在这里插入图片描述
注意

对文件进行读写操作时,会先调用系统(操作系统提供的接口)系统帮我们读写文件,读写文件很频繁时会频繁打断操作系统,使操作系统效率降低。缓冲区可以提高操作系统的效率

  • 当我们要把内存中的数据写入到硬盘(把硬盘上的数据输入到内存)中时,写入到硬盘的(输入到内存中的)数据是先会存放在一个输出(输入 )缓冲区,当输出(输入 )的数据把缓冲区填满时,系统才会一次性把数据写入到硬盘(输入到内存中去)。
  • 当我们打开一个文件写入数据时,如果数据不够填满输出缓冲区,操作系统就不会把数据写入到硬盘上;这时如果一直不关闭文件写入或者刷新缓冲区,就有可能会发生错误导致数据丢失。
//这是一个例子
#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
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;
}

在这里插入图片描述等待fflush(pf)刷新缓冲区,就可以看到文件有内容了。
在这里插入图片描述

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

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

相关文章

高云FPGA系列教程(5):ARM点灯工程设计

文章目录[toc]1. ARM核定制2. ARM核程序设计3. ARM程序烧写4. 工程下载本文是高云FPGA系列教程的第5篇文章。 前面几篇笔记都是介绍的高云GW1NSR-4C FPGA部分的使用&#xff0c;本篇文章介绍片上ARM Cortex-M3硬核处理器的使用&#xff0c;演示如何定制一颗ARM处理器硬件&#…

大数据电信客服-数据采集/消费(二)

目录 一、数据采集/消费(存储) 二、数据采集 三、数据消费 四、编写代码 在project-ct.pom 在ct.consume下 在ct.consumer.bean 在ct.consumer.dao 在ct-consumer的resources 在ct-common.pom 在ct.common.api 在ct.common.bean 在ct.common.constant 在ct-common的…

LQ0123 小朋友崇拜圈【DFS】

题目来源&#xff1a;蓝桥杯2018初赛 C C组G题 题目描述 班里N个小朋友&#xff0c;每个人都有自己最崇拜的一个小朋友&#xff08;也可以是自己&#xff09;。 在一个游戏中&#xff0c;需要小朋友坐一个圈&#xff0c; 每个小朋友都有自己最崇拜的小朋友在他的右手边。 求满…

vue06安装vue-cli+使用vue-cli搭建项目+什么是*.vue文件+开发示例+必问面试知识点

目录 1. vue-cli安装 1.1 安装前提 1.2 什么是vue-cli 1.3 安装vue-cli 2. 使用vue-cli构建项目 2.1 使用脚手架创建项目骨架 2.2 到新建项目目录&#xff0c;安装需要的模块 2.3 如何修改端口号 2.4 添加element-ui模块 2.5 package.json详解 3. install命令中的-g…

腾讯云~ zookeeper集群安装、配置、验证

文章目录一、 预备工作1. 下载2. 解压3. 创建目录4. myid 文件5. 验证6. 效果图二、配置管理2.1. zoo1.cfg2.2. zoo2.cfg2.3. zoo3.cfg2.4. 防火墙2.5. 启动zk2.6. 运行状态一、 预备工作 1. 下载 cd /app wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/…

GitLab API 的使用教程

1 简介 GitLab 作为一个开源、强大的分布式版本控制系统&#xff0c;已经成为互联网公司、软件开发公司的主流版本管理工具。使用过 GitLab 的都知道&#xff0c;想要提交一段代码&#xff0c;可以通过 git push 提交到远程仓库&#xff0c;也可以直接在 GitLab 平台上修改提交…

基于华为云IOT平台实现多节点温度采集(STM32+NBIOT)

一、前言 当前的场景是&#xff0c;在高速公路上部署温度采集设备&#xff0c;在高速路地表安装温度检测传感器&#xff0c;检测当前路段的路面实际温度。一段高速路上有多个地点需要采集温度数据。 采集温度数据需要上传到云平台进行数据存储&#xff0c;并且通过可视化界面展…

七万字整理SpringCloud + CloudAlibaba知识点总结笔记

各位小伙伴们大家好&#xff0c;欢迎来到这个小扎扎的spring cloud专栏&#xff0c;在这个系列专栏中我对B站尚硅谷阳哥的spring cloud教程进行一个总结&#xff0c;鉴于 看到就是学到、学到就是赚到 精神&#xff0c;这波依然是血赚 ┗|&#xff40;O′|┛ SpringCloud Clou…

Linux文件系统inode的作用

目录 前言 简介 inode与block 1、查看文件的inode信息 2、查看分区中的inode节点数 前言 前面学习了磁盘管理中的磁盘分区&#xff0c;以及逻辑卷&#xff0c;交换分区的创建&#xff0c;这篇文章将介绍一下我们在分区以及格式化时候用到的ext4文件系统&#xff0c;本盘文…

【云原生之Docker实战】使用Docker部署ShowDoc文档工具

【云原生之Docker实战】使用Docker部署ShowDoc文档工具一、ShowDoc介绍1.ShowDoc简介2.ShowDoc功能二、检查docker版本三、检查docker状态四、下载ShowDoc镜像五、创建ShowDoc容器1.创建数据目录2目录授权3.运行ShowDoc容器4.查看ShowDoc容器状态5.查看容器运行日志六、ShowDoc…

【精通Java篇 | IO流】详讲字节流与常用方法

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;喜欢编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

Java流式编程stream

文章目录一、简介二、创建Stream三、常用操作四、其他操作一、简介 流式 API 从 Java8 开始引入&#xff0c;支持链式书写。 流只能消费一次&#xff0c;不能被两次消费&#xff08;两次最终操作&#xff09; 流在管道中流通&#xff0c;在节点被处理。 流【无存储】&#x…

vim如何进行批量化注释及取消,也在1024表明自己算十分之一的程序员

前言 &#x1f47b;作者&#xff1a;龟龟不断向前 &#x1f47b;简介&#xff1a;宁愿做一只不停跑的慢乌龟&#xff0c;也不想当一只三分钟热度的兔子。 &#x1f47b;专栏&#xff1a;C初阶知识点 &#x1f47b;工具分享&#xff1a; 刷题&#xff1a; 牛客网 leetcode笔记软…

人家网站都免费了,你还用Python去爬?

文章目录⛳️ 实战场景⛳️ 实战编码⛳️ 实战场景 这次实战的目标是一个叫做猫肯的字体站点&#xff0c;该站点所有的字体都是免费可商用的&#xff0c;所以为什么还要去下载呢&#xff1f; 答案是练手&#xff0c;借免费站点学习爬虫&#xff0c;&#x1f30b; 目标站点地址…

Python爬虫技术系列-05字符验证码识别

Python爬虫技术系列-05字符验证码识别1. 光学文字识别1.1 OCR概述1.2 OCR识别库Tesseract下载安装1.3 生成验证码图片1.4 字符验证码识别1.安装python识别验证码库&#xff1a;2.验证码识别&#xff1a;1.5 使用打码平台识别验证码1.6 滑动验证码识别1. 光学文字识别 1.1 OCR概…

卡尔曼滤波实例——预测橘子的轨迹

目录 流程 一、采用轮廓的方式检测橘子位置 &#xff08;一&#xff09;滚动条获取阈值 &#xff08;二&#xff09;获取到图像中的包围橘子对应的白色图形的最小矩形框的信息 二、获取橘子检测框的质心 三、将质心送入卡尔曼滤波器&#xff0c;获取下一次的质心位置 四…

Markdown语言的简单学习

Markdown简单语法标题#空格 一级标题##空格 二级标题 以此类推三级标题四级...五级.....引用列表代码块表格分隔线链接强调语法&#xff08;斜体、加粗、下划线&#xff09;标题 #空格 一级标题 ##空格 二级标题 以此类推 三级标题 四级… 五级… … 引用 这是一段引用 …

<人生重开模拟器>——《Python项目实战》

目录 1.模拟实现 "人生重开模拟器" 1.1 问题导引&#xff1a; 1.2 问题分析&#xff1a; 2. 模拟实现分析及步骤&#xff1a; 3.完整源码&#xff1a; 4.写在最后的话&#xff1a; 后记&#xff1a;●由于作者水平有限&#xff0c;文章难免存在谬误之处&…

数据结构与算法----栈和队列(Stack Queue)

文章目录栈栈的操作栈的初始化入栈出栈取栈顶的元素判断栈是否为空求栈中数据元素的个数遍历栈中的所有元素清空栈栈的存储结构顺序存储链式存储顺序栈和链栈的区别栈的实战题目队列队列的操作入队出队遍历队列清空队列队列的存储结构顺序存储循环队列链式存储队列实战题目总结…

快速发布windows上的web项目【免费内网穿透】

快速发布windows上的web项目【免费内网穿透】 文章目录快速发布windows上的web项目【免费内网穿透】什么是cpolar内网穿透&#xff1f;概述1. 搭建一个静态Web站点1.1 下载演示站点1.2 本地运行演示站点1.3 本地浏览测试站点是否正常2. 注册并安装cpolar内网穿透3. 本地web站点…