一文掌握如何使用Java操作文件与IO流

news2024/9/21 11:13:19

文章目录

  • 1. 认识文件
  • 2. 文件的类型
  • 3. 操作文件
    • 3.1 属性
    • 3.2 构造方法
    • 3.3 常用方法
  • 4. IO流
    • 4.1 字节流
      • 4.1.1 InputStream
      • 4.1.2 OutputStream
      • 4.1.3 flush刷新
      • 4.1.4 关闭文件close
      • 4.1.5 字节缓冲流
    • 4.2 字符流
      • 4.2.1 Reader
      • 4.2.2 Writer
      • 4.2.3 Scanner
      • 4.2.4 字符缓冲流
  • 5. 复制文件
    • 5.1 字节流复制图片
    • 5.2 缓冲字节流复制图片
    • 5.3 字符流复制Java文件
    • 5.4 缓冲字符流复制Java文件
    • 5.5 耗时对比
  • 6. Files类
    • 6.1 Files类读文件
    • 6.2 Files类写文件

1. 认识文件

  • 侠义上的文件:硬盘上的文件和目录(文件夹)
  • 广义上的文件:泛指计算机中很多的软硬件资源,操作系统中,把很多的硬件设备和软件资源抽象成文件,按照文件的方式统一管理

此处只讨论侠义上的文件,也就是硬盘上的文件

每个文件在硬盘上都有一个具体的路径,表示一个文件的具体位置路径,就可以使用/(斜杠)\(反斜杠)来分割不同的目录级别
在这里插入图片描述

路径有两种表示风格:

  1. 绝对路径:以盘符c:,d:这样开头的
  2. 相对路径:以当前所在的目录(工作目录)为基准,./../开头,./有时候可以省略

说明: 每个程序运行的时候都有一个工作目录,./为当前目录../为上级目录,打开idea,下面的路径就是idea的工作目录,我们在程序中要是写相对目录的话,就是以该路径为基准的

在这里插入图片描述

2. 文件的类型

我们一般将文件分为两种类型,文本文件二进制文件

文本文件存的是文本也就是字符串,字符串是由字符构成的,每个字符是由一个整数数字表示的
二进制文件存储的是二进制数据

小技巧:如何区分文本文件与二进制文件?

使用记事本打开文件,看的懂就是文本文件,看不懂(乱码)的就是二进制文件

3. 操作文件

Java标准库提供了File这个类

3.1 属性

separator是File类里的一个静态变量,表示的是系统里的路径分割符

        System.out.println(File.separator);

在这里插入图片描述

\反斜杠windows系统中路径的分割符

3.2 构造方法

构造方法说明
File(String pathName)根据文件路径创建一个File实例,路径可以为绝对或者相对路径
File(File parent, String child)根据父目录与孩子文件创建一个File实例,父目录用File表示
File(String parent, String child)根据父目录与孩子路径创建一个File实例,父目录用String表示

注意: 使用路径创建File实例的时候,不要求文件真实存在

        File file1 = new File("D:/photo/1.jpg"); //最常用
        File file2 = new File("D:/photo/","2.jpg");
        File file3 = new File(new File("D:/photo/"),"3.jpg");

3.3 常用方法

返回值方法说明
booleanexists()目录或文件是否存在
StringgetName()返回目录或文件的名称
StringgetPath()返回文件路径(使用啥路径创建FIle,返回啥路径)
StringgetAbsolutePath()返回绝对路径
booleanisDirectory()是否是目录
booleanisFile()是否是文件
File[]listFiles()返回目录下一级的子文件夹或子文件
booleanmkdir()创建目录
booleanmkdirs()创建多级目录
booleancreateNewFile()创建文件
booleandelete()删除文件

示例1:

        File file = new File("./dir/test.txt"); //此路径不要求真实存在
        System.out.println(file.getName()); //获取目录或文件名称
        System.out.println(file.getPath()); //获取文件路径(用啥路径创建File,返回啥路径)
        System.out.println(file.getAbsoluteFile()); //获取文件绝对路径
        System.out.println(file.getCanonicalPath()); //获取使用File修饰过的绝对路径
        System.out.println(file.exists()); //判断目录或文件是否存在
        System.out.println(file.isFile()); //判断是否是文件
        System.out.println(file.isDirectory()); //判断是否是目录

在这里插入图片描述

示例2:

        File file = new File("./a/b/c");
        file.mkdirs(); //创建多级目录
        File file1 = new File("./a/b/c/d.txt");
        file1.createNewFile(); //创建文件

在这里插入图片描述

示例3:

        File file1 = new File("./a/b/c/d.txt");
        file1.delete(); //删除文件

在这里插入图片描述

4. IO流

针对文件内容的读写,使用流对象来操作

流对象从类型上分为两个大类别:

  1. 字节流:操作二进制数据
    InputStream(字节输入流)
    OutputStream(字节输出流)
  2. 字符流:操作文本数据
    Reader(字符输入流)
    Writer(字符输出流)

这些类的使用方式比较固定:

  1. 打开文件
  2. 读文件
  3. 写文件
  4. 关闭文件

输入输出的方向:

  • 数据从硬盘到内存称为读(input)
  • 数据从内存到硬盘称为写(output)

使用推荐:

  • 对于文本文件,推荐使用字符流进行读写,使用二进制读写也行,只是推荐使用字符流
  • 对于二进制文件(图片,视频等),使用字节流进行读写

字节数组可以和字符串相互转换

字节数组转字符串:

byte[] bytes = new byte[1024];
String str = new String(bytes);

还可以指定字节数组的范围

int len = 10;
String str = new String(bytes,0,len);

字符串转字节数组:

String str = "hello";
byte[] bytes = str.getBytes();

字符转字节是编码,字节转字符是解码,解码编码如果不一致会发生乱码,所以在字符串与字节数组进行转换的时候可以指定编码集:

byte[] bytes = str.getBytes("utf-8");
String s = new String(bytes,"utf-8");

不同编码类型说明:

  • GBK:英文占1个字节,中文占2个字节
  • UTF-8:英文占1个字节,中文占3个字节
  • Unicode:英文占2个字节,中文占2个字节
  • Ascll:单字节编码,无中文

4.1 字节流

4.1.1 InputStream

InputStream是一个抽象类不能创建实例,要创建实例得使用它的子类,我们使用FileInputStream创建字节输入流对象

InputStream的方法:

方法说明
int read()一次读一个字节,返回读到的内容,返回-1代表读完
int read(byte[] b)一次读一个字节数组,返回实际读到的长度,返回-1代表读完
int read(byte[] b, int off, int len)往字节数组b从off开始,读取len个长度,返回读到的长度,返回-1代表读完
void close()关闭字节输入流

FileInputStream的构造方法:

构造方法说明
FileInputStream(String fileName)使用文件路径构建输入流对象(可以是绝对路径或相对路径)
FileInputStream(File file)使用File对象构建输入流对象

注意: 创建输入流的时候必须要保证文件存在,否则会抛出异常,因为是在读文件

一个字节一个字节的读:

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //该文件路径必须存在,因为是读文件
        InputStream is = new FileInputStream("./dir/test.txt");
        int n;
        while((n = is.read()) != -1){
            System.out.println(n);
        }
        is.close();
    }
}

在这里插入图片描述
上述代码是一次读一个字节,导致读的次数多,而单次IO操作是要访问硬盘设备的,单词操作是比较耗时的,如果频繁进行这样的IO操作,效率肯定低

一次读一个字节数组:

public class Demo3 {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("./dir/test.txt");
        byte[] bytes = new byte[1024];
        int len;
        while((len = is.read(bytes)) != -1){
            for(int i = 0;i < len;i++){
                System.out.println(bytes[i]);
            }
        }
        is.close();
    }
}

在这里插入图片描述

这种操作一次最多可读1024个字节,大大减少了IO操作的次数,也就是减少了访问硬盘设备的次数,所以效率大大提高了

将读到的字节数组转换为字符串输出:

public class Demo3 {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("./dir/test.txt");
        byte[] bytes = new byte[1024];
        int len;
        while((len = is.read(bytes)) != -1){
            String s = new String(bytes,0,len);
            System.out.println(s);
        }
    }
}

在这里插入图片描述

4.1.2 OutputStream

OutputStream也是一个抽象类,不可以创建实例,我们使用它的子类FileOutputStream创建字节输出流对象

注意: 使用FileOutputStream创建对象时,文件不要求真实存在,如果文件不存在,则会创建文件

在这里插入图片描述

运行程序后,发现文件被创建

在这里插入图片描述
方法:

方法说明
void write(int b)一次写一个字节
void write(byte[] b)一次写一个字节数组
int write(byte[] b, int off, int len)从字节数组off位置开始写,一次写len长度
void close()关闭字节输出流

写文件之前,文件中存在内容hello

在这里插入图片描述

public class Demo5 {
    public static void main(String[] args) throws IOException {
        OutputStream os = new FileOutputStream("./dir/test.txt");
        os.write(97);
        os.write(98);
        os.write(99);
        os.write(100);
        os.close();
    }
}

写文件后,文件内容被更新为abcd

在这里插入图片描述

说明: 使用OutputStream打开文件,默认会清空文件原有的内容,如果想在原文件的基础上追加写,则在创建输出流对象时添加一个参数true,true代表不清空文件原有内容追加写

public class Demo5 {
    public static void main(String[] args) throws IOException {
        OutputStream os = new FileOutputStream("./dir/test.txt",true);
        os.write(97);
        os.write(98);
        os.write(99);
        os.write(100);
        os.close();
    }
}

发现在abcd的基础上又多了abcd

在这里插入图片描述

一次写一个字节数组:

public class Demo6 {
    public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("./dir/test.txt")){
            byte[] bytes = {96,97,98,99,100};
            os.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.1.3 flush刷新

IO操作是很慢的,所以OutputStream为了减少IO次数,写数据的时候会先将数据写到内存的一个指定区域里,该区域称为缓冲区,直到该区域满了或者满足其他指定条件时,才会把数据真正的写入到硬盘中,所以我们写文件的时候,很可能数据还存在缓冲区中,我们常常在合适的位置调用flush(),将数据刷新到硬盘中

public class Demo6 {
    public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("./dir/test.txt")){
            byte[] bytes = {96,97,98,99,100};
            os.write(bytes);
            os.flush(); //刷新操作
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.1.4 关闭文件close

在写或者读完文件,都要调用close来关闭文件,那调用close到底关闭的是什么?

在内核里,使用PCB这样的数据结构来表示进程,一个进程可以用一个或者多个PCB来表示,而一个线程对应一个PCB,PCB中有一个属性,文件描述符表(类似与数组)记录了该进程打开了哪些文件
一个进程里有多个线程,有多个PCB,这些PCB公用一个文件描述符表

在这里插入图片描述

  • 每次打开文件,就会在文件描述符表中申请一个空间,然后把该文件的信息放进去
  • 每次关闭文件(close),就会把这个文件描述符表对应的表项释放掉

如果文件没关闭,也就是没有调用close会怎样呢?

如果没有调用close,那文件描述符中对应的表项就不会及时的被释放掉,虽然Java中有GC操作,但是这个GC不一定及时,也就是不手动调用close释放,会导致文件描述符表很快被占满了(文件描述符表的容量大小一定,不能自动扩容)如果被占满了,后续在打开文件向文件描述符表申请空间的时候就会失败,所以文件就打不开了

一般来说close要被手动执行的,但是如果该文件始终伴随着程序,那么不关闭问题也不大,因为随着程序的运行结束,进程的销毁,PCB也就跟着销毁了,文件描述符表也就销毁了,对应的资源,操作系统就自动回收了

一般写代码都是要手动调用close的,那么如果保证close一定被执行到呢?

使用try-finally:

public class Demo5 {
    public static void main(String[] args) throws IOException {
        OutputStream os = null;
        try{
            os = new FileOutputStream("./dir/test.txt",true);
            os.write(97);
            os.write(98);
            os.write(99);
            os.write(100);
        }finally{
            os.close();
        }
    }
}

这种方式代码写着不优雅,有一种更推荐的写法:

public class Demo5 {
    public static void main(String[] args) throws IOException {
        try(OutputStream os = new FileOutputStream("./dir/test.txt",true)){
            os.write(97);
            os.write(98);
            os.write(99);
            os.write(100);
        }
    }
}

这样写对然没有显式调用close,但是在try语句块执行完,会自动调用close,try()中满足自动释放的有一定要求的,类必须实现Closeable接口,才可以自动调用close释放资源

在这里插入图片描述

4.1.5 字节缓冲流

一个字节一个字节的读会频繁进行IO操作,也就是频繁发生系统内核调用,这个操作是很耗时的,使用字节缓冲流,类似“池子”快速读写,减少系统内核调用频率

  • 字节缓冲输入流:BufferedInputStream(InputStream is)
  • 字节缓冲输出流:BufferedOutputStream(OutputStream os)

注意: 字节缓冲流构造函数的参数是字节流对象不是文件路径

缓冲流在内存提供一个区域为缓冲区,做了封装以块形式读写数据,但是读写数据还是依赖字节流对象,缓冲区的大小默认是8k(8192字节)

缓冲流和字节流之间的关系图:
在这里插入图片描述
缓冲字节输入流读数据:

public class Demo10 {
    public static void main(String[] args) throws IOException {
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream("./dir/test.txt"))){
            int n;
            byte[] bytes = new byte[1024];
            while((n = bis.read(bytes)) != -1){
                String str = new String(bytes,0,n);
                System.out.print(str);
            }
        }
    }
}

在这里插入图片描述

缓冲字节输出流写数据:

public class Demo11 {
    public static void main(String[] args) throws IOException {
        try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("./dir/test.txt"))){
            String str = "世界,你好";
            byte[] bytes = str.getBytes();
            bos.write(bytes);
            bos.flush();
        }
    }
}

在这里插入图片描述

4.2 字符流

字符流其实就是带编码的字节流,对于文本类型的文件,优先使用字符流,字符流的使用和字节流差不多

4.2.1 Reader

Reader是一个抽象类,必须new其子类FileReader

方法说明
int read()一次读一个字符,返回读的内容,返回-1代表读完
int read(char[] c)一次读一个字符数组,返回读的长度,返回-1待变读完
int read(char[] c, int off, int len)一次读一个字符数组的范围

一次读一个字符:

public class Demo8 {
    public static void main(String[] args) throws IOException {
        try(Reader r = new FileReader("./dir/test.txt")){
            int n;
            while((n = r.read()) != -1){
                System.out.println(n);
            }
        }
    }
}

往字符数组中读:

public class Demo8 {
    public static void main(String[] args) throws IOException {
        try(Reader r = new FileReader("./dir/test.txt")){
            char[] c = new char[100];
            int n;
            while((n = r.read(c)) != -1){
                String s = new String(c,0,n);
                System.out.print(s);
            }
        }
    }
}

在这里插入图片描述

4.2.2 Writer

Writer是一个抽象类,new的时候必须new其子类FileWriter

方法说明
void write(int c)一次写一个字符
void write(String str)一次写一个字符串
void write(char[] c)一次写一个字符数组
void write(String str, int off, int len)一次写字符串的部分数据
void write(char[] c, int off, int len)一次写字符数组的部分数据
public class Demo9 {
    public static void main(String[] args) throws IOException {
        try(Writer w = new FileWriter("./dir/test.txt")){
            w.write(98);
            w.write('\n');
            w.write("hello");
            w.write('\n');
            char[] c = {'w','o','r','l','d'};
            w.write(c);
            w.write('\n');
            w.write("好好学习",0,2);
            w.write('\n');
            w.write(c,0,2);
            w.flush();
        }
    }
}

在这里插入图片描述

4.2.3 Scanner

Scanner是搭配流对象使用的

构造方法说明
Scanner(InputStream is, String charset)使用charset字符集对is的扫描进行读取

我们常常写的这句代码:System.in就是一个输入流对象

Scanner sc = new Scanner(System.in);

也可以使用我们存在的文件构建流对象传入:

public class Demo7 {
    public static void main(String[] args) {
        try(Scanner sc = new Scanner(new FileInputStream("./dir/test.txt"))){
            while(sc.hasNext()){
                System.out.println(sc.nextLine());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

4.2.4 字符缓冲流

字符缓冲流的用法和字节缓冲流一样,是对字符流进行了封装,缓冲区的大小默认也是8k

  • 字符缓冲输入流:BufferedReader(FileReader fr)
  • 字符串冲输出流:BufferedWriter(FileWriter fw)

字符缓冲流读数据:

public class Demo12 {
    public static void main(String[] args) throws IOException {
        try(BufferedReader br = new BufferedReader(new FileReader("./dir/test.txt"))){
            int len;
            char[] c = new char[10];
            while((len = br.read(c)) != -1){
                String str = new String(c,0,len);
                System.out.print(str);
            }
        }
    }
}

在这里插入图片描述

字符缓冲流写数据:

public class Demo12 {
    public static void main(String[] args) throws IOException {
        try(BufferedWriter bw = new BufferedWriter(new FileWriter("./dir/test.txt"))){
            String str = "好好学习 找好工作";
            bw.write(str);
            bw.flush();
        }
    }
}

在这里插入图片描述

5. 复制文件

复制文件前提说明:

  • 用字节流复制图片文件(.jpg)
  • 用字符流复制普通的xml文件(.xml)

5.1 字节流复制图片

    public static void method1() throws IOException {
        InputStream is = new FileInputStream("./dir/图片.jpg");
        OutputStream os = new FileOutputStream("./dir/图片复制.jpg");
        int len;
        byte[] bytes = new byte[1024];
        while((len = is.read(bytes)) != -1){
            os.write(bytes,0,len);
        }
        os.flush();
        os.close();
        is.close();
    }

在这里插入图片描述

5.2 缓冲字节流复制图片

    public static void method2() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("./dir/图片.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("./dir/图片复制1.jpg"));
        int len;
        byte[] bytes = new byte[1024];
        while((len = bis.read(bytes)) != -1){
            bos.write(bytes);
        }
        bos.flush();
        bos.close();
        bis.close();
    }

在这里插入图片描述

5.3 字符流复制Java文件

    public static void method3() throws IOException {
        FileReader fr = new FileReader("./dir/server.xml");
        FileWriter fw = new FileWriter("./dir/server1.xml");
        int len;
        char[] c = new char[255];
        while((len = fr.read(c)) != -1){
            fw.write(c,0,len);
        }
        fw.flush();
        fw.close();
        fr.close();
    }

在这里插入图片描述

5.4 缓冲字符流复制Java文件

    public static void method4() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("./dir/server.xml"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("./dir/server2.xml"));
        int len;
        char[] c = new char[255];
        while((len = br.read(c)) != -1){
            bw.write(c,0,len);
        }
        bw.flush();
        bw.close();
        br.close();
    }

在这里插入图片描述

5.5 耗时对比

我们对上述的四个操作的耗时进行分组对比

  1. 字节流与缓冲字节流对比
  2. 字符流与缓冲字符流对比

看看哪个效率更高?

    public static void main(String[] args) throws IOException {
        long start1 = System.currentTimeMillis();
        method1();
        long end1 = System.currentTimeMillis();
        System.out.println("字节流耗时:"+(end1-start1));
        long start2 = System.currentTimeMillis();
        method2();
        long end2 = System.currentTimeMillis();
        System.out.println("缓冲字节流耗时:"+(end2-start2));
        long start3 = System.currentTimeMillis();
        method3();
        long end3 = System.currentTimeMillis();
        System.out.println("字符流耗时:"+(end3-start3));
        long start4 = System.currentTimeMillis();
        method4();
        long end4 = System.currentTimeMillis();
        System.out.println("缓冲字符流耗时:"+(end4-start4));
    }

在这里插入图片描述

从中发现,带缓冲的流比不带缓冲的流效率高,但是这里好像差别不大,那是因为这里举例的文件本身不大,大家可以换成稍微大的文件,效果更明显

6. Files类

Files类是java.nio包下的类,封装了许多文件读写的简单方法

6.1 Files类读文件

将文件内容读到一个字节数组中:

byte[] bytes = Files.readAllBytes(Path.of("./dir/test.txt"));

对于文本文件可以将文件的内容读到String中:

//默认使用utf-8
String context1 = Files.readString(Path.of("./dir/test.txt"));
//按行读取
List<String> lines = Files.readAllLines(Path.of("./dir/test.txt"));

6.2 Files类写文件

写文件也非常方便:

//写入二进制文件
byte[] bytes = "hello".getBytes();
Files.write(Path.of("./dir/test.txt"),bytes);
//写入文本
String text = "hello";
Files.writeString(Path.of("./dir/test.txt"),text);

注意: Files提供的读写方法,受内存限制,只能读写小文件,如配置文件,不可以一次读入几个G的大文件,读写大型文件仍然需要使用文件流来每次读取一小部分文件内容

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

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

相关文章

C语言入门篇——语句篇

目录 1、空语句 2、表达式语句 3、复合语句 4、控制语句 4.1、C控制语句&#xff1a;循环 4.1.1、while 4.1.2、while里的break和continue 4.2.1、for 4.2.2、for里的break和continue 4.3.1、do while 4.3.2、do while里的break和continue 5、C控制语句&#xff1a…

Flink 实时数仓 (一) --------- 数据采集层

目录 一、数仓分层介绍二、实时需求概览三、统计架构分析四、日志数据采集1. 模拟日志生成器的使用2. 日志采集模块-本地测试3. 日志采集模块-打包单机部署 五、业务数据库数据采集1. MySQL 的准备2. 环境搭建3. 代码实现 六、Nginx 安装七、Maxwell 安装八、Canal 安装 一、数…

STM32 平衡小车之电机驱动

TB6612FNG简介 单片机引脚的电流一般只有几十个毫安&#xff0c;无法驱动电机&#xff0c;因此一般是通过单片机控制电机驱动芯片进而控制电机。TB6612是比较常用的电机驱动芯片之一。 TB6612FNG可以同时控制两个电机&#xff0c;工作电流1.2A&#xff0c;最大电流3.2A。 VM电…

通信方式基础知识

文章目录 前言一、分类方式1、串行通信和并行通信2、同步通信和异步通信3、单工、半双工、全双工通信 前言 南京的梧桐树可以鲨掉我的程度 一、分类方式 1、串行通信和并行通信 串行通信&#xff1a;按位顺序&#xff0c;占用引脚资源较少&#xff0c;速度较慢 并行通信&…

移除链表元素(链表篇)

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 思路&#xff1a; ①直接使用原来的链表来进行删除操作。 ②设置一个虚拟头结点在进行删除操作 ①直接使用原来的链表…

【数据结构】- (带头结点)循环双向链表 - 详细实现思路及代码

目录 一、概述 二、循环双向链表 三、循环双向链表实现步骤  &#x1f4cc;3.1 C语言定义循环双向链表结点  &#x1f4cc;3.2 循环双向链表初始化  &#x1f4cc;3.3 循环双向链表插入数据  &#x1f4cc;3.4 循环双向链表删除数据  &#x1f4cc;3.5 循环双向链表查找数…

【python中的多线程了解一下?】

基本说明 线程&#xff08;Thread&#xff09;是操作系统进行调度的最小单位&#xff0c;是进程中的一个独立执行单元。线程与进程相比&#xff0c;具有更轻量级、更高效率、更易调度、共享资源等优点。 在传统的单核CPU中&#xff0c;操作系统通过时间片轮转算法将CPU的时间…

各种通讯总线的学习记要

一、在B站板道题看到一个比较好完视频&#xff08;爱上半导体&#xff09; 我觉得将232和485之前先将串口通信&#xff0c;因为它们都是串口通讯的变种。 串口通讯&#xff1a; 串口通讯我们约定好帧格式和波特率&#xff0c;通讯正常起始位为低开始&#xff0c;8位数据位&a…

【ABAQUS文档阅读笔记】关于体单元、壳单元、梁单元 、truss单元的总体认识

我的主页&#xff1a; 技术邻&#xff1a;小铭的ABAQUS学习的技术邻主页博客园 : HF_SO4的主页哔哩哔哩&#xff1a;小铭的ABAQUS学习的个人空间csdn&#xff1a;qgm1702 博客园文章链接&#xff1a; 学习笔记&#xff0c;from abaqus document “getting start with ABAQUS…

【代码随想录】刷题Day4

1.交换链表 24. 两两交换链表中的节点 前后指针实现 1.没有元素或者只有一个元素无意义 2.给出一个前驱prev&#xff0c;以及用来交换的两个节点cur和next 3.我当时是这么想的&#xff0c;如果两个指针一起动&#xff0c;那么就要用cur和next同时判断结束&#xff0c;也许这个…

C#基础学习--异常

目录 什么是异常 try语句 异常类 catch子句 catch子句段 finally块 为异常寻找处理程序 更进一步搜索 一般法则 抛出异常 不带异常对象的抛出 什么是异常 异常是程序运行时错误&#xff0c;它违反了系统约束或应用程序约束&#xff0c;或出现了在正常操作时未预料的情…

Windows环境下JDK内置迭代器的简介

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天讨论一下Windows环境下JDK内置迭代器。 相信大家已经注意到&#xff0c;为了让广大程序员能够更加方便地操作聚合对象&#xff0c;在Java、C#等编程语言中都提供了内置迭代器。 如果对这种迭代器还不了…

在JetsonNano上安装PREEMPT-RT实时核+IghEtherCAT主站的详细步骤

特别说明&#xff1a;由于本人空闲时间有限&#xff0c;此博客中所有内容均是从本人的个人笔记中摘抄出来&#xff0c;命令行大多以图片形式展示&#xff0c;不能提供复制粘贴功能敬请体谅。此外&#xff0c;第一部分关于在 Jetson Nano 上安装PREEMPT-RT 实时核的步骤比较详细…

企业工商四要素核验 API:有效应对商业欺诈和恶意交易的利器

引言 企业工商四要素核验是一种用于验证企业基本信息的方法&#xff0c;主要包括企业名称、社会统一信用代码、法人名称、法人身份证四个要素。这些要素是企业注册时必须提供的信息&#xff0c;通过对这些信息的验证&#xff0c;可以确定企业的真实性和合法性&#xff0c;通常…

【力扣-21】合并两个有序链表

&#x1f58a;作者 : Djx_hmbb &#x1f4d8;专栏 : 数据结构 &#x1f606;今日分享 : 英文文章里 : TL;DR 或者 tl;dr。 网上英文解释有两种&#xff0c;一种是Too long;Don’t read&#xff0c;另一种是Too long;Didn’t read。意思是&#xff1a;“文章太长了&#xff0c;读…

Stable Diffusion MacBookAir 手把手安装教程,以及checkpoint安装、Lora安装、civitai介绍。

目标&#xff1a; 本地部署Stable Diffusion 安装步骤&#xff1a; 安装git Git - Downloadshttps://git-scm.com/downloads安装python 3.10.6 Python Releases for macOS | Python.orgThe official home of the Python Programming Languagehttps://www.python.org/downl…

再捐1亿元种树治沙:蚂蚁集团持续七年支持内蒙古生态治理

今天&#xff08;4月22日&#xff09;是“世界地球日”&#xff0c;内蒙古自治区林草局与蚂蚁集团启动战略合作&#xff1a;由蚂蚁集团在三年内再捐资1亿元&#xff0c;通过公益项目“蚂蚁森林”支持浑善达克沙地的生态治理。这1亿元将用于当地林草生态的修复保护、沙化土地的治…

助力电力行业数字化,BI 大有可为

各地密集上马的电力工程为上下游产业链发展带去了更多市场机遇&#xff0c;“三零”“三省”办电服务的推广让企业获得了看得见、摸得着的实惠&#xff0c;电力行业正在以自身高质量发展新成效助力经济稳增长&#xff0c;为扎实推进中国式现代化建设注入强劲动能。 电力行业是…

Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)

Spring Cloud Gateway Actuator API SpEL表达式注入命令执行&#xff08;CVE-2022-22947&#xff09; 0x00 前言 Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本&#xff08;包含&#xff09;以前存在一处SpEL表达式注入漏洞&#xff0c;当攻击者可以访问…

plt.title()函数中文无法显示问题

文章目录 问题描述解决办法plt.title()函数参数说明 问题描述 由于画图时plt.title()默认是显示英文&#xff0c;如果我们设置标题为中文&#xff0c;会无法显示&#xff0c;如图&#xff1a; plt.title(训练损失) plt.plot(np.arange(len(losses)), losses, -o, colorred) p…