Java进阶-IO(1)

news2024/11/16 1:20:50

进入java IO部分的学习,首先学习IO基础,内容如下。需要了解流的概念、分类还有其他一些如集合与文件的转换,字符编码问题等,这次先学到字节流的读写数据,剩余下次学完。
在这里插入图片描述

一、IO基础

1、背景

1.1 数据存储问题

变量、数组、对象和集合中存储的数据是暂时存在的,一旦程序结束它们就会丢失。

解决:为了永久保存程序创建的数据,需要将其保存到磁盘文件中。

1.2 流与IO

1)流
是一种抽象概念,是对数据传输的总称。即数据在设备间的传输称为流,流的本质是数据传输

  • Java 中所有数据都是用流读写的。
  • 流是一组有序的数据序列(以输入流的形式获取,输出流的形式输出),将数据从一个地方带到另一个地方。(可类比水管里水的流动)
    • 输入:将数据从各种输入设备(包括文件、键盘等)中读取到内存中
    • 输出:将数据写入到各种输出设备(比如文件、显示器、磁盘等)
  • 流相关的类都封装在 java.io 包中,且每个数据流都是一个对象。

可分为输入和输出两种模式

输入流:文件、网络、数据库及其他数据源—(输入流)—>目的地
输出流:源—(输出流)—>文件、网络、数据库及其他数据源

2)Java 的 I/O(输入/输出)技术
作用:处理设备间数据传输问题

将数据保存到文本文件和二进制文件中, 以达到永久保存数据的要求。常见应用:文件复制;文件上传;文件下载

2、流的分类

2.1 按流的方向

1)输入流(input)
用于读数据

所有输入流类都是 InputStream 抽象类(字节输入流)和 Reader 抽象类(字符输入流)的子类

InputStream(字节输入流)结构------>了解即可

FileInputStream  文件输入流
PipedInputStream  管道输入流
ObjectInputStream  对象输入流

FilterInputStream  过滤器输入流
- PushBackInputStream  回压输入流
- BufferedInputStream  缓冲输入流
- DataInputStream  数据输入流

SequenceInputStream  顺序输入流
ByteArrayInputStream  字节数组输入流
StringBufferInputStream  缓冲字符串输入流

InputStream 类常用方法------>掌握

read()方法(重载)3- int read():从输入流读入一个 8 字节的数据,将它转换成一个 0~ 255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1
- int read(byte[] b):从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,返回的字节数表示读取的字节数,如果遇到输入流的结尾返回 -1
- int read(byte[] b,int off,int len):从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,其中 off 是指在数组中开始保存数据位置的起始下标,len 是指读取字节的位数。返回的是实际读取的字节数,如果遇到输入流的结尾则返回 -1

close():关闭数据流,当完成对数据流的操作之后需要关闭数据流
available():返回可以从数据源读取的数据流的位数
skip(long n):从输入流跳过参数 n 指定的字节数目

markSupported():判断输入流是否可以重复读取
mark(int readLimit):如果输入流可以被重复读取,从流的当前位置开始设置标记,readLimit 指定可以设置标记的字节数
reset():使输入流重新定位到刚才被标记的位置,这样可以重新读取标记过的数据

两点注意:

最后 3 个方法一般结合使用,先用 markSupported() 判断,如果可以重复读取,则用 mark(int readLimit) 方法进行标记,标记完成后可以用 read() 方法读取标记范围内的字节数,最后用 reset() 方法使输入流重新定位到标记的位置,继而完成重复读取操作。

Java 中的字符是 Unicode 编码(双字节),而 InputerStream 是用来处理单字节的,在处理字符文本时不是很方便。这时可以使用 Java 的文本输入流 Reader 类,该类是字符输入流的抽象类,即所有字符输入流的实现都是它的子类,该类的方法与 InputerSteam 类的方法类似,不再赘述。

2)输出流(Output)
用于写数据

所有输出流类都是 OutputStream 抽象类(字节输出流)和 Writer 抽象类(字符输出流)的子类

OutputStream(字节输出流)结构------>了解即可

FileOutputStream  文件输出流
PipedOutputStream  管道输出流
ObjectOutputStream  对象输出流
FilterOutputStream  过滤器输出流
PrintStream  打印输出流
BufferedOutputStream  缓冲输出流
DataOutputStream  数据输出流
ByteArrayOutputStream  字节数组输出流

OutputStream 类常用方法------>掌握

write()方法(重载)3- int write(b):将指定字节的数据写入到输出流
- int write(byte[] b):将指定字节数组的内容写入输出流
- int write(byte[] b,int off,int len):将指定字节数组从 off 位置开始的 len 字节的内容写入输出流
close():关闭数据流
flush():刷新数据流
2.2 按数据单位

1)字节流
写数据
字节流抽象基类(父类)

InputStream:是字节输入流的所有类的超类(父类)
OutputStream:是字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类名的后缀 (可参考上一节的输入流和输出流内容)

FileOutputStream:文件输出流用于将数据写入File

FileOutputStream(String name):创建文件输出流以指定的名称写入文件

使用字节输出流写数据的步骤:(创建对象–>写数据–>释放资源)

1、创建字节输出流对象(做了3件事情)
- 调用系统功能创建了文件
- 创建字节输出流对象
- 让字节输出流对象指向文件

2、调用字节输出流对象的写数据方法
3、释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

示例1

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo1 {
    public static void main(String[] args) throws IOException { // 抛出异常
        // 创建字节输出流对象
        // FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");
        /*
        做了三件事情:
        1:调用系统功能创建了文件
        2:创建字节输出流对象
        3:让字节输出流对象指向创建好的文件
         */
        //void write(int b):将指定的字节写入此文件输出流
        fos.write(97);  // a
        fos.write(57);  // 9 (是字符不是数字)
        fos.write(55);  // 7 (是字符不是数字)

        // 最后都要释放资源
        // void close():关闭此文件输出流并释放与此流相关联的任何系统资源
        fos.close();
    }
}

运行结果(会生成一个fos.txt文件,打开查看内容如下)

a97

字节流写数据的三种方式(write()方法的重载–3个)

int write(b):将指定字节的数据写入到输出流
int write(byte[] b):将指定字节数组的内容写入输出流
int write(byte[] b,int off,int len):将指定字节数组从 off 位置开始的 len 字节的内容写入输出流

示例2

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class FileOutputStreamDemo2 {
    public static void main(String[] args) throws IOException { // 抛出异常
        /**
         * 1.创建对象
         */
        // 创建字节输出流对象
        // FileOutputStream(String name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos1=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");

        /**
         * 2.写数据(3种方式)
         */
        // void write(int b):将指定的字节写入此文件输出流
//        fos1.write(97);
//        fos1.write(98);
//        fos1.write(99);
//        fos1.write(100);
//        fos1.write(101);  // 结果:abcde
        // void write(byte[] b):将指定字节数组的内容写入输出流
//        byte[] bys={97,98,99,100,101};  //方法1:创建数组
        byte[] bys="abcde".getBytes();    //方法2:getBytes()方法
//        fos1.write(bys);      // 结果:abcde
        // void write(byte[] b,int off,int len):将指定字节数组从 off 位置开始的 len 字节的内容写入输出流
//        fos1.write(bys,0,bys.length);  // 结果:abcde
        fos1.write(bys,1,3);     // 结果:bcd

        /**
         * 3.释放资源
         */
        fos1.close();
    }
}

getBytes()方法使用注意:

getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

字节流写数据的两个小问题
a、实现换行(添加换行符)

windows:\r\n
linux:\n
mac:\r

b、实现追加写入

public FileOutputStream(String name,boolean append)

创建文件输出流以指定名称写入文件。若第二个参数为true,则字节将写入文件的末尾而不是开头(开头覆盖,末尾追加)
- 默认是false,即写在开头,这样每运行一次都会覆盖原内容,追加写入时要改为true

示例3

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo3 {
    public static void main(String[] args) throws IOException {
        // 创建字节输出流对象
        //boolean append为true实现追加(将字节写入末尾而不是开头)
        FileOutputStream fos3=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt",true);
        // 写数据
        for(int i=0;i<10;i++){
            fos3.write("hello".getBytes()); // getBytes()方法
            fos3.write("\r\n".getBytes()); // 每写完一次做一个换行
        }
        // 释放资源
        fos3.close();
    }
}

补充:

try-catch异常处理(一般文件相关的异常直接用throws抛出即可,但try-catch异常捕获方式也要了解,不懂的可以回去看异常处理部分)

finally:在异常处理时提供finally块来执行所有清除操作。如IO流中的释放资源。特点:被finally控制的语句一定会执行,除非JVM退出

示例4

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo4 {
    public static void main(String[] args) {
        FileOutputStream fos4 = null; // 初始化文件对象为null(全局+初始化)
        try {
            // 创建对象
//            fos4 = new FileOutputStream("Z:\\Ultimate JavaCode\\src\\test6\\fos4.txt"); //文件不存在会抛出FileNotFoundException异常
            fos4 = new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");
            // 写入数据
            fos4.write("javaEE".getBytes());
            // 关闭资源
            fos4.close();
            // 若写入操作存在异常,则直接跳到catch捕获,不会执行关闭资源操作,这时需要引入finally
        } catch (IOException e) { // 捕获异常
            e.printStackTrace(); //存在异常时,追踪异常信息
        } finally { // 加入finally实现释放资源
            if(fos4!=null){ // 文件不为null时,才需要释放资源(防止文件为null时关闭资源出现空指针异常NullPointerException)
                try{
                    fos4.close(); // 释放资源
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

读数据
字节流读数据(一次读一个字节数据)

FileInputStream:从文件系统中的文件获取输入字节
- FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

使用字节输入流读数据的步骤:(创建对象-->读数据-->释放资源)
1、创建字节输入流对象(做了3件事情)
- 调用系统功能创建了文件
- 创建字节输出流对象
- 让字节输出流对象指向文件
2、调用字节输入流对象的读数据方法
3、释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)

字节流读数据的3种方式(read()方法重载–3个)

int read():从输入流读入一个 8 字节的数据,将它转换成一个 0~ 255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1
int read(byte[] b):从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,返回的字节数表示读取的字节数,如果遇到输入流的结尾返回 -1
int read(byte[] b,int off,int len):从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,其中 off 是指在数组中开始保存数据位置的起始下标,len 是指读取字节的位数。返回的是实际读取的字节数,如果遇到输入流的结尾则返回 -1

案例1

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo1 {
    public static void main(String[] args) throws IOException {
        // 创建对象
        FileInputStream fis=new FileInputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");
        // 读数据
//        int bys= fis.read();
//        System.out.println(bys); // 结果:98(文件的字符是'b')
//        System.out.println((char)bys); // 大转小,强制转换,显示原字符(结果:b)

        /*
        字节流读数据标准代码如下
        1.fis.read():读数据
        2.by=fis.read():将读取的数据赋值给by
        3.by!=-1:判断读取到的数据是否是-1(到达文件末尾)
         */
        int by; // 类型声明
        while((by=fis.read())!=-1){
            System.out.print((char)by); // 强转显示原字符(结果:bcd),注意用print而不是println
        }
        // 释放资源
        fis.close();
    }
}

案例2:字节流复制文本文件
需求:把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileInputStreamDemo2{
    public static void main(String[] args) throws IOException {
        // 创建对象
        FileInputStream fis=new FileInputStream("D:\\文本复制案例.txt"); // 从指定路径下读取要复制的文本文件(数据源)
        FileOutputStream fos=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");//目的地
        // 先从数据源(fis)读取,后写入目的地(fos)
        int by;
        while((by=fis.read())!=-1){ // 一次读取一个字节,直到读完(到文件末尾)
            fos.write(by); // 一次写入一个字节
        }
        // 释放资源
        fos.close();
        fis.close(); // 先创建的后释放
    }
}

案例3
需求:字节流读数据(一次读一个字符数组),用到int read(byte[] b)构造方法

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamDemo3 {
    public static void main(String[] args) throws IOException {
        // 创建对象
        FileInputStream fis=new FileInputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");
        byte[] bys=new byte[1024]; // 1024及其整数倍
        int len;
        // 读取数据
        while((len=fis.read(bys))!=-1){ // 一次读一个字符数组,用到int read(byte[] b)构造方法
            System.out.println(new String(bys,0,len)); // new String方法转换为字符串输出到控制台
        }
        // 释放资源
        fis.close();
    }
}

字节缓冲流

BufferedOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以将字节写入基础输出流,而不必为写入的每个字节调用底层系统。
BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。

构造方法

字节缓冲输出流:BufferedOutputStream(OutputStream out)
字节缓冲输入流:BufferedInputStream(InputStream in)

问题:构造方法里需要的是字节流而不是具体的文件或路径?
原因:字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作。

示例

import java.io.*;

public class BufferStreamDemo1 {
    public static void main(String[] args) throws IOException {
//        FileOutputStream fos=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt");
//        BufferedOutputStream bos=new BufferedOutputStream(fos);
        // 创建字节缓冲输出流对象
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt"));
        // 操作1:写数据
        bos.write("hello\n".getBytes());
        bos.write("javaEE\n".getBytes());
        // 创建字节缓冲输入流对象(用于读数据)
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C:\\Users\\ASUS\\Desktop\\project1\\src\\fos.txt"));

        // 操作2:读数据
        // 方法1:一次读取一个字节数据
//        int by;
//        while((by=bis.read())!=-1){
//            System.out.println((char)by);
//        }
        // 方法2:一次读取一个字节数组
        byte[] bys=new byte[1024]; // 1024及其整数倍
        int len;
        while((len=bis.read(bys))!=-1){
            System.out.println(new String(bys,0,len)); // 转换为字符串输出到控制台
        }
        // 释放资源
        bos.close();
    }
}

运行结果(打开fos.txt文件,显示如下)

hello
javaEE

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

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

相关文章

Day21-磁盘管理之raid及分区

Day21-磁盘管理之raid及分区 1 Raid技术1.1 什么是Raid?1.2 为什么服务器需要Raid?1.3 什么是Raid级别?1.4 Raid有哪些实现方式&#xff1f;1.5 什么是RAID0&#xff1f;&#xff08;图&#xff09;1.6 什么是RAID1&#xff1f;&#xff08;图&#xff09;1.7 什么是RAID5&a…

Python爬虫Cookies 池的搭建

Cookies 池的搭建 很多时候&#xff0c;在爬取没有登录的情况下&#xff0c;我们也可以访问一部分页面或请求一些接口&#xff0c;因为毕竟网站本身需要做 SEO&#xff0c;不会对所有页面都设置登录限制。 但是&#xff0c;不登录直接爬取会有一些弊端&#xff0c;弊端主要有…

[HackMyVM] 靶场 Wave

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…

学习助手:借助AI大模型,学习更高效!

在当今的数字时代&#xff0c;人工智能&#xff08;AI&#xff09;的崛起已经彻底改变了我们获取信息、处理数据以及学习新知识的方式。AI大模型&#xff0c;特别是如OpenAI开发的GPT-4这类先进的技术&#xff0c;已成为学习和教育领域的一大助力。本文旨在探索如何借助AI大模型…

tritonserver学习之八:redis_caches实践

tritonserver学习之一&#xff1a;triton使用流程 tritonserver学习之二&#xff1a;tritonserver编译 tritonserver学习之三&#xff1a;tritonserver运行流程 tritonserver学习之四&#xff1a;命令行解析 tritonserver学习之五&#xff1a;backend实现机制 tritonserv…

javaWebssh票据管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh票据管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模 式开发。开发环境为TOMCAT7.0,My…

Vue+SpringBoot打造高校大学生创业管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统公告模块2.2 创业项目模块2.3 创业社团模块2.4 政府政策模块2.5 创业比赛模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 系统公告表3.2.2 创业项目表3.2.3 创业社团表3.2.4 政策表 四、系统展示五、核心代码5.…

MutationObserver是一个可以监听DOM结构变化的接口,请停用DOMContentLoaded

DOMContentLoaded已经要被放弃使用了&#xff0c;所以官方推荐使用MutationObserver来监听页面发生变化。但是如果你想继续使用也是可以的&#xff1b;Document: DOMContentLoaded event - Web APIs | MDN MutationObserver官方文档&#xff1a;MutationObserver - Web APIs |…

Python 自动化给女友发邮件:含新闻、天气、每日一句、图片 最全攻略系列02 如何添加emoji

Python 自动化给女友发邮件:含新闻、天气、每日一句、图片 最全攻略系列 是否想在女友面前展示程序员炫酷的一面? 是否想给她每日问候但是害怕忘记固定时间发送信息? 是否也羡慕别人可以优雅使用Python定时发送邮件? 欢迎来到Python自动化发邮件最全攻略系列,本系列将…

《剑指 Offer》专项突破版 - 面试题 65、66 和 67 : 关于前缀树应用的面试题(C++ 实现)

目录 面试题 65 : 最短的单词编码 面试题 66 : 单词之和 面试题 67 : 最大的异或 面试题 65 : 最短的单词编码 题目&#xff1a; 输入一个包含 n 个单词的数组&#xff0c;可以把它们编码成一个字符串和 n 个下标。例如&#xff0c;单词数组 ["time", "me&…

一、环境配置

一、下载Ubuntu18.04版本镜像 我的电脑配置比较低(08年奥运限定版哦)&#xff0c;使用的是虚拟机VMware进行安装Ubuntu18.04版&#xff0c;跟书上使用的一样 Ubuntu 18.04镜像 别下载错了哈 二、VMware下安装Ubuntu18.04操作系统 之前写过相关的博文&#xff0c;详细配置可…

如何选择护眼台灯?2024五大出众品牌护眼台灯推荐

护眼台灯的日常使用非常简便&#xff0c;而且还能提供合适的光照&#xff0c;起到预防近视的效果。但如今市场却有一些劣质护眼台灯&#xff0c;它们的使用体验不佳&#xff0c;还有可能会对眼睛健康造成影响、那么如何选择护眼台灯呢&#xff1f;关于这点今天就将分享几个选购…

用node或者vscode开启一个简单的本地server服务器,加载html网页

使用Live Server 想要加载本地html页面可以快速能让它在你本地浏览器中打开&#xff0c;可以有好多种方式&#xff0c;如果你有使用vscode&#xff0c;可以安装一个插件&#xff1a;Live Server&#xff0c;然后直接在vscode中直接右键就可以开启这个服务&#xff1a; 安装好之…

攻防世界例题wp

1.看到_wakeup()函数第一反应要么触发&#xff0c;要么绕过在这里绕过 2.构造payload实例化一个对象后反序列化 3构造脚本如下&#xff1a; 4.因为它是一个绕过的方法所以我们要使用绕过的方法。 5.继续构造payload将上图的1换成2进行绕过 最终的payload为 O:4:"xctf…

MATLAB_ESP32有限脉冲响应FIR无限脉冲响应IIR滤波器

要点 ESP32闪烁LED&#xff0c;计时LEDESP32基础控制&#xff1a;温控输出串口监控&#xff0c;LCD事件计数器&#xff0c;SD卡读写&#xff0c;扫描WiFi网络&#xff0c;手机控制LED&#xff0c;经典蓝牙、数字麦克风捕捉音频、使用放大器和喇叭、播放SD卡和闪存MP3文件、立体…

【SVN】使用TortoiseGit删除Git分支

使用TortoiseGit删除Git分支 前言 平时我在进行开发的时候&#xff0c;比如需要开发一个新功能&#xff0c;这里以蘑菇博客开发服务网关-gateway功能为例 一般我都会在原来master分支的基础上&#xff0c;然后拉取一个新的分支【gateway】&#xff0c;然后在 gateway分支上进…

社区店选址评估:利用大数据选址的技巧与策略

在当今数字化的时代&#xff0c;利用大数据进行社区店选址评估已成为一种高效、科学的方法。作为一名开鲜奶吧5年的创业者&#xff0c;我将分享一些利用大数据选址的技巧与策略&#xff0c;帮助你找到最适合的店铺位置。 1、确定目标商圈 在选址之前&#xff0c;首先要明确自己…

css实现居中

基础代码&#xff1a; <div class"box"><div class"content"></div> </div> css实现居中的几种方式&#xff1a; 1、flex布局&#xff08;水平垂直&#xff09; .box {width: 200px;height: 200px;background-color: pink;disp…

MySQL入门------数据库与SQL概述

目录 前言 一、数据库相关概念 二、数据模型 1.关系型数据库&#xff08;RDBMS&#xff09; 三、MySQL数据库 1.下载和安装 2.配置环境变量 四、SQL 1.SQL通用语法 2.SQL分类 前言 从本期开始&#xff0c;我们开始学习数据库的相关理论和实践知识&#xff0c;从入门…

把python完全卸载干净

1.winR&#xff0c;输入control回车&#xff0c;点击程序和功能&#xff0c;在搜索框输入python&#xff0c;右键点击卸载 2、找到Python安装路径&#xff0c;把所有文件全部删除。 安装路径可以打开CMD输入&#xff1a;where python 3、强制删除Python.exe 打开cmd&#xff…