【Java EE】 文件IO的使用以及流操作

news2024/11/24 17:16:53

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶​
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客

系列专栏:xiaoxie的JAVAEE学习系列专栏——CSDN博客●'ᴗ'σσணღ
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

目录

​编辑​ 一.文件IO概述

1.什么IO

2.什么是文件

1.绝对路径

2.相对路径

​编辑​

3.如何区分一个文件是二进制文件还是文本文件 

3.使用Java操作文件

1.使用Java针对文件系统进行操作

1.构造方法

2.常用API

3.常用方法使用

Java代码 

创建文件

 删除文件

创建目录

 2.Java通过使用流来对文件内容进行操作

1. 字节流 vs 字符流

1.字节流 (Byte Streams)

2.字符流 (Character Streams)

3.区别

 2.使用字节流对文件内容操作

1.InputStream的使用(从文件读取数据)

1.read()方法不带参数

2.read()方法带参数

2.OutputStream的操作(从文件中写入数据)

 1.write()方法

3.使用字符流对文件内容操作

1.Reader的使用

1.read()方法

 2.Writer的使用

1.writer

二.根据文件IO操作和流操作的知识解决问题的案例

1.案例一: 

2.案例二:

3.案例三:


​ 一.文件IO概述

1.什么IO

IO就是 Input(输入), Output(输出),至于如何判断一个操作是否为输入还是输出,可以以下图的标准作为参考

我们以CPU 作为基准,进入CPU方向的操作就是Input(输入),从CPU方向出去就是Output(输出).

2.什么是文件

文件是一个很广义的概念,在操作系统中把 软件资源/ 硬件资源 都给抽象为 文件 ,特别是在 Linux一切皆为文件.

在此处我们所提的文件,特指的就是保存在硬盘中的文件,而硬盘上又有非常多的文件和目录(就是我们俗称的文件夹)directory,它们之间又有着嵌套的关系,从而就构成了多叉树的结构.

​而我们对文件的操作,本质上就是对该多叉树的增删查改,而我们该如何找到文件的具体位置在那呢,这个时候,就引入的两个方法,即绝对路径,以及相对路径

1.绝对路径

在计算机操作系统中,绝对路径是指从文件系统的根目录开始的完整路径,它提供了到达某个特定文件或目录的确切位置。绝对路径是唯一的,并且不依赖于当前工作目录的位置

例如我们要找到qq.exe绝对路径

 在Windows操作系统中 我们直接点上方搜索框,即可 C:\Program Files\Tencent\QQNT\QQ.exe

这个就为QQ.exe 这个文件的绝对路径了

注意:

这里的 \ 是 路径分割符,这里博主建议应该为 / ,因为只有在Windows操作系统中, \ 这个为路径分割符,而在像Linux中是以 这个为路径分割符,我们日后再工作中一般使用的都是 Linux 的环境下的,所以在我们写代码的时候建议使用 / 作为路径分隔符.

2.相对路径

例如我们是以 QQNT 作为基准的, 直接就  ./QQ.exe 就可以找到对于的文件了,这个就是相对路径,就是不是以根路径为基准了, 其中 . 这一个点表示的意思是在当前所在的位置. 或者我们此时在 QQNT的另一个文件中

​我们要想找到QQ.exe的相应位置 就得使用 ../QQ.exe  其中 .. 这两个点的意思就是,回到上一级路径, 相对路径相对来说就比较多表了,根据不同的情况就有不同的相对路径,而绝对路径是唯一的.

3.如何区分一个文件是二进制文件还是文本文件 

区分一个文件是二进制文件还是文本文件还是特别重要的,文件的不同,我们的代码也大相同,那么如何,快速区分呢,直接使用记事本打开看看是不是乱码就可以区分,如果是,那么就为二进制文件,不是就为文本文件

例如我们使用记事本打开一个图片看一下

可以看到我们所看到的记事本的内容为乱码,即这个文件那就是二进制文件

3.使用Java操作文件

1.使用Java针对文件系统进行操作

在Java中,操作文件系统主要涉及Java标准库中的java.iojava.nio.file包。下面是一些常用的API

1.构造方法
方法名说明
File(File parent, String child)
根据⽗⽬录 + 孩⼦⽂件路径,创建⼀个新的 File 实例
File(String pathname)
根据⽂件路径创建⼀个新的 File 实例,路径可以是绝对路径或者相对路径
File(String parent, String child)
根据⽗⽬录 + 孩⼦⽂件路径,创建⼀个新的 File 实
例,⽗⽬录⽤路径表⽰

我们一般使用第二种方法来创建文件

2.常用API
修饰符及返回值类型
方法名说明
String
getParent()
返回 File 对象的⽗⽬录⽂件路径
String
getName()
返回 FIle 对象的纯⽂件名称
String
getPath()
返回 File 对象的⽂件路径
String
getAbsolutePath()
返回 File 对象的绝对路径
String
getCanonicalPath()
返回 File 对象的修饰过的绝对路径
boolean
exists()
判断 File 对象描述的⽂件是否真实 存在
boolean
isDirectory()
判断 File 对象代表的⽂件是否是⼀
个⽬录
boolean
isFile()
判断 File 对象代表的⽂件是否是⼀
个普通⽂件
boolean
createNewFile()
根据 File 对象,⾃动创建⼀个空⽂
件。成功创建后返回 true
boolean
delete()
根据 File 对象,删除该⽂件。成功
删除后返回 true
void
deleteOnExit()
根据 File 对象,标注⽂件将被删
除,删除动作会到 JVM 运⾏结束时 才会进⾏
String[]
list()
返回 File 对象代表的⽬录下的所有
⽂件名
File[]
listFiles()
返回 File 对象代表的⽬录下的所有
⽂件,以 File 对象表⽰
boolean
mkdir()
创建 File 对象代表的⽬录
boolean
mkdirs()
创建 File 对象代表的⽬录,如果必
要,会创建中间⽬录
boolean
renameTo(File dest)
进⾏⽂件改名,也可以视为我们平
时的剪切、粘贴操作
boolean
canRead()
判断⽤⼾是否对⽂件有可读权限
boolean
canWrite()
判断⽤⼾是否对⽂件有可写权限
3.常用方法使用

首先我先创建好一个 文本文件-> work.txt

Java代码 

public static void main(String[] args) throws IOException {

    // 创建一个File对象,这里使用的是绝对路径
    File file = new File("C:/java/work.txt");

    // 获取文件所在的父路径
    System.out.println(file.getParent());

    // 获取文件名部分
    System.out.println(file.getName());

    // 获取从当前工作目录到文件的相对路径,
    System.out.println(file.getPath());

    // 获取文件的绝对路径,基于系统的根目录,确保得到完整的路径
    System.out.println(file.getAbsolutePath());

   // 获取文件的相对路径
    System.out.println(file.getCanonicalPath());
}

结果为 

 如果我们在构造方法上使用相对路径的话,就会在你的Java工作文件上创建

public static void main(String[] args) throws IOException {
        File file = new File("./work.txt");
        System.out.println(file.getParent());
        System.out.println(file.getName());
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }

结果为 

可以看到相对路径和绝对路径就是在Java工作路径和相对路径进行简单的拼接. 

创建文件
 // 主方法的开始,可以抛出IOException异常
public static void main(String[] args) throws IOException {
         // 创建File对象file,使用相对路径
        File file = new File("./work.txt"); 
        // 如果work.txt文件不存在,则创建它;如果已存在,则不执行任何操作
        file.createNewFile();  

       // 打印true,如果文件存在(包括文件和目录)
        System.out.println(file.exists());  

        // 打印文件是否为普通文件的检查结果
        System.out.println(file.isFile());  

        // 打印文件是否为目录的检查结果
        System.out.println(file.isDirectory());  
    }

结果为:

同时还可以看到,在Java工作路径下,work.txt被创建出来了

 删除文件

实际上,在大多数情况下,delete() 方法就已经足够用于删除文件。然而,deleteOnExit() 方法提供了另一种特殊的删除策略,它的应用场景有所不同:

  1. delete() 方法:

    • 直接尝试删除指定的文件或目录(非空目录需先删除其中的所有子文件和子目录)。
    • 如果文件正在被另一个进程或线程访问,该方法可能无法成功删除文件。
    • 调用该方法后,删除操作立即执行,若失败则会抛出异常。
  2. deleteOnExit() 方法:

    • 注册一个请求,指示在虚拟机终止时(当Java应用程序正常退出时)应该删除指定的文件。
    • 这种方法适用于你希望在程序退出时清理临时文件或日志文件等资源,但不想在程序运行过程中因删除文件导致的问题而影响程序逻辑。
    • 使用此方法时,即使在删除文件时发生异常,也不会立即抛出异常,而是等到JVM关闭时再尝试删除。

所以,是否选择deleteOnExit()取决于你的具体需求。如果你需要立即且确定地删除文件,应使用delete()方法;如果你希望在程序结束时清理某个文件,同时允许在程序运行过程中继续使用该文件,可以考虑使用deleteOnExit()方法。但请注意,deleteOnExit()方法注册的待删文件数量过多或文件较大,可能会消耗较多系统资源,应在适当场景下谨慎使用。

delete()就不过多演示,这里演示一下deleteOnExit()方法

 public static void main(String[] args) throws IOException {
        File file = new File("./work.txt");
        file.deleteOnExit(); 
         /为了演示,这里让程序暂停一会儿,以便观察文件是否被删除
        try {
            Thread.sleep(5000);
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
       // 请注意,这段代码不会立即删除文件,文件将在JVM退出时删除
        System.out.println(file.exists());

    }
创建目录
 public static void main(String[] args) {
        File dir = new File("./testDir/aaa/bbb/ccc/ddd");
        // mkdir 只能创建出一级目录
        // dir.mkdir();
        // 可以创建多级目录
        dir.mkdirs();
        System.out.println(dir.isDirectory());
    }

 2.Java通过使用流来对文件内容进行操作

Java主要通过字节流 和 字符流 来对文件内容进行操作

1. 字节流 vs 字符流
1.字节流 (Byte Streams)

字节流用于处理二进制数据,它们不关心数据的编码或字符集。字节流可以处理任何类型的数据,包括文本、图片、视频等。字节流在Java中由java.io包提供,主要的类有:

  • InputStream: 字节输入流的基类。(抽象类)
  • OutputStream: 字节输出流的基类。(抽象类)
  • FileInputStream: 用于从文件中读取字节的类。
  • FileOutputStream: 用于向文件中写入字节的类。
2.字符流 (Character Streams)

字符流用于处理文本数据,它们处理的是字符而不是字节。字符流可以自动处理不同平台间的字符编码差异。字符流在Java中由java.io包提供,主要的类有:

  • Reader: 字符输入流的基类。(抽象类)
  • Writer: 字符输出流的基类。(抽象类)
  • FileReader: 用于从文件中读取字符的类。
  • FileWriter: 用于向文件中写入字符的类。
3.区别
  1. 处理数据类型: 字节流处理二进制数据,字符流处理文本数据
  2. 编码问题: 字符流可以自动处理字符编码,而字节流不关心编码。
  3. 效率: 字节流通常比字符流更高效,因为它们直接处理字节,不需要进行字符编码转换。
  4. 使用场景: 字节流适用于处理非文本文件,如图片、音频、视频等;字符流适用于处理文本文件。
 2.使用字节流对文件内容操作
1.InputStream的使用(从文件读取数据)
InputStream 只是⼀个 抽象类 ,要使⽤还需要具体的实现类。关于 InputStream 的实现类有很多,基 本可以认为不同的输⼊设备都可以对应⼀个 InputStream 类,我们现在只关⼼ 从⽂件中读取 ,所以使 ⽤ FileInputStream.
由于读取数据时所设置的参数不同,所以就可以大概分为三种方法
1.read()方法不带参数
  public static void main(String[] args)  {
      try(InputStream in = new FileInputStream("hello.txt")) {
          while (true) {
              int b = in.read();
              if(b == -1) {
                  //读取完毕
                  break;
              }
              System.out.printf("0x%X ", b);
          }
      }catch (IOException e) {
          e.printStackTrace();
      }
    }

几个需要解释的地方

1.try(InputStream in = new FileInputStream("hello.txt") 这里的hello.txt 需要我们提前准备好模拟接收到文件的过程.所以里面需要写好一些数据,同时这里使用 try()是因为 InputStream 实现了Closeable 接口,可以让系统帮你关闭文件.防止你忘记关闭文件,或者可能因为别的原因没有关闭文件导致,出现问题

2.这里的 int b 是in.read()的返回值 如果成功读取到了字节,则返回该字节对应的十进制数值(范围是0-255,因为一个字节有8位,最高位为符号位,实际能表示的无符号整数范围是0-255)。但如果已经到达了流的末尾,也就是文件的结尾,并且没有更多的数据可供读取时,read()方法会返回-1

2.read()方法带参数
public static void main(String[] args) {
        try(InputStream in = new FileInputStream("hello.txt")) {
            byte[] bytes = new byte[1024];
            int n = in.read(bytes);
            for (int i = 0; i < n; i++) {
                System.out.printf("0x%x ", bytes[i]);
            }

        }catch (IOException e) {
            e.printStackTrace();
        }
    }

几个需要解释的地方

1.定义一个大小为1024的字节数组bytes,用于存放从文件中读取的数据。数组的大小决定了每次读取的最大字节数。意思就是不是一个字节的读了,而是一次性读最多读1024个字节,如果超过1024个字节,可以写一个循环,循环读取,直到 n = -1;

while ((n = in.read(bytes)) != -1) {
    for (int i = 0; i < n; i++) {
        System.out.printf("0x%x ", bytes[i]);
    }
}

2.带参数的方法,还可以控制,每次读取操作的起始位置和读取长度可以更精细的控制其他的和别的方法无太多差别.

int read(byte[] b, int off, int len)
2.OutputStream的操作(从文件中写入数据)
 1.write()方法
public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("hello.txt",true)) {
            outputStream.write(97);
            outputStream.write(100);
            outputStream.write(99);
            outputStream.write(98);
            System.out.println("写入完毕");
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

 几个解释的地方

1.OutputStream outputStream = new FileOutputStream("hello.txt",true) ,这里除了加上了相对路径,后面还有一个参数为 true,这里要是没设置,就默认为false 也就是如果为true 就可以在原来的文件内容后面加上你写入的内容,如果为false 就直接先清空了之前的内容了,再写入了.

2.outputStream.write(97);这里写入的数字是 ascii

3.这里写入数据也可以不用一个一个的写入可以使用byte数组,一次性将数组内的数据写入到文件中.同时也一样可以精准控制,这里就不过多的介绍了. 

3.使用字符流对文件内容操作
1.Reader的使用
1.read()方法
 public static void main(String[] args) {
        try(Reader reader = new FileReader("hello.txt")) {
            while(true) {
                int n = reader.read();
                if(n == -1) {
                    break;
                }
                char ch = (char) n
                System.out.println(ch);
            }

        }catch (IOException e) {
            e.printStackTrace();
        }
    }

几个解释的地方

1.Reader reader = new FileReader("hello.txt")一样继承了closeable 接口可以使用try()的方法来自动关闭文件.

2.read()方法不同参数也一样可以一个一个字符的读取,也可以一个char数组的形式读取这里就不演示了

 2.Writer的使用
1.writer
 public static void main(String[] args) {
        try(Writer writer = new FileWriter("hello.txt",true)) {
            writer.write("你好CSDN");
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

 和上述的内容没什么差别,就是write的参数不一样,根据实际情况选择相应的参数

二.根据文件IO操作和流操作的知识解决问题的案例

这里主要是通过三个案例来巩固一下文件IO和流操作的知识

1.案例一: 

扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录).

 public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要查找的目录的路径: ->");
        String rootPath = scanner.next();
        System.out.println("请输入你要查找的普通文件的单词: ->");
        String fileWord = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isDirectory()) {
            System.out.println("路径非法请重新在输入");
            return;
        }
        search(rootFile,fileWord);
    }
    private static void search(File file,String str) {
        //列出当前的有哪些文件
        File[] files = file.listFiles();
        if(files == null) {
            return;
        }
        for(File f : files) {
            if(f.isFile()) {
                String fileName = f.getName();
                if(fileName.contains(str)) {
                    System.out.println("找到了" + f.getAbsolutePath());
                }
            }else if(f.isDirectory()) {
                search(f,str);
            }
        }
    }

主要逻辑

  1. 主方法(main)启动时,通过Scanner类从控制台接收用户输入的两个参数:

    • rootPath:指定需要搜索的目录路径。
    • fileWord:用户想要在文件名中查找的特定单词。
  2. 创建一个File对象rootFile,其路径为用户输入的rootPath。接着,检查rootFile是否为一个有效的目录。若不是,输出错误提示信息并直接结束程序运行。

  3. rootFile确实是一个目录,调用私有方法search进行递归文件搜索。该方法接受两个参数:当前处理的目录(file)和待查找的单词(str)。

  4. search方法内部,首先使用listFiles()获取当前目录下的所有文件及子目录(以File数组形式返回)。如果返回值为null,说明目录为空或无权限访问,此时直接返回。

  5. 遍历得到的File数组,对于每个元素:

    • 如果是普通文件(isFile()返回true),则提取其文件名,检查是否包含用户指定的str。如果包含,输出该文件的绝对路径,表示已找到匹配文件。
    • 如果是目录(isDirectory()返回true),则递归调用search方法,继续在该子目录中查找含有指定单词的文件。

2.案例二:

进行普通文件的复制
public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要复制的文件路径");
        String rootPath = scanner.next();
        System.out.println("请输入你要复制到那个文件的目标路径");
        String destPath = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isFile()){
            System.out.println("复制的文件路径非法");
            return;
        }
        File destFile = new File(destPath);
        if(destFile.getParentFile().isDirectory()) {
            System.out.println("输入的复制目标路径非法");
            return;
        }
        try(InputStream inputStream = new FileInputStream(rootPath);
            OutputStream outputstream = new FileOutputStream(destPath)) {
            while (true) {
                byte[] bytes = new byte[1024];
                int n = inputStream.read(bytes);
                if(n == -1) {
                      break;
                  }
                outputstream.write(bytes,0,bytes.length);
            }
        }catch(IOException e) {
            e.printStackTrace();
        }

    }
  1. 使用Scanner类从控制台接收用户输入的两个路径:

    • rootPath:用户要复制的源文件路径。
    • destPath:用户指定的目标文件路径。
  2. 创建一个File对象rootFile,其路径为用户输入的rootPath。接着,检查rootFile是否为一个有效的文件(非目录)。若不是,输出错误提示信息并直接结束程序运行。

  3. 同样创建一个File对象destFile,其路径为用户输入的destPath。接下来,检查destFile的父目录是否存在且为目录。若不符合条件(即父目录不存在或非目录),输出错误提示信息并返回。

  4. 使用try-catch结构处理可能出现的IOException。在try块内,创建InputStreaminputStream)和OutputStreamoutputstream)对象分别用于读取源文件和写入目标文件。这里使用FileInputStreamFileOutputStream构造函数传入对应的路径。

  5. 使用无限循环(while (true))逐块读取源文件内容并写入目标文件。每次读取1024字节(byte[] bytes = new byte[1024];),通过inputStream.read(bytes)方法读取数据并返回实际读取的字节数(n)。

  6. 将读取的数据块写入目标文件:outputstream.write(bytes, 0,n);将读取的数据写入到要复制的目标文件中

  7. 如果n = -1 就代表以读取完成,退出循环

3.案例三:

扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件 

 public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要查找的目录的路径: ->");
        String rootPath = scanner.next();
        System.out.println("请输入要查询的单词: ->");
        String fileWord = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isDirectory()) {
            System.out.println("路径非法请重新在输入");
            return;
        }
        search(rootFile,fileWord);
    }
    private static void search(File file,String str) {
        //列出当前的有哪些文件
        File[] files = file.listFiles();
        if(files == null) {
            return;
        }
        for(File f : files) {
            if(f.isFile()) {
                machWord(f,str);
            }else if(f.isDirectory()) {
                search(f,str);
            }
        }
    }
    private static void machWord(File f,String str) {
        try(Reader reader = new FileReader(f)) {
            StringBuilder ret = new StringBuilder();
            while(true) {
                int n = reader.read();
                if(n == -1) {
                    break;
                }
                ret.append((char) n);
            }
            if(ret.indexOf(str) >= 0) {
                System.out.println("找到了" + f.getAbsolutePath());
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

  1. 主方法(main)启动时,通过Scanner类从控制台接收用户输入的两个参数:

    • rootPath:指定需要搜索的目录路径。
    • fileWord:用户想要在文件内容中查找的特定单词。
  2. 创建一个File对象rootFile,其路径为用户输入的rootPath。接着,检查rootFile是否为一个有效的目录。若不是,输出错误提示信息并直接结束程序运行。

  3. rootFile确实是一个目录,调用私有方法search进行递归文件搜索。该方法接受两个参数:当前处理的目录(file)和待查找的单词(str)。

  4. search方法内部,首先使用listFiles()获取当前目录下的所有文件及子目录(以File数组形式返回)。如果返回值为null,说明目录为空或无权限访问,此时直接返回。

  5. 遍历得到的File数组,对于每个元素:

    • 如果是普通文件(isFile()返回true),则调用machWord方法检查该文件内容是否包含用户指定的str
    • 如果是目录(isDirectory()返回true),则递归调用search方法,继续在该子目录中查找含有指定单词的文件。
  6. 私有方法machWord负责检查单个文件内容是否包含查询单词。具体步骤如下:

    • 使用FileReader创建一个Reader对象,用于读取文件内容。
    • 初始化一个StringBuilder对象ret,用于存储文件内容。
    • 使用无限循环(while(true))逐字符读取文件内容。当reader.read()返回-1时,表明已到达文件末尾,此时跳出循环。
    • 将读取的字符追加到ret中。
    • 检查ret中的字符串是否包含查询单词str。如果包含,输出该文件的绝对路径,表示已找到匹配文件。
    • 使用try-catch结构捕获并打印可能抛出的IOException

感谢你的阅读,祝你一天愉快! 

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

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

相关文章

C++:const成员和取地址操作符

目录 一、const成员 二、取地址及const取地址操作符重载 一、const成员 将const修饰的“成员函数”称之为const成员函数&#xff0c;const修饰类成员函数&#xff0c;实际修饰该成员函数 隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何成员进行修改。 注&…

【JAVA】PO、VO、DAO、BO、DTO、POJO你分得清吗?

在Java开发中&#xff0c;PO、VO、DAO、BO、DTO、POJO这些词汇是比较常见的&#xff0c;每个术语都有其特定的含义和用途。下面是它们的具体区别&#xff1a; 名称简要概况用途和特定PO (Persistence Object) 持…

PDF 书签制作与调整 从可编辑、不可编辑 PDF 文档创建书签的方法

本文是对以前发表的旧文拆分&#xff0c;因为原文主题太多&#xff0c;过长&#xff0c;特另起一篇分述。 第一部分 由可编辑 PDF 文档创建书签 方法 1. Adobe Acrobat Pro autobookmark AutoBookmark 是一个可用于 Adobe Acrobat 自动生成书签的插件。 官方下载地址&…

手拉手安装Kafka2.13发送和消费消息

Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft&#xff0c;两种方式只能选择其中一种启动&#xff0c;不能同时使用。 Kafka下载https://downloads.apache.org/kafka/3.7.0/kafka_2.…

静态链接lib库使用

lib库实际上分为两种&#xff0c;一种是静态链接lib库或者叫做静态lib库&#xff0c;另一种叫做动态链接库dll库的lib导入库或称为lib导入库。这两个库是不一样的&#xff0c;很多人都分不清楚&#xff0c;很容易混淆。 第一种是静态lib&#xff0c;包含了所有的代码实现的&am…

回归预测 | Matlab实现SSA-ESN基于麻雀搜索算法优化回声状态网络的多输入单输出回归预测

回归预测 | Matlab实现SSA-ESN基于麻雀搜索算法优化回声状态网络的多输入单输出回归预测 目录 回归预测 | Matlab实现SSA-ESN基于麻雀搜索算法优化回声状态网络的多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SSA-ESN基于麻雀搜索算法…

2024/4/26 C++day4

1在Complex类的基础上&#xff0c;完成^&#xff0c;>>&#xff0c;<<,~运算符的重载 #include <iostream> using namespace std; class Complex {int rel; //实部int vir; //虚部 public:Complex(){}Complex(int rel,int vir):rel(rel),vir(vir){}vo…

小程序中如何快速给分类添加商品

​快速在分类下面上传商品&#xff0c;并且能够设置商品顺序&#xff0c;关系到运营效率的高低。下面就具体介绍如何快速在某个分类下面设置商品。 一、在商品管理处&#xff0c;查询某个分类下面的商品。 进入小程序管理员后台->商品管理&#xff0c;点击分类输入框&…

【汇编语言】直接定址表

【汇编语言】直接定址表 文章目录 【汇编语言】直接定址表前言一、移位指令移位指令过程逻辑移位指令shl 和 shr 二、操作显存数据显示的原理显示缓冲区的结构显示信息的一种“直接”方式 三、描述内存单元的标号关于标号去了冒号的数据标号数据标号同时描述内存地址和单元长度…

css:echarts渐变色转换为css渐变色

通过一个下拉框来选择渐变类型&#xff0c;为了简化&#xff0c;我设置了三种&#xff1a;水平方向的渐变、垂直方向的渐变和径向渐变用&#xff0c;表格来配置echarts渐变色的百分比位置和颜色。 config是表格里的数据格式如下&#xff1a; offset是百分比位置&#xff0c;co…

2024北京车展来了!自主品牌成“流量担当”!

时隔四年&#xff0c;2024北京国际车展重磅回归&#xff01; 4月25日&#xff0c;2024&#xff08;第十八届&#xff09;北京国际汽车展览会&#xff08;以下简称“北京车展”&#xff09;正式开幕&#xff0c;本次车展以“新时代 新汽车”为主题。作为今年国内首个国际A级车展…

Centos/linux根目录扩容、分区、挂载。LVM、物理卷、逻辑卷

前言    &#xff08;空格&#xff09; &#xff1a;分区挂载和扩容是两码事 每个Linux使用者在安装Linux时都会遇到这样的困境&#xff1a;在为系统分区时&#xff0c;如何精确评估和分配各个硬盘分区的容量&#xff0c;因为系统管理员不但要考虑到当前某个分区需要的容量&a…

使用 Godot 游戏引擎为 Apple 的 visionOS 创建游戏和应用的平台

借助GodotVision ,您可以使用Godot 游戏引擎为 Apple VisionOS创建游戏和应用程序。 保卫牛城堡,一款使用 GodotVision 制作的 VisionOS 游戏 GodotVision 运行一个控制本机RealityKit 视图的无头 Godot实例。粗略地说:Godot 是后端,

C++面向对象程序设计 - 派生类的构造函数和析构函数

构造函数的主要作用对数据成员初始化&#xff0c;基类的构造函数是不能被继承的&#xff0c;在声明派生类时&#xff0c;派生类并没有把类的构造函数继承下来。因此&#xff0c;对继承过来的基类成员初始化的工作也要由派生类的构造函数完成&#xff1b;所以在派生类中不仅要考…

OSPF的LSA与特殊区域

Area区域概念 *一个区域维护一张LSDB&#xff0c;路由器详细的链路信息只在这个区域内传播 不是每一台路由器都需要了解所有外部目的地的详细信息 *OSPF网络的层次化设计 通过区域ID标识 骨干&#xff08; Backbone &#xff09;区域&#xff0c;必须是area 0(骨干区域…

JVM(Jvm如何管理空间?对象如何存储、管理?)

Jvm如何管理空间&#xff08;Java运行时数据区域与分配空间的方式&#xff09; ⭐运行时数据区域 程序计数器 程序计数器&#xff08;PC&#xff09;&#xff0c;是一块较小的内存空。它可以看作是当前线程所执行的字节码的行号指示器。Java虚拟机的多线程是通过时间片轮转调…

milvus对象存储和消息中间件的工厂设计模式分析

milvus对象存储和消息中间件的工厂设计模式分析 需求 根据参数设置创建mq和storage mq有kafka,pulsar storage有local,minio,remote 配置文件 根据配置文件选择初始化mq和存储: mq:type: pulsarcommon:storageType: minio对于这种类型一个是mq&#xff0c;一个是存储&…

抓住四月小尾巴,拿个offer~

首先声明一下~本人是个双非二本大三在校生。 从三月份就开始了苦哈哈的找实习之旅&#xff0c;快三月中旬才敢投大厂&#xff0c;为什么嘞&#xff1f;因为学校要求必须参加完期末考试才能出去实习&#xff08;差不多七月初&#xff09;&#xff0c;因为这个好多公司一听就不安…

算法模版自用(杂)

文章目录 算法库函数next_permutation(start,end) prev_permutation(start,end) (全排列函数)nth_element &#xff08;求第k小值&#xff09;next(it,num),prev(it,num)min_element(begin(),end()),max_element(begiin(),end()) (取最小值最大值) _int128的输入输出STLlist 数…

serdes 同轴电缆和双绞线接法

1、同轴电缆 Coaxial Cable 2、双绞线STP&#xff08;Shielded Twisted Pair&#xff09; 比如我们用的车载camera一般就只需要接一路即可&#xff0c;RIN接camera&#xff0c; RIN-通过电容接地。