【C语言】文件操作 -- 详解

一、什么是文件

磁盘上的文件是文件。

1、为什么要使用文件

        举个例子,当我们想实现一个 “通讯录” 程序时,在通讯录中新建联系人、删除联系人等一系列操作,此时的数据存储于内存中,程序退出后所有数据都会随之消失。为了让通讯录中的信息得以保存,也就是想让数据持久化,我们就需要采用让数据持久化的方法。我们一般数据持久化的方法有:把数据存放在磁盘文件中,或存放到数据库等方式


在程序设计中,我们一般谈的文件有两种:程序文件数据文件

2、程序文件

包括源程序文件(后缀为 .c ),目标文件( windows 环境后缀为 .obj ),可执行程序( windows 环境后缀为 .exe)。
#include <stdio.h>int main()
{printf("Hello,World!\n");return 0;
}

(1)

 (2)


3、数据文件

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

此时,如果我写的程序在读写这个文件(我可以读这个文件夹的内容进我的程序中,或是将一些内容写到这个文件夹中),那么这个文件就成为数据文件。 


二、文件名

一个文件要有一个唯一的文件标识,方便用户识别和引用。

文件名包含三个部分:文件路径 + 文件名主干 + 文件后缀( 例如:C:\code\test.txt )

 为了方便起见,文件标识常被称为文件名


三、文件类型

  • 根据数据的组织形式,数据文件被称为文本文件或者二进制文件
  1. 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件
  2. 如果要求在外存上以 ASCII 的形式存储,则需要在存储前转换。以 ASCII 字符的形式存储的文件就是文本文件
一个数据在内存中是怎么存储的呢?
字符一律以  ASCII  形式存储,数值型数据既可以用  ASCII  形式存储,也可以使用二进制形式存储。如有整数 10000 ,如果以  ASCII  码的形式输出到磁盘,则磁盘中占用  个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占 4  个字节(  VS2019  测试)。
#include <stdio.h>int main()
{int a = 10000;FILE* pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf); // 二进制的形式写到文件中fclose(pf);pf = NULL;return 0;
}

 

 

 

 


四、文件缓冲区(File Buffer)

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

#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); // 刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");Sleep(10000);fclose(pf); // fclose在关闭文件的时候,也会刷新缓冲区pf = NULL;return 0;
}

 

结论: 因为有缓冲区的存在,C 语言在操作文件时,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。


五、文件指针

在 C 语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。

  • 缓冲文件系统中,关键的概念是文件类型指针,简称文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名 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;

 注意

  1. FILE 的结构在不同的 C 编辑器中包含的内容并不是不完全相同的,但还是颇为相似的。
  2. 每当打开一个文件时,系统会根据文件的状况自动创建一个 FILE 结构的变量,并填充其中的信息。只要文件被读写发生变化,文件信息区也会跟着发生变化。至于文件变化时文件信息区是怎么变化和修改的,我们其实并不需要关心这些细节,因为 C 语言已经帮你弄好了。
  3. 我们一般会通过一个 FILE 的指针来维护这个 FILE 结构的变量。并不会直接使用,而是拿一个结构体指针指向这个结构,通过这个指针来访问和维护相关的数据,这样使用起来会更加方便。
// 以创建一个FILE*的指针变量
FILE* pf; // 文件指针变量
定义  pf  是一个指向  FILE   类型数据的指针变量。可以使  pf  指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件


六、文件的打开和关闭

  • 文件在读写之前应该先打开文件,在使用结束之后应该关闭文件
  • 在编写程序的时候,在打开文件的同时,都会返回一个 FILE* 的指针变量指向该文件,也相当于建立了指针和文件的关系
  • ANSIC 规定使用 fopen 函数来打开文件,fclose 来关闭文件

 

 

// open the file
FILE * fopen (const char* filename, const char* mode);// close the file
int fclose (FILE* stream);// filename参数指的是文件名,mode参数为打开方式

#include <stdio.h>int main()
{FILE* pf = fopen("test.dat", "w");if (pf == NULL) // 检查是否为空指针{perror("fopen");return 1;}fclose(pf);pf = NULL; // 将pf置为空指针return 0;
}

 一切正常。

我们把 test.dat 文件删除,然后打开方式改成 r 试试看。

#include <stdio.h>int main()
{FILE* pf = fopen("test.dat", "r");if (pf == NULL) // 检查是否为空指针{perror("fopen");return 1;}fclose(pf);pf = NULL; // 将pf置为空指针return 0;
}

 perror 返回的错误信息。

如果不适用相对路径,使用绝对路径读文件:

可以使用绝对路径,但是要注意转义绝对路径中的斜杠

#include <stdio.h>int main()
{// FILE* pf = fopen("D:\code\0824\0824\test.dat", "w"); // errorFILE* pf = fopen("D:\\code\\0824\\0824\\test.dat", "w"); // 转移字符\if (pf == NULL){perror("fopen");return 1;}fclose(pf);pf = NULL;return 0;
}

注意:不关闭文件的后果:一个程序能够打开的文件是有限的,文件属于一种资源。如果只打开不释放,文件就会被占用。可能会导致一些操作被缓冲在内存中,如果不能正常关闭,缓冲在内存中的数据就不能正常写入到文件中从而导致数据的丢失。


七、文件的顺序读写

  • 顺序读写,简而言之就是按照顺序在文件中读和写。

首先要了解什么是读写:我们写的程序是在内存中,而数据是要放到文件中的,文件又是在硬盘上的。当我们把文件里的数据读到内存中去时,这个动作我们称之为输入 / 读取。反过来,如果把程序中的东西放到硬盘上,这个动作我们称之为输出 / 写入


1、什么是流

⚪stdin:标准输入流 - 键盘

⚪stdout:标准输出流 - 屏幕

⚪stderr:标准错误流 - 屏幕

(它们的类型都是 FILE* )

#include<stdio.h>int main()
{// 从标准输出流里输入数据fputc('b', stdout);// 同printf("b");fputc('i', stdout);fputc('t', stdout);printf("\n");// 从标准输入流里读取数据int ret = fgetc(stdin); // 同scanf("%d", ret);printf("%c\n", ret);ret = fgetc(stdin);printf("%c\n", ret);ret = fgetc(stdin);printf("%c\n", ret);return 0;
}


2、字符输入函数 fgetc

从指定的流 stream 获取下一个字符,并把位置标识符向前移动(字符必须为一个无符号字符)。如果读取成功会返回相应的 ASCII码值,如果读取失败会返回一个 EOF 适用于所有输入流。

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ret = fgetc(pf);printf("%c\n", ret);ret = fgetc(pf);printf("%c\n", ret);ret = fgetc(pf);printf("%c\n", ret);fclose(pf);pf = NULL;return 0;
}

 

读取结束或者读取失败返回 EOF。


3、字符输出函数 fputc

  • 将参数 char 指定的字符写入到指定的流 stream 中,并把位置标识符向前移动 (字符必须为一个无符号字符)。适用于所有输出流。

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputc('a', pf);fputc('b', pf);fputc('c', pf);fclose(pf);pf = NULL;return 0;
}

 abc 成功被写入。

倘若将代码修改为:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}/*fputc('a', pf);fputc('b', pf);fputc('c', pf);*/fclose(pf);pf = NULL;return 0;
}

此时再次运行,我们发现那个文件里的内容不见了(大小也变为0kb): 


4、文本行输入函数 fgets

  • 从指定的流 stream 读取一行,并把它存储在 string 所指向的字符串中,当读取(n-1)个字符时,或者读取到换行符、到达文件末尾时,它会停止,具体视情况而定。适用于所有输入流。

注意:假如 n 是 100,读取到的就是 99 个字符(n-1),因为要留一个字符给 '\0'。

 

#include <stdio.h>int main()
{char arr[10] = "xxxxxx"; // 存放处FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}fgets(arr, 4, pf);printf("%s\n", arr);fgets(arr, 4, pf);printf("%s\n", arr);fclose(pf);pf = NULL;return 0;
}


5、文本行输出函数 fputs

  • 将字符串写入到指定的流 stream 中(不包括空字符)。适用于所有输出流。

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fputs("abcdef", pf);fputs("123456", pf);fclose(pf);pf = NULL;return 0;
}

如果想要在 "abcdef" 后面换行,只需在 fputs("abcdef\n", pf); 加上换行符即可。 


6、 格式化输入函数 fscanf

  • fscanf 用于对格式化的数据进行读取,从流 stream 读取格式化输入。适用于所有输入流。

#include <stdio.h>struct Student
{char name[10];int id;float score;
};int main()
{struct Student s1 = { 0 };// 对格式化的数据进行写文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}fscanf(pf, "%s %d %f", s1.name, &(s1.id), &(s1.score));printf("%s %d %f\n", s1.name, s1.id, s1.score);fclose(pf);pf = NULL;return 0;
}

注意: p1.name本身就是地址(不用&)。


7、格式化输出函数 fprintf

#include<stdio.h>
struct S
{char arr[10];int num;float sc;
};int main()
{struct S s = { "abcdef", 10, 5.5f };FILE* pf1 = fopen("test.txt", "w");if(pf1 == NULL){perror("fopen");return 1;}fprintf(pf1, "%s %d %f", s.arr, s.num, s.sc); // 将结构体格式化的数据写入文件fclose(pf1);pf1 = NULL;struct S temp = { 0 }; // 用于存储读出的数据 FILE* pf2 = fopen("test.txt", "r");if(pf2 == NULL){perror("fopen");return 1;}fscanf(pf2, "%s %d %f", temp.arr, &(temp.num), &(temp.sc));	// 再把数据从文件中读到结构体中printf("%s %d %f\n", temp.arr, temp.num, temp.sc); // 打印fclose(pf2);pf2 = NULL;return 0;
}


8、二进制输入函数 fread

  • 从流中读取,从给定流 stream 读取数据到 buffer 所指向的数组中。

#include <stdio.h>
// 二进制的形式读struct S
{char arr[10];int num;float score;
};int main()
{struct S s = { 0 };FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}fread(&s, sizeof(struct S), 1, pf);printf("%s %d %f", s.arr, s.num, s.score);fclose(pf);pf = NULL;return 0;
}

9、二进制输出函数 fwrite

  •  写一个数据到流中去,把 buffer 所指向的数组中的数据写入到给定流 stream 中。

#include <stdio.h>
// 二进制的形式写struct S
{char arr[10];int num;float score;
};int main()
{struct S s = { "abcde", 10, 5.5f };FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}fwrite(&s, sizeof(struct S), 1, pf);fclose(pf);pf = NULL;return 0;
}

 

为什么是乱码?为什么 abcde 不是乱码?
  1. 我们刚才用的都是文本编译器,文本编译器打开二进制形式的文件完全是两种状态。
  2. 因为字符串以文本形式写进去和以二进制形式写进去是一样的,但是对于整数、浮点数等来说就不一样了,文本形式写入和二进制形式写入完全是两个概念。

结论:fwritefread 是一对,fwrire 写进去用 fread 读。


八、文件的随机读写

1、文件指针定位函数 fseek

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

int fseek (FILE* stream, long int offset, int origin);// offset是偏移量,origin是起始位置,有三种选项:// 1、SEEK_CUR - 当前文件指针的位置开始偏移。
// 2、SEEK_END - 文件的末尾位置开始偏移。
// 3、SEEK_SET - 文件的起始位置开始偏移。

 

#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);ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}

如果我想得到 a a b,该怎么处理呢?
#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);// 调整文件指针fseek(pf, -1, SEEK_CUR); // SEEK_CUR为当前文件指针位置,偏移量为-1,向前移动1个单位ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}


⚪用 SEEK_SET ,打印 a d e

#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);// 调整文件指针fseek(pf, 2, SEEK_CUR); // SEEK_SET为文件的起始位置,偏移量为2,向后移动2个单位ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}


⚪用 SEEK_END ,打印 a e f 

#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);// 调整文件指针fseek(pf, -2, SEEK_END); // SEEK_END为当前文件末尾位置,偏移量为-2,向前移动2个单位ch = fgetc(pf);printf("%c\n", ch);ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}


2、返回偏移量函数 ftell

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

long int ftell ( FILE * stream );
#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}// 调整文件指针fseek(pf, 5, SEEK_CUR); // SEEK_CUR为当前文件指针位置,偏移量为5,向后移动5个单位int ch = fgetc(pf);printf("%c\n", ch); // f// 返回偏移量int ret = ftell(pf);printf("%d\n", ret); // 6fclose(pf);pf = NULL;return 0;
}

 


3、文件指针回到起始位置函数 rewind

  • rewind(意为倒带,磁带倒带),设置文件位置为给定流 stream 的文件的开头,让文件指针回到起始位置

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}// 调整文件指针fseek(pf, 5, SEEK_CUR); // SEEK_CUR为当前文件指针位置,偏移量为5,向后移动5个单位// 返回偏移量int loc = ftell(pf);printf("fseek调整文件指针后:%d\n", loc); // 6// 让文件指针回到起始位置rewind(pf);// 再次返回偏移量,看看是不是回到起始位置了loc = ftell(pf);printf("使用rewind后:%d\n", loc); // 6fclose(pf);pf = NULL;return 0;
}


九、文件读取结束的判定 

1、被错误使用的 feof

  • 在文件结束时判断文件因为何种原因导致文件结束的函数判断是因为读取失败而结束,还是因为遇到文件尾而结束。如果文件结束,则返回非 0 值,否则返回 0。

注意feof 函数是个经常被错误使用的一个函数。在文件读取过程中,不能用 feof 函数的返回值直接判断文件是否结束!feof 函数绝对不是用来判断文件是否结束的函数!feof 不是用来判定文件是否结束了的,还是在文件已经结束时,判断是什么原因导致文件结束的

文本文件读取是否结束,判断返回值是否为EOF fgetc),或者NULLfgets

  • fgetc 判断是否为 EOF。
  • fgets 判断返回值是否为 NULL。
#include <stdio.h>
#include <stdlib.h>int main()
{int ch = 0; // 注意:int,非char,要求处理EOFFILE* pf = fopen("test.txt", "r");if (!pf){perror("fopen");return EXIT_FAILURE; // 符号常量EXIT_FAILURE,表示没有成功地执行一个程序}// fgetc - 当读取失败的时候或者遇到文件结束的时候,都会返回EOFwhile ( (ch = fgetc(pf)) != EOF ){putchar(ch);}printf("\n");// 判断文件结束的原因if (ferror(pf)) // ferror - 检查是否出现错误{  puts("读取失败错误(I/O error when reading)");}else if (feof(pf)){puts("遇到文件尾而结束(End of file reached successfully)");}fclose(pf);pf = NULL;
}

 


二进制文件的读取结束判断,判断返回值是否小于实际要读的个数

  • fread 判断返回值是否小于实际要读的个数。
#include <stdio.h>enum { SIZE = 5 };int main(void)
{double a[SIZE] = {1.0,2.0,3.0,4.0,5.0};double b = 0.0;size_t ret_code = 0;FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式fwrite(a, sizeof(*a), SIZE, fp); // 写double的数组fclose(fp);fp = fopen("test.bin","rb");// 读 double 的数组while((ret_code = fread(&b, sizeof(double), 1, fp))>=1){printf("%lf\n",b);}if (feof(fp)){printf("Error reading test.bin: unexpected end of file\n");}else if (ferror(fp)){perror("Error reading test.bin");}fclose(fp);fp = NULL;
}


2、正确判定文件是否读取结束的方法

  • 文本文件读取是否结束,判断返回值是否为 EOFfgetc),或者 NULLfgets)。
  1. fgetc 函数在读取结束时会返回 EOF,正常读取时,返回读取到的字符的 ASCII 码值
  2. fgets 函数在读取结束时会返回 NULL,正常读取时,返回存放字符串的空间的起始地址
  3. fread 函数在读取结束时会返回实际读取到的完整元素的个数,如果发现读取到的完整的元素个数小于指定的元素个数,那么就是最后一次读取了。

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

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

相关文章

第60步 深度学习图像识别:误判病例分析(Pytorch)

基于WIN10的64位系统演示 一、写在前面 上期内容基于Tensorflow环境做了误判病例分析&#xff08;传送门&#xff09;&#xff0c;考虑到不少模型在Tensorflow环境没有迁移学习的预训练模型&#xff0c;因此有必要在Pytorch环境也搞搞误判病例分析。 本期以SqueezeNet模型为…

窗口看门狗

从下往上看: 1. 时钟设置 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//使能独立看门狗时钟 WWDG_SetPrescaler(WWDG_Prescaler_8);//看门狗预分频器WWDG counter clock (PCLK1/4096)/8 2.设置窗口值 实际就是设置WWDG_CR的低七位值, 但是这个值要大于0x40(也就是…

【分享】小型园区组网场景

小型园区组网图 在小型园区中&#xff0c;S2700&S3700通常部署在网络的接入层&#xff0c;S5700&S6700通常部署在网络的核心&#xff0c;出口路由器一般选用AR系列路由器。 接入交换机与核心交换机通过Eth-Trunk组网保证可靠性。 每个部门业务划分到一个VLAN中&#…

Vulnhub: DriftingBlues: 2靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.207 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.207 80端口的/blog目录为wordpress wpscan收集wordpress用户和爆破密码 wpscan --url http://driftingblues.box/blog -e…

非凸联合创始人李佐凡受邀出席复旦DSBA项目座谈会

8月17日&#xff0c;非凸科技联合创始人&CTO李佐凡受邀参加复旦管院数据科学与商业分析专业硕士&#xff08;DS&BA&#xff09;项目发展座谈会&#xff0c;与学校教授、老师在生源背景、课程教学、职业发展、学生培养和企业合作方面进行深入交流&#xff0c;旨在更好地…

【C++练习】普通方法+利用this 设置一个矩形类(Rectangle), 包含私有成员长(length)、 宽(width), 定义一下成员函数

题目 设置一个矩形类(Rectangle), 包含私有成员长(length)、 宽(width), 定义成员函数: void set_ len(int l); //设置长度 设置宽度void set_ wid(int w); 获取长度: int get len(); 获取宽度: int get _wid); 显示周长和面积: v…

民族传统文化分享系统uniapp 微信小程序

管理员、用户可通过Android系统手机打开系统&#xff0c;注册登录后可进行管理员后端&#xff1b;首页、个人中心、用户管理、知识分类管理、知识资源管理、用户分享管理、意见反馈、系统管理&#xff0c;用户前端&#xff1b;首页、知识资源、用户分享、我的等。 本系统的使用…

GO-vscode远程开发和调试

本文内容主要包括&#xff1a; 概述&#xff1a; 主要就是把代码放到服务器上然后远程去开发和调试 工具&#xff1a; vscode 远程端&#xff1a; linux 一.安装远程插件 vscode安装Remote - SSH&#xff0c;Remote Explorer&#xff0c;Remote Development&#xff0c…

卷积过程详细讲解

1&#xff1a;单通道卷积 以单通道卷积为例&#xff0c;输入为&#xff08;1,5,5&#xff09;&#xff0c;分别表示1个通道&#xff0c;宽为5&#xff0c;高为5。假设卷积核大小为3x3&#xff0c;padding0&#xff0c;stride1。 卷积过程如下&#xff1a; 相应的卷积核不断…

企微配置回调服务

1、企微配置可信域名 2、企微获取成员userID 3、企微获取用户敏感数据 4、企微配置回调服务 文章目录 一、简介1、概述2、相关文档地址 二、企微配置消息服务器1、配置消息接收参数2、参数解析3、参数拼接规则 三、代码编写—使用已有库1、代码下载2、代码修改3、服务代码编写 …

基于swing的超市信息管理系统java jsp仓库进销存mysql源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 基于swing的超市信息管理系统 系统有1权限&#xff1…

Linux驱动开发(Day5)

思维导图&#xff1a; 不同设备号文件绑定&#xff1a;

回归预测 | MATLAB实现SA-ELM模拟退火算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现SA-ELM模拟退火算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现SA-ELM模拟退火算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基本…

ElasticSearch-集成ik分词器

本文已收录于专栏 《中间件合集》 目录 背景介绍版本选择优势说明集成过程1.下载安装包2.解压安装包3.重启ElasticSearch服务3.1通过ps -ef | grep elastic查看正在启动的es进程号3.2使用kill -9 xxx 杀死进程3.3使用 ./elasticsearch 启动es服务 分词测试细粒度分词方式分词请…

CTFshow 限时活动 红包挑战9 详细题解

CTFshow红包挑战9 题目源码开源了。源码如下&#xff1a; common.php <?phpclass user{public $id;public $username;private $password;public function __toString(){return $this->username;}}class cookie_helper{private $secret "*************"; /…

【Java架构-包管理工具】-Maven私服搭建-Nexus(三)

本文摘要 Maven作为Java后端使用频率非常高的一款依赖管理工具&#xff0c;在此咱们由浅入深&#xff0c;分三篇文章&#xff08;Maven基础、Maven进阶、私服搭建&#xff09;来深入学习Maven&#xff0c;此篇为开篇主要介绍Maven私服搭建-Nexus 文章目录 本文摘要1. Nexus安装…

本地搭建CFimagehost私人图床【公网远程访问】

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

Redis数据结构之Set

Set 类型是一个无序并唯一的键值集合&#xff0c;它的存储顺序不会按照插入的先后顺序进行存储。Redis 中集合是通过哈希表实现的&#xff0c;所以添加&#xff0c;删除&#xff0c;查找的复杂度都是 O(1)。相对于列表&#xff0c;集合也有两个特点&#xff1a;无序、不可重复 …

js reverse实现数据的倒序

2023.8.25今天我学习了如何在数组顺序进行倒序排列&#xff0c;如&#xff1a; 原数组为&#xff1a; 我们只需要对数组使用reverse()方法 let demo [{id: 1, name: 一号},{id: 2, name: 二号},{id: 3, name: 三号},]demo.reverse()console.log(demo) 扩展&#xff1a; 当我…

jmeter入门:接口压力测试全解析

一.对接口压力测试 1.配置 1.添加线程组&#xff08;参数上文有解释 这里不介绍&#xff09; 2.添加取样器 不用解释一看就知道填什么。。。 3.添加头信息&#xff08;否则请求头对不上&#xff09; 也不用解释。。。 4.配置监听器 可以尝试使用这几个监听器。 2.聚合结果…