【JavaEE精炼宝库】文件操作(2)——文件内容读写 | IO流
文章目录
- 一、输入流
- 1.1 InputStream 概述:
- 1.2 read 方法详解:
- 1.3 close 方法:
- 1.4 利用 Scanner 进行读操作:
- 1.5 Reader:
- 二、输出流
- 2.1 OutputStream 概述:
- 2.2 write 方法详解:
- 2.3 利用 PrintWriter 进行写操作:
- 三、小程序练习
- 3.1 程序1:
- 3.2 程序2:
- 3.3 程序3:
在上一篇文章主要讲述了 Java 针对文件系统进行操作(创建文件,删除文件,创建目录,重命名文件)。本文章是上一篇文章的续集,主要讲述 Java 针对文件内容进行操作(读文件,写文件)。
读写操作就涉及到流的概念,Java 中通过 ‘流’(stream)这样的一组类,进行上述的文件内容操作。
主要分为输入流(InputStream)和输出流(OutputStream)这两类。
一、输入流
说明:InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用 FileInputStream。
1.1 InputStream 概述:
- 方法:
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
int | read() | 读取一个字节的数据,返回 -1 代表已经完全读完了。 |
int | read(byte[] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量。-1 代表已经读完了。 |
int | read(byte[] b, int off, int len) | 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量。-1 代表已经读完了。 |
void | close() | 关闭字节流。 |
- 构造方法:
签名 | 说明 |
---|---|
FileInputStream(File file) | 利用 File 构造文件输入流 |
FileInputStream(String name) | 利用文件路径构造文件输入流 |
1.2 read 方法详解:
不难看到 read 方法有 3 种使用的版本,接下来我会分别给大家演示前两种(第 3 种就是第 2 种加上起点),并进行讲解。
- 版本一:无参数,一次读取一个字节。读取到的内容,就通过返回值来进行表示。
注意:这里的返回值是 int 类型,这是为什么呢?既然一次读取一个字节,返回值不是 byte 就行了?
答:注意有以下三个原因:
- 为了能够有额外的空间表示 “到达末尾” -1 这样的情况。
- 确保读取到的数据都是正数:从原则上来说,“字节” 这样的概念,本身就是 “无符号”,但是 byte 是带有符号的,使用 int 就可以确保读取出来的字节都是正数。按照 “无符号”的方式来处理了。
- 为什么不使用
short
,而是使用int
?答:虽然使用 int 较 short 是浪费了 2 个字节。但是还是不建议使用 short 类型,这个类型随着硬件的升级,正在逐渐被取代。对于 32 位 CPU,一次处理 4 个字节的数据,使用 short,操作系统内部还是要把 short 转化成 int 来处理,32 位 CPU 如此,对于 64 位 CPU,short 就更加没有意义了。
案例演示:
关于为什么 inputStream 的创建为什么能和为什么要写在try()里面,在后面会有详细解释,这里主要看 read 的使用。
import java.io.*;
public class demo2 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./text.txt")){//推荐这样的写法。while(true){int n = inputStream.read();if(n == -1) break;System.out.printf("0x%x ",n);//按照十六进制打印}}}
}
案例演示结果:
- 版本二:带有一个参数 byte[]。
版本二和版本一的返回值的含义不太一样,具体差别如下:版本二的返回值代表读入 byte 数组的长度,如果返回 -1 表示读取完毕。 这个写法在 Java 中不太常见,这是一种属于 C++
式的写法。用参数来作为函数的返回结果(输出型参数)。
一次读取多少,取决于数组的长度和文件内容多少,read 会尽可能把数组填满。
案例演示:
import java.io.*;
public class demo3 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./text.txt")){byte[] bytes = new byte[1024];int n = 0;while(true){n = inputStream.read(bytes);if(n == -1) break;for(int i = 0;i < n;i++){System.out.printf("0x%x ",bytes[i]);}}}}
}
案例演示结果:
将文件完全读完的两种方式。相比较而言,后一种的 IO 次数更少,性能更好。
1.3 close 方法:
关闭文件是一个非常关键的操作。
为什么要关闭文件?
答:没关闭文件大部分情况下我们是感知不到的,但是一旦出现问题,就是大事(能击碎年终奖😭)。在打开文件的时候,会在操作系统内核,PCB 结构体(进程)中给“文件描述符表(长度存在上限,并且不能自动扩容)”添加一个元素,这个元素就是表示当前打开文件的相关信息。一旦占满了之后,再尝试打开,就会打开文件失败。(其他的操作,网络通信相关的操作就可能收到影响)。
inputStream.close();
上面的这种写法是一般的关闭文件的方式。但是这样写不太好,因为如果代码前面出现异常或者 return,此时 close 就执行不到了。虽然使用 try finally 可以解决问题,但是写出来的代码不太优化。
try(){........
}finally{inputStream.close();
}
对于老程序猿来说代码是语文,要追求优雅。于是 Java 实现了把流对象的创建写到 try()里,代码执行出了 try{}时,就会自动调用 inputStream
的 close
了。
写法如下:
try(InputStream inputStream = new FileInputStream("./text.txt"))
要抛异常(这里没写)。
注意:务必要实现 Closeable 接口的类,才能够放到 try() 里。
1.4 利用 Scanner 进行读操作:
上述栗子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该共作,就是 Scanner
类。
构造方法 | 说明 |
---|---|
Scanner(InputStream is) | 构造一个新的 Scanner ,产生从指定输入流扫描的值。 |
Scanner(InputStream is, String charset) | 构造一个新的 Scanner ,产生从指定输入流扫描的值。使用 charset 字符集进行 is 的扫描读取。 |
示例如下:
public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("./text.txt")){try(Scanner in = new Scanner(inputStream)){}}}
1.5 Reader:
以字符为单位读取数据,在 InputStream 中,虽然可以通过 Scanner 传入字符集来达到读取字符的效果,但是这种办法并不是通用的。我们更推荐使用 Reader 来实现读取字符。
由于 Reader 的使用方法和 InputStream 类的使用方式基本一致,所以这里只叙述 read 方法。
注意:这里传入的是 char
类型的数组,这样就有足够的内存来保存字符了。
由于写法基本一样,这里就演示版本二(带字符数组)。
import java.io.*;
public class demo2 {public static void main(String[] args) throws IOException {try(Reader reader = new FileReader("./text.txt")){char[] chars = new char[1024];while(true){int n = reader.read(chars);if(n == -1) break;for(int i = 0;i < n;i++){System.out.print(chars[i]);}}}}
}
演示结果如下:
二、输出流
说明:OutputStream 只是一个抽象类,要使用还需要具体的实现类。关于 OutputStream 的实现类有很多,基本可以认为不同的输出设备都可以对应一个 OutputStream 类,我们现在只关心写文件,所以使用 FileOutputStream。
2.1 OutputStream 概述:
- 方法:
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
void | write(int b) | 将指定的字节写入此输出流。 |
void | write(byte[] b) | 将 b.length 字节从指定的字节数组写入此输出流。 |
int | write(byte[] b,int off,int len) | 从指定的字节数组写入 len 个字节,从偏移 off 开始输出到此输出流。 |
void | close() | 关闭此输出流并释放与此流相关联的任何系统资源。 |
void | flush() | 刷新此输出流并强制任何缓冲的输出字节被写出。 |
解释一下 flush
:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream
为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区
。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后
或者合适
的位置,调用flush
(刷新)操作,将数据刷到设备中。
- 构造方法:
构造方法 | 说明 |
---|---|
FileOutputStream(String name) | 创建文件输出流,以指定的名称写入文件 |
FileOutputStream(String name,boolean append) | 创建文件输出流,以指定的名称是否追加写入文件。 |
注意:在使用 FileOutputStream 创建指定文件对象的时候,如果不在文件名后面加上 true
,原有的文件内容会被清空,如果加上 true
就是在原文件内容上追加写。
案例如下:
执行完try(OutputStream outputStream = new FileOutputStream("./text.txt"))
后变成:
2.2 write 方法详解:
和 read 一样有三种版本,并且没有返回值,这里就只演示版本二(带byte 数组)。
- 版本二:一次 write 若干字节。会把参数数组里所有的字节都写入文件中。
代码案例如下:
public class demo5 {public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./text.txt")){byte[] bytes = new byte[4];for(int i = 0;i < 4;i++){bytes[i] = (byte)(97 + i);//对应是字符 abcd}outputStream.write(bytes);outputStream.flush();//不要忘记,flush 刷新缓存}}
}
案例演示结果:
2.3 利用 PrintWriter 进行写操作:
注意:OutputStream
也有 close
操作,这里没有单独写,是因为使用和注意点都一样。
上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用 PrintWriter 类来完成输出,因为 PrintWriter 类中提供了我们熟悉的 print/println/printf 方法。
案例演示如下:
public class demo6 {public static void main(String[] args) throws IOException {try(OutputStream outputStream = new FileOutputStream("./text.txt")){try(PrintWriter printWriter = new PrintWriter(outputStream)){printWriter.print("abcd");printWriter.flush();}}}
}
案例演示结果:
还有一个对应的字符写类 Writer 使用的方法是一样的,就不再赘述了。
三、小程序练习
我们学会了文件的基本操作 + 文件内容读写操作,接下来,我们实现一些小工具程序,来锻炼我们的能力。
3.1 程序1:
- 程序要求:扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件。
步骤如下:
- 提示用户输入
- 找到名称包含指定字符的所有普通文件
- 是否删除
源码如下(有详细注释):
import java.io.*;
import java.util.*;//扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否
//要删除该⽂件
public class demo1 {static Scanner in = new Scanner(System.in);public static void main(String[] args) {//1提示用户输入System.out.println("请输入要查找的文件目录:");String dirName = in.next();List<File> result = new ArrayList<>();//2找到名称包含指定字符的所有普通文件File file = new File(dirName);//判断输入是否合法if(!file.isDirectory()){System.out.println("输入的目录不存在");return;}System.out.println("请输入要查找的指定字符:");String searchWord = in.next();searchFile(file,searchWord,result);System.out.println("一共找到了" + result.size() + "种结果");for(int i = 0;i < result.size();i++){System.out.println((i + 1) + "号:" + result.get(i).getAbsolutePath());}List<Integer> list = new ArrayList<>();//存储用来删除的下标System.out.println("请输入要删除第几号文件(输入0停止删除):");int y = in.nextInt();while(y != 0){y--;if(!result.get(y).exists()){System.out.println("已经被删除过来");}else{result.get(y).delete();System.out.println("删除成功");}y = in.nextInt();}}//查找目录底下的所有文件public static void searchFile(File file,String searchWord,List<File> result){if(file == null) return;//递归出口File[] files = file.listFiles();//返回目录底下的文件for(int i = 0;i < files.length;i++){if(files[i].isDirectory()){//目录的情况searchFile(files[i],searchWord,result);}else{//走到这里说明是普通文件//找文件名字是否包含关键字if(searchWord(files[i],searchWord)){//包含关键字的情况result.add(files[i]);}}}}//查找文件名是否包含关键字private static boolean searchWord(File file, String searchWord) {String fileName = file.getName();return fileName.contains(searchWord);}
}
程序运行结果如下:可以在电脑上单独创建一个文件夹来测试。
3.2 程序2:
- 程序要求:进行普通文件的复制。
步骤如下:
- 提示用户输入
- 检查输入是否合法
- 进行复制
源码如下:
import java.util.*;
import java.io.*;//进⾏普通⽂件的复制
public class demo1 {public static void main(String[] args) throws IOException {Scanner in = new Scanner(System.in);//1.提示读入System.out.println("请输入要复制的文件");String srcFileRoot = in.next();//检查输入是否合法File srcFile = new File(srcFileRoot);if (!srcFile.isFile()) {System.out.println("输入的不是普通文件路径");return;}//已经是文件了System.out.println("请输入要复制到的文件路径");String destFileRoot = in.next();File destFile = new File(destFileRoot);//检查输入是否合法if (destFile.isDirectory()) {System.out.println("输入的不是普通文件(路径)");return;}//进行复制copyFile(srcFile, destFile);System.out.println("复制完毕");}//复制文件public static void copyFile(File srcFile, File destFile) throws IOException {try (InputStream inputStream = new FileInputStream(srcFile)) {try (OutputStream outputStream = new FileOutputStream(destFile)) {byte[] bytes = new byte[1024];while (true) {int n = inputStream.read(bytes);if (n == -1) break;outputStream.write(bytes, 0, n);//起点和要复制的长度}outputStream.flush();}}}
}
程序运行结果如下:
3.3 程序3:
- 程序要求:扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)。
步骤如下:
- 提示读入数据
- 检查输入是否合法
- 查找指定文件
源码如下:
//案例三
//目的:扫描指定⽬录,并找到内容中包含指定字符的所有普通⽂件(不包含⽬录)
import java.util.*;
import java.io.*;
public class demo2 {public static void main(String[] args) {Scanner in = new Scanner(System.in);//提示读入数据System.out.println("请输入要搜索的目录:");String dirRoot = in.next();File dirFile = new File(dirRoot);if(!dirFile.isDirectory()){System.out.println("目录输入错误");return;}System.out.println("请输入要查找的指定内容");String serWord = in.next();//查找指定文件searchFile(dirFile,serWord);}private static void searchFile(File dirFile,String serWord) {File[] files = dirFile.listFiles();//这里不用判断为空for(int i = 0;i < files.length;i++){if(files[i].isFile()){//查找指定内容searchWord(files[i],serWord);}else if(files[i].isDirectory()){//递归进行查找searchFile(files[i],serWord);}}}private static void searchWord(File file, String serWord) {//查找文件内容StringBuilder sd = new StringBuilder();try(InputStream inputStream = new FileInputStream(file)){//读取数据while(true){int n = inputStream.read();if(n == -1) break;sd.append((char)n);}if(sd.indexOf(serWord) >= 0){//找到了System.out.println("文件路径为:" + file.getAbsolutePath());}} catch (IOException e) {throw new RuntimeException(e);}}
}
程序运行结果如下:
结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。
相关文章:

【JavaEE精炼宝库】文件操作(2)——文件内容读写 | IO流
文章目录 一、输入流1.1 InputStream 概述:1.2 read 方法详解:1.3 close 方法:1.4 利用 Scanner 进行读操作:1.5 Reader: 二、输出流2.1 OutputStream 概述:2.2 write 方法详解:2.3 利用 PrintW…...

C++ 指针变量做参数传递时的情况分析
前言 指针变量作为参数传递时,很容易混淆指针本身和指针指向的内容,实际应用中可能会导致无法预料的问题,所以做一下详细分析。 注意,在测试过程中为了看测试效果,有些指针变量分配了空间,但是未做回收&am…...

Linux环境下Oracle 11g的离线安装与配置历程
在成功体验了 Windows 版本的Oracle 11g 后,这几天心血来潮,决定再挑战一下Linux 环境下的安装,特别是在考虑到部门内部虚拟机无法联网的情况下,我选择了在CentOS 7上进行离线安装。这次安装之旅,主要参考了下面大佬的…...

上位机图像处理和嵌入式模块部署(mcu项目2:串口日志记录器)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 淘宝上面有一个商品蛮好玩的,那就是日志记录器。说是记录器,其实就是一个模块,这个模块的输入是一个ttl串口&am…...

容器是线程不安全的,如果多线程下不加锁直接使用容器会发什么
可能存在的问题 数据竞争 当两个或多个线程同时读写同一个容器且至少有一个线程在写时,会导致数据竞争。这种情况下,容器的内部状态可能会被破坏,从而导致未定义行为。这些未定义的行为包括数据损坏,程序崩溃,以及无…...

配置光源——笔记
一、灯光的类型 (一)Directional Light(定向光) 1、只改变方向变化,不记录位置变化 2、相当于太阳光 3、室外一般使用 (二)Spot 聚光灯:昏暗(凌晨或傍晚),有一个光斑…...

Java---SpringBoot详解一
人性本善亦本恶, 喜怒哀乐显真情。 寒冬暖夏皆有道, 善恶终归一念间。 善念慈悲天下广, 恶行自缚梦难安。 人心如镜自省照, 善恶分明照乾坤。 目录 一,入门程序 ①,创建springboot工程&#…...

MFC扩展库BCGControlBar Pro v35.0 - 可视化管理主题等全新升级
BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中,并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.0已全新发布了,这个版本改进类Visual Studio 2022的视觉主题、增强对多个…...

Springboot 配置 log4j2 时的注意事项
感谢博主 https://www.cnblogs.com/fishlittle/p/17950944 依赖 SpringBoot 的 spring-boot-starter/ spring-boot-starter-web 自带的是 logback 日志,若要使用 log4j2 日志,需要引入对应依赖。logback 日志和 log4j2 日志都是对 slf4j 门面的实现&am…...

微服务-初级篇
微服务-初级篇 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务 SpringCloud2.1 了解2.2 服务拆分原则2.3 服务拆分效果 Nacos注册中心3.1 认识和安装Nacos3.1.1 Nacos下载3.1.2 Nacos安装 3.2 服务注册到Nacos Feign远程调用4.1 Feign引入4.2 Feign配置 认识微服务 1.1 单体…...

批量制作word表格
问题背景 将excel表中的成绩内容制作为成绩单,每页对应一个学员的成绩,方便打印 代码实现 ## 导入包 import pandas as pd from docx import Document from docx.enum.text import WD_ALIGN_PARAGRAPH,WD_LINE_SPACING# 读取 Excel 内容 df pd.read_e…...

代码随想录算法训练营:27/60
非科班学习算法day27 | LeetCode455:分发饼干 ,Leetcode376:摆动序列 ,Leetcode53:最大子数组和 介绍 包含LC的两道题目,还有相应概念的补充。 相关图解和更多版本: 代码随想录 (programmercarl.com)https://programmercarl.c…...

Redis 中String类型操作命令(命令演示,时间复杂度,返回值,注意事项)
String 类型 文章目录 String 类型set 命令get 命令mset 命令mget 命令get 和 mget 的区别incr 命令incrby 命令decr 命令decrby 命令incrbyfloat 命令append 命令getrange 命令setrange 命令 字符串类型是 Redis 中最基础的数据类型,在讲解命令之前,我们…...

2024亚太杯中文赛B题洪水灾害的数据分析与预测原创论文分享
大家好,从昨天肝到现在,终于完成了2024年第十四届 APMCM 亚太地区大学生数学建模竞赛B题洪水灾害的数据分析与预测的完整论文啦。 实在精力有限,具体的讲解大家可以去讲解视频: 2024亚太杯中文赛B题洪水灾害预测原创论文保姆级教…...

Oracle 19c 统一审计表清理
zabbix 收到SYSAUX表空间告警超过90%告警,最后面给出的清理方法只适合ORACLE 统一审计表的清理,传统审计表的清理SYS.AUD$不适合,请注意。 SQL> Col tablespace_name for a30 Col used_pct for a10 Set line 120 pages 120 select total.…...

PostgreSQL(二十二)缓冲区管理器
目录 一、缓冲区概述 1、缓冲区结构 2、buffer_tag结构 3、Backend进程读取操作 4、写脏块 二、缓冲区管理器结构 1、第一层:Buffer Table layer(缓冲区表层) 2、第二层:Buffer Descriptor Layer(缓冲区描述层…...

流程制造业与离散制造业有何差异?流程行业智能制造关注什么?
在当今快速发展的工业领域,智能制造已经成为推动制造业转型升级的关键力量。随着“工业4.0”概念的提出,智能制造的理念和技术被广泛应用于各个制造行业,包括离散制造业和流程制造业。尽管智能制造的起源和发展在很大程度上受到了离散制造业的…...

【论文速读】《面向深度学习的联合消息传递与自编码器》,无线AI的挑战和解决思路
这篇文章来自华为的渥太华无线先进系统能力中心和无线技术实验室,作者中有大名鼎鼎的童文。 一、自编码架构的全局收发机面临的主要问题 文章对我比较有启发的地方,是提到自编码架构的全局收发机面临的主要问题: 问题一:基于随…...

C++从入门到起飞之——输入输出!
目录 1.命名空间 1.1namespace的价值 1.2namespace的定义 1.3命名空间使⽤ 2.C输⼊&输出 3.完结散花 个人主页:秋风起,再归来~ C从入门到起飞 个人格言:悟已往之不谏,知来者犹可追 克心守己…...

米文AD10配置gmsl摄像头操作
一、进入桌面快捷方式 0、设置摄像头型号 miivii_websettings.desktop 设置摄像头 1、获取camera信息 cat /var/log/gmsl_camera.lognvidiamiivii-tegra:~$ cat /var/log/gmsl_camera.log attestationVerify [13] succeed. [INFO ]: miivii gmsl service start! [INFO ]: V…...

【Selenium配置】WebDriver安装浏览器驱动(ChromeEdge)
【Selenium配置】WebDriver安装浏览器驱动(Chrome&Edge) 文章目录 【Selenium配置】WebDriver安装浏览器驱动(Chrome&Edge)Chrome确认Chrome版本下载对应driver把解压后的chromedriver文件放在chrome安装目录下࿰…...

预测算法面试
这次面试的是一个预测算法的岗位。虽然我对供应链相关的预测很厌烦了,但是这个不是供应链领域的,感觉应该还好。 首先在介绍工作经历和项目部分,这次面试没有上来没有条理乱说一气,而是预测目标、算法架构、各种使用特征这些分层…...

号称世界上第一个开源实时翻译的 App,微软开源GraphRAG:极大增强大模型问答、摘要、推理,以及开源基于ChatGPT的超级文本代码智能体(附代码地址)
号称世界上第一个开源实时翻译的 App,微软开源GraphRAG:极大增强大模型问答、摘要、推理,以及开源基于ChatGPT的超级文本代码智能体(附代码地址) 在「端侧」上实现可离线的「实时同传」翻译,支持 29 语言的…...

PyTorch 2-深度学习-模块
PyTorch 2-深度学习-模块 一: pytorch1> pytorch 介绍2> pytorch 作用3> pytorch 优点4> pytorch 流程二:pytorch 模块1> torch.Tensor 模块2> torch.nn模块3> torch.nn.function模块4> torch.random模块5> torch.onnx模块6> torch.sparse模块7…...

【MyBatis】MyBatis 理论 40 问(二)
《MyBatis 理论 40 问》包含以下 2 篇文章: MyBatis 理论 40 问(一)MyBatis 理论 40 问(二) MyBatis 理论 40 问(二) 21.如何获取生成的主键?22.当实体类中的属性名和表中的字段名不…...

数据分析——Python网络爬虫(三){爬虫基本原理}
爬虫基本原理 爬虫基本流程拉取什么数据JavaScript渲染页面cookies爬虫代理检查robots.txt爬虫的攻与防 爬虫基本流程 • 获取网页源代码:通过库来实现,urllib,requests等实现http请求 • 提取信息:分析网页源代码࿰…...

Linux 忘记root密码,通过单用户模式修改
银河麒麟桌面操作系统 V10(sp1)”忘记用户密码,需要修改用户密码所写,可用于 X86 架构和 arm 架构。 2. 选择第一项,在上图界面按“e”键进行编辑修改。 3. 在以 linux 开头这行的行末,添加“init/bin/bas…...

安卓热门面试题二
什么是AndroidManifest.xml文件?它包含了哪些重要信息? AndroidManifest.xml文件是Android应用程序的全局配置文件,每个Android应用程序的根目录中都必须包含一个AndroidManifest.xml文件,且文件名不能修改。这个文件对于Android…...

agents 分类
一、分类 自动agent、半自动agent、领域、自定义sop和支持人为干预的agent。 先泼个冷水,目前这些agent项目都是实验品,发展还没有做知识库问答相关开源项目那么成熟, 二、全自动agent autoGPT、loopGPT、babyAGI 全自动agent就是人类不可…...

【期末考试复习】概率论与数理统计(知识点模式 - 复习题2)
题目: 设随机变量 X X X 的概率密度函数为 f ( x ) a b x f(x) a bx f(x)abx,其中 0 < x ≤ 1 0 < x \leq 1 0<x≤1; f ( x ) 0 f(x) 0 f(x)0,在其他情况下。已知 P ( X ≤ 1 / 2 ) 3 / 8 P(X \leq 1/2) 3/…...