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

˃͈꒵˂͈꒱ 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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】error LNK2001: 无法解析的外部符号 “__declspec(dllimport)

参考&#xff1a;Qt/VS LNK2019/LNK2001&#xff1a;无法解析的外部符号_qt lnk2001无法解析的外部符号-CSDN博客 微软官方报错文档-链接器工具错误 LNK2019 __declspec error LNK2001: 无法解析的外部符号 "__declspec(dllimport) 原因 以这种为前缀的基本上跟库相关…

Visual Studio安装MFC开发组件

MFC由于比较古老了&#xff0c;Visual Studio默认没有这个开发组件。最近由于一些原因&#xff0c;需要使用这个库&#xff0c;这就需要另外安装。 参考了网上的一些资料&#xff0c;根据实际使用&#xff0c;其实很多步骤不是必须的。 https://zhuanlan.zhihu.com/p/68117276…

HarmonyOS开发实战(黑马健康系列一:欢迎页)

系列文章目录 &#xff08;零&#xff09;鸿蒙HarmonyOS入门&#xff1a;如何配置环境&#xff0c;输出“Hello World“ &#xff08;一&#xff09;鸿蒙HarmonyOS开发基础 &#xff08;二&#xff09;鸿蒙HarmonyOS主力开发语言ArkTS-基本语法 &#xff08;三&#xff09;鸿蒙…

沐风老师3DMAX一键相框生成插件安装使用方法教程

3DMAX一键相框生成插件使用教程 3DMAX一键相框生成插件&#xff0c;用于根据导入的图像文件以正确的比例从选定的图像中快速创建相框。只需点击几下鼠标&#xff0c;它就可以同时创建多个相框&#xff0c;在尺寸、轮廓、颜色和玻璃方面有许多选项。 支持Corona、Vray和标准材质…

Java基础(运算符)

运算符 运算符和表达式 运算符&#xff1a;对字面量或者变量进行操作的符号 表达式&#xff1a;用运算符把字面量或者变量连接起来&#xff0c;符合java语法的式子就可以称为表达式&#xff1b;不同运算符连接的表达式体现的是不同类型的表达式。 算术运算符&#xff08;加…

Unity 按下Play键后,Scene View里面一切正常,但是Game View中什么都没有 -- Camera Clear Flags的设置

问题如下所示。 最先遇到这个问题是我想用Unity开发一个VR 360-degree Image Viewer。在Scene View中可以看到球体&#xff0c;但是Game View什么都看不到。最后找到的原因是&#xff0c;我使用的shader是Skybox/Panorama&#xff0c; 需要把Main Camera的Clear Flags设置成Do…

灌区信息化解决方案-大型灌区信息化改造

系统方案 灌区信息化解决方案主要对灌区的水情、渠道流量、土壤墒情、气象等信息进行监测&#xff0c;对重点区域进行视频监控&#xff0c;同时对泵站、闸门进行远程控制&#xff0c;实现信息的测量、统计、分析、控制、调度等功能。为灌区管理部门科学决策提供了依据&#xff…

多组学+机器学习+膀胱癌+分型+建模

这是一个基于多组学机器学习的分型建模文章&#xff0c;这里我们大概介绍一下&#xff0c;这篇文章做了啥 一、研究背景 1、尿路上皮癌是高度恶性的肿瘤&#xff0c;预后差&#xff0c;死亡率高 2、没有明显有效的治疗方法&#xff0c;多数患者在免疫治疗中无法受益&#xf…

Java混淆的重要性

在软件开发领域&#xff0c;安全性与代码保护一直是备受关注的问题。特别是在Java这样的跨平台语言中&#xff0c;保护源代码的机密性和完整性显得尤为重要。Java混淆作为一种代码保护技术&#xff0c;其在现代软件开发中的地位日益凸显。本文将详细探讨Java混淆的重要性&#…

【网络安全】网络安全协议和防火墙

目录 1、网络层的安全协议&#xff1a;IPsec 协议族 &#xff08;1&#xff09;IP 安全数据报格式 &#xff08;2&#xff09;互联网密钥交换 IKE (Internet Key Exchange) 协议 2、运输层的安全协议&#xff1a;TLS 协议 3、系统安全&#xff1a;防火墙与入侵检测 1、网络…

addr2line + objdump 定位crash问题

目录 背景 godbolt汇编工具 tombstone ARM平台汇编知识 寄存器介绍 常见汇编指令 函数入参及传递返回值过程 入参顺序 变参函数 虚函数表 典型问题分析过程 Crash BackTrace Addr2line objdump 拓展 为什么SetCameraId函数地址偏移是40(0x28) 参考 背景 最近在…

kerberos:介绍

文章目录 一、介绍二、kerberos框架1、名词解释2、框架 三、优缺点四、其他认证机制1、SSL2、OAuth3、LDAP 一、介绍 Kerberos是一种计算机网络授权协议&#xff0c;主要用于在非安全网络环境中对个人通信进行安全的身份认证。这个协议由麻省理工学院&#xff08;MIT&#xff…

软考-系统分析师-精要1

1、什么是软件需求 软件需求是指用户对系统在功能、行为、性能、设计约束等方面的期望。 软件需求是指用户解决问题或达到目标所需的条件或能力&#xff0c;是系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或能力&#xff0c;以及反映这些条件或能力…

Leetcode 118 杨辉三角

目录 一、问题描述二、示例及约束三、代码方法一&#xff1a;数学 四、总结 一、问题描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。   在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 二、示例及约束 示例 1&#xff1a…

电子防潮柜出厂前要经过哪些测试?

电子防潮柜在发货前应执行一系列质量控制测试以确保其功能正常、性能稳定且能够满足用户存储物品对湿度控制的需求。以下是沐渥电子防潮柜出厂前的测试流程&#xff1a; 1&#xff09;除湿性能测试&#xff1a;检查并验证防潮柜能否按照设定的湿度目标值准确运行&#xff0c;可…

燃冬之yum、vim和你

了解了很多指令和权限&#xff0c;搞点真枪实弹来瞅瞅 学Linux不是天天就在那掰扯指令玩&#xff0c;也不是就研究那个权限 准备好迎接Linux相关工具的使用了么码农桑~ yum 软件包 什么是软件包呢&#xff1f; 首先来举个生活中常见点的例子&#xff1a;比如我的手机是华为…

盘点数据资产管理十大活动职能 优化企业数据资产管理和应用

在当今的数字化时代&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;在上篇文章中我们对数据资产管理进行了初步的介绍。 上篇文章指路&#x1f449;什么是数据资产管理&#xff1f;详谈数据资产管理的难点与发展现状&#xff01; 有效的数据资产管理不仅能提升企业的…

【JAVA】阿里技术官耗时三个月整理的Java核心知识点

在裁员风波的席卷之下&#xff0c;IT行业弥漫着浓厚的焦虑和不安。面对如此动荡的环境&#xff0c;一个共识日益凸显&#xff1a;提升个人价值至关重要。 这不仅仅是指薪资上的数字增长&#xff0c;更重要的是在职场中、在专业领域、在技术上不断取得突破&#xff0c;并塑造自…

固态继电器:推进可再生能源系统

随着可再生能源系统的发展&#xff0c;太阳能系统日益成为现代能源解决方案的先锋。在这种背景下&#xff0c;固态继电器&#xff08;SSR&#xff09;&#xff0c;特别是光耦固态继电器的利用变得日益突出。本文旨在深入探讨SSR在可再生能源系统中的多方位应用&#xff0c;重点…

ClickHouse 数据类型、表引擎与TTL

文章目录 数据类型注意事项 表引擎1.TinyLog 引擎2.MergeTree 引擎3.ReplacingMergeTree 引擎4.AggregatingMergeTree 引擎5.SummingMergeTree 引擎6.CollapsingMergeTree 引擎7.Distributed 引擎 TTL列级 TTL表级TTL 数据类型 ClickHouse 数据类型Java 数据类型数据范围UInt8…