《Java面向对象程序设计》学习笔记——CSV文件的读写与处理
笔记汇总:《Java面向对象程序设计》学习笔记
笔记记录的不是非常详实,如果有补充的建议或纠错,请踊跃评论留言!!!
什么是CSV文件
CSV文件的定义
CSV 是英文 comma-separated values 的缩写,翻译为 “逗号分隔值“。
CSV 文件可以理解为以带逗号分隔(也可以是其他简单字符分割)的纯文本形式存储表格数据的文件。
CSV文件与Excel文件的关系
CSV文件和Excel文件有点像,但Excel是带格式的文件,且一个工作表里最多只可以存放 1048576 (2^10)行。
可以使用Excel打开CSV。但如果没有按照指定编码方式进行保存,用Excel打开CSV会乱码。
CSV文件的优点
-
方便数据交换
-
无最大行数的限制
CSV文件格式
格式规范
-
CSV文件第一行可以是字段名(也可以不写字段名直接写数据)
-
接下来每一行是字段所对应的值
-
不同 字段/数据 之间用 逗号 隔开
-
其他格式规范
比如:
// 通讯录.csv
姓名,手机,QQ,微信号
小新,13913000001,1819122001,xx9907
小亮,13913000002,1819122002,xiaoliang
小刚,13913000003,1819122003,gang1004
大刘,13913000004,1819122004,liu666
大王,13913000005,1819122005,jack_w
奇妙方程式,12345678910,229600398,qq229600398
// 统计demo.csv
下单,0,a,BCF
付款,0,a,BCF
发货,0,a,BCF
付款,0,a,BCF
收款,0,a,BCF
下单,0,a,BCF
付款,0,a,BCF
CSV文件的读写操作
注意事项
-
其实CSV文件有固定的规范,简单的用逗号分隔,并不是安全的解析方法
比如:有些值中有逗号,直接使用split分隔逗号会出问题
-
一般都是使用类库来对csv文件进行处理,比如python的csv库、java的open-csv库。
-
其实在读写时最好上锁。
-
但个人练习没啥大问题。
-
使用Java读写文件后记得调用方法关闭流。
读取方法
以下为Java中读取CSV文件的方法,程序打印所读内容
// test.csv
Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
1,5.1,1.4,1.4,0.2,Iris-setosa
2,4.9,3,1.4,0.2,Iris-setosa
3,4.7,3.2,1.3,0.2,Iris-setosa
4,4.6,3.1,1.5,0.2,Iris-setosa
5,5,3.6,1.4,0.2,Iris-setosa
6,5.4,3.9,1.7,0.4,Iris-setosa
7,4.6,3.4,1.4,0.3,Iris-setosa
8,5,3.4,1.5,0.2,Iris-setosa
// Csv.java
package csv;import java.io.BufferedReader;
import java.io.FileReader;public class Csv {public static void main(String[] args) {String filepath = "D:\\CSV文件\\test.csv";String[][] alldata = null;try {// 1. 创建流// 创建FileReader和BufferedReader对象来读取文件内容FileReader filereader = new FileReader(filepath);BufferedReader buffereader = new BufferedReader(filereader);// 当然写在一起也行// BufferedReader buffereader = new BufferedReader(new FileReader(filepath));// 2. 计算文件中的行数int linenumber = 0;while (buffereader.readLine() != null) {linenumber++;}// 3. 将缓冲读取器重置为从文件开头读取filereader = new FileReader(filepath);buffereader = new BufferedReader(filereader);// 4. 用适当的维度初始化AllData数组alldata = new String[linenumber][];// 5. 读取内容,存储到内存(数组、Map或其他数据类型)中。使用split分隔逗号,还可以使用正则表达式进一步处理。String line;linenumber = 0;while ((line = buffereader.readLine()) != null) {// 按逗号分隔每行数据String[] data = line.split(",");// 第一种方式
// if (data.length > 0) {
// // 初始化内部数组
// alldata[linenumber] = new String[data.length];
// // 存入二维字符数组中
// for (int i = 0; i < data.length; i++) {
// alldata[linenumber][i] = data[i];
// }
// }// 第二种方式alldata[linenumber] = data;linenumber++;}// 6. 输出存储数据for (int i = 0; i < linenumber; i++) {System.out.print(alldata[i][0]);for (int j = 1; j < alldata[0].length; j++) {System.out.print(","+alldata[i][j]);}System.out.println();}// 7. 关闭FileReader流和BufferedReader流filereader.close();buffereader.close();} catch (Exception e) {// 处理异常情况e.printStackTrace();}}
}
// 输出
Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
1,5.1,1.4,1.4,0.2,Iris-setosa
2,4.9,3,1.4,0.2,Iris-setosa
3,4.7,3.2,1.3,0.2,Iris-setosa
4,4.6,3.1,1.5,0.2,Iris-setosa
5,5,3.6,1.4,0.2,Iris-setosa
6,5.4,3.9,1.7,0.4,Iris-setosa
7,4.6,3.4,1.4,0.3,Iris-setosa
8,5,3.4,1.5,0.2,Iris-setosa
写入方法
以下为Java中读取CSV文件,写入新CSV文件的方法(读取方法的代码和上面一致,就省略)。
// Csv.java
package csv;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;public class Csv {public static void main(String[] args) {String filepath = "D:\\CSV文件\\test.csv";String[][] alldata = null;try {// 接上面的代码,省略// 1. 创建流// 创建FileWriter和BufferedWriter对象来读取文件内容filepath = "D:\\CSV文件\\test1.csv";FileWriter filewriter = new FileWriter(filepath);BufferedWriter bufferwriter = new BufferedWriter(filewriter);// 当然写在一起也行
// BufferedWriter bufferwriter = new BufferedWriter(new FileWriter(filepath));// 2. 写入新文件for(String[] str:alldata) {String context = str[0];for (int i = 1; i < alldata[0].length; i++) {context = context + "," + str[i];}bufferwriter.write(context);bufferwriter.newLine(); // 换行}// 3. 关闭BufferedWriter流和FileWriter流,顺序不要搞反bufferwriter.close();filewriter.close();} catch (Exception e) {// 处理异常情况e.printStackTrace();}}
}
数据处理
数据处理其实不涉及IO流的知识,更多涉及正则表达式、字符串操作、循环、赋值等知识。
比如寻找最值、计算平均值、提取某个数据等。
正则表达式
匹配整数和小数
// 匹配整数或小数的字符串
// -? 表示可选的负号,匹配一个或零个负号。
// \\d+ 匹配一个或多个数字字符。
// (\\.\\d+)? 表示可选的小数部分,包括一个点号和一个或多个数字字符。
String regex = "-?(0|[1-9]\\d*)(\\.\\d+)?";if (s.matches(regex)) {···
}else {···
}
其他匹配方式欢迎补充
字符串操作
split() 方法分隔逗号
result = s.split(",");
equals() 方法判断字符串是否相等
if (s.equals(num)) {···
}else {···
}
trim() 方法去除字符串两端的空格或指定字符
String s = " 1 23 4 ";
s = s.trim();
System.out.print(s);
// 输出
1 23 4
其他方法欢迎补充
缺值处理
- 使用正则表达式统计出现次数
- 排序后取最大最小值
- 使用平均值、中位数等填充缺失数据
其他方法欢迎补充
练习案例
1. 读取 CSV 文件并按第一列分组计数
// 统计demo.csv
下单,0,a,BCF
付款,0,a,BCF
发货,0,a,BCF
付款,0,a,BCF
收款,0,a,BCF
下单,0,a,BCF
付款,0,a,BCF
// CsvDataGrouping.java
package csv;import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;public class CsvDataGrouping {public static void main(String[] args) {String filepath = "D:\\CSV文件\\统计demo.csv";try {// 创建一个BufferedReader对象来读取文件BufferedReader reader = new BufferedReader(new FileReader(filepath));// 创建一个Map来存储统计结果Map<String, Integer> countMap = new HashMap<>();String line;while ((line = reader.readLine()) != null) {// 按逗号分隔每行数据String[] data = line.split(",");if (data.length > 0) {// 去除首尾空格并取得关键字String key = data[0].trim();// 统计关键字出现次数countMap.put(key, countMap.getOrDefault(key, 0) + 1);}}// 输出统计结果for (Map.Entry<String, Integer> entry : countMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}} catch (Exception e) {// 处理异常情况e.printStackTrace();}}
}
// 输出
下单: 2
收款: 1
发货: 1
付款: 3
代码大致说明
在这段代码中,我们首先定义了一个文件路径 filepath,它指向要读取的CSV文件。然后我们使用 BufferedReader 和 FileReader 来创建一个读取文件的对象 reader。
接下来,我们创建了一个 Map<String, Integer> 类型的对象 countMap,用于统计每个关键字出现的次数。
然后,我们使用 reader.readLine() 逐行读取文件内容,将每一行按逗号分隔成字符串数组 data。如果数组长度大于0,说明该行有数据,我们提取关键字 key。然后使用 countMap.getOrDefault(key, 0) + 1 统计关键字出现的次数,并将结果存入 countMap 中。
最后,我们遍历 countMap 中的键值对,并打印出每个关键字及其出现的次数。
代码详细说明
上述代码是一个Java程序,用于读取指定路径下的CSV文件并统计每个关键字出现的次数。让我们逐步分析代码:
main方法是程序的入口点,使用了public static void修饰符,表示它是一个公共静态方法,不返回任何值,接受一个String类型的数组作为参数。String filepath = "D:\\CSV文件\\统计demo.csv";定义了一个字符串变量filepath,用于存储CSV文件的路径。- 在
try-catch块中,代码通过创建BufferedReader对象来读取文件内容。使用new BufferedReader(new FileReader(filepath)),传入一个FileReader对象,该对象负责读取指定路径下的文件。 - 创建了一个
Map<String, Integer>类型的变量countMap,用于存储统计结果。HashMap类实现了Map接口,可以存储键值对,这里键的类型是String,值的类型是Integer。 - 进入一个
while循环,读取文件的每一行数据,将读取的结果存储在line变量中。循环条件为line = reader.readLine(),当读取到的行不为空时继续循环。 - 在循环中,通过
line.split(",")使用逗号分隔每一行的数据,并将结果存储在data数组中。 - 如果
data数组的长度大于0,表示当前行有数据。代码通过data[0].trim()去除首尾空格并获取关键字,将结果存储在key变量中。 - 通过
countMap.getOrDefault(key, 0)获取countMap中关键字key对应的值,如果不存在则返回默认值0。 - 使用
countMap.put(key, countMap.getOrDefault(key, 0) + 1)将关键字key的出现次数加1,并将结果保存回countMap中。 - 循环结束后,通过遍历
countMap的每个条目,使用entry.getKey()获取关键字,使用entry.getValue()获取关键字出现的次数,并将结果打印到控制台。 - 在
catch块中,代码捕捉并处理可能发生的异常情况,使用e.printStackTrace()打印异常堆栈信息。
总体而言,这段代码读取指定路径下的CSV文件,统计每个关键字出现的次数,并将结果输出到控制台。
2. 读数据的第一行,输出所有的值、最值、指定数值出现的次数
// iris.csv
Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
1,5.1,1.4,1.4,0.2,Iris-setosa
2,4.9,3,1.4,0.2,Iris-setosa
3,4.7,3.2,1.3,0.2,Iris-setosa
4,4.6,3.1,1.5,0.2,Iris-setosa
5,5,3.6,1.4,0.2,Iris-setosa
// IrisData.java
package csv;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;public class IrisData {public static void main(String[] args) {// 创建文件对象,指向要读取的CSV文件File file = new File("D:\\CSV文件\\Iris.csv");String[] result = new String[10];// 匹配整数或小数的字符串// -? 表示可选的负号,匹配一个或零个负号。// \\d+ 匹配一个或多个数字字符。// (\\.\\d+)? 表示可选的小数部分,包括一个点号和一个或多个数字字符。String regex = "-?(0|[1-9]\\d*)(\\.\\d+)?";try {// 创建FileReader和BufferedReader对象来读取文件内容FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);String string;int line = 0;// 逐行读取文件内容while ((string = br.readLine()) != null) {// 当行数为1时,将该行按逗号分割成字符串数组并存储在result中if (line == 1) {result = string.split(",");// 数组拷贝方法。从源数组中指定的范围复制一部分元素到一个新的数组中。// Arrays.copyOfRange(源数组, 起始位置, 终止位置)// 相当于复制下标1->最后的数组给原字符串,同时改变了原数组的长度result = Arrays.copyOfRange(result, 1, result.length);break;}line ++;}br.close();} catch (IOException e) {e.printStackTrace();}// 创建ArrayList对象用于存储符合条件的数字ArrayList<Double> numbers = new ArrayList<>();// 如果34行附近没有对数组进行截取拷贝操作// 则可以调整循环,使其在迭代结果数组时从索引1而不是0开始// 这种方式更为简单粗暴for (int i = 0; i < result.length; i++) {// 判断字符串是否匹配正则表达式,如果匹配则将其转换为Double类型并添加到numbers中if (result[i].matches(regex)) {numbers.add(Double.parseDouble(result[i]));}}// 打印列表中的所有数字for (int i = 0; i < numbers.size(); i++) {System.out.println(numbers.get(i));}// 输出指定数字在列表中出现的次数System.out.println("1.4 出现了 " + getCount(numbers, 1.4) + " 次");// 输出列表中的最大值和最小值System.out.println("max: " + getMaxAndMin(numbers)[0] + "\nmin: " + getMaxAndMin(numbers)[1]);}/*** 统计给定数值在列表中出现的次数** @param numbers 列表* @param num 给定数值* @return 出现次数*/public static int getCount(ArrayList<Double> numbers, Double num) {int count = 0;for (int i = 0; i < numbers.size(); i++) {if (numbers.get(i).equals(num)) {count ++;}}return count;}/*** 获取列表中的最大值和最小值** @param numbers 列表* @return 包含最大值和最小值的数组,索引0为最大值,索引1为最小值*/public static Double[] getMaxAndMin(ArrayList<Double> numbers) {Double[] max = {numbers.get(0), numbers.get(0)};for (int i = 0; i < numbers.size(); i++) {if (numbers.get(i) > max[0]) {max[0] = numbers.get(i);}if (numbers.get(i) < max[1]) {max[1] = numbers.get(i);}}return max;}
}
// 输出
5.1
1.4
1.4
0.2
1.4 出现了 2 次
max: 5.1
min: 0.2
代码大致说明
这段代码读取一个CSV文件,并对文件中的数据进行分析。首先,它读取文件的第二行数据(索引为1),将该行按逗号分割成字符串数组 result,copyOfRange() 方法用于排除第一个元素,它表示ID列。然后存储在 numbers 列表中的元素必须满足正则表达式 regex 的匹配条件(即匹配一个浮点数),才会被添加到 numbers 列表中。
接下来,它使用两个辅助方法 getCount 和 getMaxAndMin 分别计算列表中指定数值出现的次数,以及列表中的最大值和最小值。
在 getCount 方法中,它遍历列表中的元素,如果元素与给定的数值相等,则计数器 count 自增。
在 getMaxAndMin 方法中,它首先将列表的第一个元素作为最大值和最小值的初始值。然后遍历列表中的元素,如果当前元素大于最大值,则更新最大值;如果当前元素小于最小值,则更新最小值。最后,它返回一个包含最大值和最小值的数组。
最后,它打印出列表中的所有数值,以及给定数值 1.4 在列表中出现的次数,以及列表中的最大值和最小值。
代码详细说明
给定的代码是一个Java程序,它从名为"Iris.csv"的CSV文件中读取数据,并对数据执行一些操作。让我们逐步分析代码:
- 代码开始导入必要的类和包。
- 定义了
IrisData类,其中包含程序执行开始的主方法。 - 创建了一个
File对象来表示CSV文件的位置。 - 初始化了一个字符串数组
result,长度为10。该数组将存储从CSV文件中提取的值。 - 定义了一个正则表达式模式
regex,用于匹配整数或小数字符串。 - 在try-catch块内,创建了
FileReader和BufferedReader来读取文件内容。 - 代码进入一个循环,使用
BufferedReader的readLine()方法逐行读取文件内容。 - 当行号为1时(行号从0开始),代码使用逗号分隔符拆分行,并将结果数组存储在
result变量中。使用Arrays.copyOfRange()方法来排除第一个元素,该元素表示ID列。 - 循环在读取第一行后中断。
- 关闭
BufferedReader以释放系统资源。 - 创建一个名为
numbers的ArrayList<Double>,用于存储从result数组中提取的数字。 - 循环遍历
result数组,检查每个元素是否与正则表达式模式匹配。如果找到匹配项,将元素转换为Double值并添加到numbers列表中。 - 另一个循环用于打印
numbers列表中的所有数字。 - 程序调用
getCount()方法,将numbers列表和值1.4作为参数传递,并打印1.4在列表中出现的次数。 - 程序调用
getMaxAndMin()方法,将numbers列表作为参数传递,并打印列表中的最大值和最小值。 getCount()方法接受一个ArrayList<Double>和一个Double值作为参数,在列表中计算给定值出现的次数。getMaxAndMin()方法接受一个ArrayList<Double>作为参数,并返回一个包含列表中最大值和最小值的数组。
总体而言,该代码读取CSV文件,从特定行提取数值,将其存储在一个列表中,并执行一些操作,如计数出现次数和查找最大值和最小值。
3. 读第三个字段的所有值,输出所有的值、最值、指定数值出现的次数
其实就是读第三列的所有值,输出所有的值、最值、指定数值出现的次数。
CSV文件和上一题一样,省略
读文件方式和上一题差不多,省略相同代码,其实也就只是处理时稍微不一样而已
// 逐行读取文件内容
while ((string = br.readLine()) != null) {// 当行数大于0时,将该行按逗号分割成字符串数组并存储在result中if (line > 0) {String[] r = string.split(",");// 题目要求读第三列的所有值,即下标2的值result[line-1] = r[2];}line ++;
}
// 数组拷贝方法。从源数组中指定的范围复制一部分元素到一个新的数组中。
// Arrays.copyOfRange(源数组, 起始位置, 终止位置)
// 相当于复制下标1->最后的数组给原字符串,同时改变了原数组的长度
result = Arrays.copyOfRange(result, 0, line-1);br.close();
代码大致说明
这段代码读取一个CSV文件的行,跳过标题行,将每行按逗号分割,并将第三列的值存储在 result 数组中。然后,数组被重新调整大小以删除未使用的元素,并且关闭了 BufferedReader。
代码详细说明
while循环使用br.readLine()逐行读取文件的内容,并将其赋值给变量string。- 条件
string = br.readLine()检查string是否不为空,这意味着仍有待读取的行。 - 在循环内部,代码检查
line是否大于 0。这确保跳过标题行(第 0 行),只处理数据行。 - 如果
line大于 0,则代码使用逗号(,)分隔string,通过string.split(",")得到一个值的数组。 - 将
r数组中索引为 2 的值(表示第三列)赋值给result数组的相应索引(result[line-1] = r[2])。 - 处理完每一行后,递增
line变量的值。 - 一旦所有行都被处理完,代码使用
Arrays.copyOfRange()方法创建一个名为result的新数组,它的长度更小。 Arrays.copyOfRange()方法从源数组中创建一个新数组,从指定的起始索引(0)开始,到指定的结束索引(line-1)结束。这有效地删除了result数组中未使用的元素。- 更新后的
result数组被重新赋值给result变量。 - 最后,代码关闭了
BufferedReader,以释放系统资源。
参考资料
b站视频
1分钟学java:统计csv文件中的数据:https://www.bilibili.com/video/BV1zX4y1Y7PJ
CSDN文章
java 操作文件及问题解决(csv):https://blog.csdn.net/weixin_43763430/article/details/125346370
致谢
感谢群成员 @电子鬼会吓到仿生人吗 提供的 部分代码 和 CSV文件
相关文章:
《Java面向对象程序设计》学习笔记——CSV文件的读写与处理
笔记汇总:《Java面向对象程序设计》学习笔记 笔记记录的不是非常详实,如果有补充的建议或纠错,请踊跃评论留言!!! 什么是CSV文件 CSV文件的定义 CSV 是英文 comma-separated values 的缩写࿰…...
opencv 案例05-基于二值图像分析(简单缺陷检测)
缺陷检测,分为两个部分,一个部分是提取指定的轮廓,第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分,学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换…...
Elasticsearch入门介绍
应用场景 1 它提供了强大的搜索功能,可以实现类似百度、谷歌等搜索。 2 可以搜索日志或者交易数据,用来分析商业趋势、搜集日志、分析系统瓶颈或者运行发展等等 3 可以提供预警功能(持续的查询分析某个数据,如果超过一定的值&a…...
QML Book 学习基础3(动画)
目录 主要动画元素 例子: 非线性动画 分组动画 Qt 动画是一种在 Qt 框架下创建交互式和引人入胜的图形用户界面的方法,我们可以认为是对某个基础元素的多个设置 主要动画元素 PropertyAnimation-属性值变化时的动画 NumberA…...
Lesson4-3:OpenCV图像特征提取与描述---SIFT/SURF算法
学习目标 理解 S I F T / S U R F SIFT/SURF SIFT/SURF算法的原理,能够使用 S I F T / S U R F SIFT/SURF SIFT/SURF进行关键点的检测 SIFT/SURF算法 1.1 SIFT原理 前面两节我们介绍了 H a r r i s Harris Harris和 S h i − T o m a s i Shi-Tomasi Shi−Tomasi…...
语言基础篇9——Python流程控制
流程控制 顺序结构、条件结构、循环结构,顺序结构由自上而下的语句构成,条件结构由if、match-case构成,循环结构由for、while构成。 if语句 flag 1 if flag 1:print("A") elif flag 2:print("B") else:print("…...
MATLAB算法实战应用案例精讲-【概念篇】构建数据指标方法(补充篇)
目录 前言 几个高频面试题目 指标与标签的区别 几个相关概念 数据域 业务过程...
【pyqt5界面化工具开发-12】QtDesigner图形化界面设计
目录 0x00 前言 一、启动程序 二、基础的使用 三、保存布局文件 四、加载UI文件 0x00 前言 关于QtDesigner工具的配置等步骤(网上链接也比较多) 下列链接非本人的(如果使用pip 在命令行安装过pyqt5以及tools,那么就可以跳过…...
CXL.mem S2M Message 释义
🔥点击查看精选 CXL 系列文章🔥 🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥 📢 声明: 🥭 作者主页:【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN,…...
设计模式—外观模式(Facade)
目录 一、什么是外观模式? 二、外观模式具有什么优点吗? 三、外观模式具有什么缺点呢? 四、什么时候使用外观模式? 五、代码展示 ①、股民炒股代码 ②、投资基金代码 ③外观模式 思维导图 一、什么是外观模式?…...
Stack Overflow开发者调查发布:AI将如何协助DevOps
Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1]。报告对 90,000 多名开发人员进行了调查,全面展示了当前软件开发人员的体验。接下来,本文将重点介绍几项重要发现,即重要编程语言和工具偏好、人工智能在开发工作流程中的应用以及…...
去掉鼠标系列之二:Sublime Text快捷键使用指南
系列之二,Sublime Text。 Sublime Text 是我们常用的文本工具,常常要沉浸如其中使用,而不希望被鼠标打扰,所以也记录一下。 学会下面这些快捷键,基本上就不需要移动鼠标啦。 1,CtrlK,CtrlV …...
docker-compose安装node-exporter, prometheus, grafana
基础 exporter提供监控数据 prometheus拉取监控数据 grafana可视化监控数据 准备 全部操作在/root/mypromethus中执行 node_exporter docker-compose -f node-exporter.yaml up -d # web访问,查看node_exporter采集到的数据 http://192.168.1.102:9101/metrics…...
企业架构LNMP学习笔记10
1、Nginx版本,在实际的业务场景中,需要使用软件新版本的功能、特性。就需要对原有软件进行升级或重装系统。 Nginx的版本需要升级迭代。那么如何进行升级呢?线上服务器如何升级,我们选择稳定版本。 从nginx的1.14版本升级到ngin…...
[国产MCU]-W801开发实例-I2C控制器
I2C控制器 文章目录 I2C控制器1、I2C控制器介绍2、I2C驱动API2、I2C简单使用示例1、I2C控制器介绍 I2C总线是一种简单、双向二线同步串口总线。I2C总线设备之间通信只需两根线即可完成设备之间的数据传输。 I2C总线设备分为主机和从机,这取决于数据传输方向。I2C总线上的主机…...
植物根系基因组与数据分析
1.背景 这段内容主要是关于植物对干旱胁迫的反应,并介绍了生活在植物体内外以及根际的真菌和细菌的作用。然而,目前对这些真菌和细菌的稳定性了解甚少。作者通过调查微生物群落组成和微生物相关性的方法,对农业系统中真菌和细菌对干旱的抗性…...
2.3 数据模型
思维导图: 前言: 我的理解: 这段话介绍了概念模型和数据模型之间的关系,以及数据模型的定义和重要性。具体解读如下: 1. **概念模型**:它是一种描述现实世界数据关系的抽象模型,不依赖于任何…...
RT-Thread 中断管理学习(一)
中断管理 什么是中断?简单的解释就是系统正在处理某一个正常事件,忽然被另一个需要马上处理的紧急事件打断,系统转而处理这个紧急事件,待处理完毕,再恢复运行刚才被打断的事件。生活中,我们经常会遇到这样…...
学习周报9.3
文章目录 前言文献阅读一摘要挑战基于时间序列的 GAN 分类 文献阅读二摘要介绍提出的模型:时间序列GAN (TimeGAN) 代码学习总结 前言 本周阅读两篇文献,文献一是一篇时序生成方面的综述,主要了解基于时间序列 的GAN主要分类以及时间序列GAN方面面临的一…...
win10 查看指定进程名的端口号
在 Windows 10 的任务管理器中也可以查看端口号。请按下面的步骤操作: 打开任务管理器,可以通过按下快捷键 CtrlShiftEsc 或者右键点击任务栏后选择任务管理器来打开。点击“性能”选项卡,然后点击左侧的“打开资源监视器”。在资源监视器中…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...
echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式
pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图,如果边框加在dom上面,pdf-lib导出svg的时候并不会导出边框,所以只能在echarts图上面加边框 grid的边框是在图里…...
