Java 文件操作 和 IO(3)-- Java文件内容操作(1)-- 字节流操作

article/2025/8/21 15:48:20

Java 文件操作 和 IO(3)-- Java文件内容操作(1)-- 字节流操作

文章目录

  • Java 文件操作 和 IO(3)-- Java文件内容操作(1)-- 字节流操作
  • 观前提醒:
  • 1. Java中操作文件的简单介绍
  • 2. Java文件内容操作--字节流
    • 2.1 流概念的介绍 和 输入输出
      • 流:
      • 输入输出:
    • 2.2 针对字节流对象的两个类的演示
      • 2.2.1 字节流:InputStream类(输入)
        • 2.2.2.1 打开文件
        • 2.2.2.2 关闭文件
        • 2.2.2.3 try with resource 语法的简单介绍
        • 2.2.2.4 不关闭文件会造成的后果
        • 2.2.2.5 读取文件的操作(三种 read方法)
      • 2.2.2 字节流:OutputStream类(输出)
        • 写文件的操作(三种 write方法):
          • 1. 带 int 参数的 write()方法
          • 2. 带 byte[ ] 参数的 write( )方法
          • 3. 带 三个参数的 write( )方法
          • 遗留的问题
        • 文件写入覆盖 和 文件追加写入
  • 3. 总结

观前提醒:

在看这篇博客之前,建议你先看完这两篇博客:

Java 文件操作 和 IO(2)-- Java文件系统操作

Java 文件操作 和 IO(1)-- 文件相关知识背景介绍


在讲Java文件内容操作之前,我们还是需要再来看看,java当中,操作文件的简单介绍,知道文件操作的区分,脑里有个大概的图,才能更好的理解这部分的知识!

1. Java中操作文件的简单介绍

使用java来操作文件,主要是通过java标准库提供的一系列的类,而这些类,又可以分为两种操作方向

  1. 文件系统操作
    这里主要是关于 文件 或 目录 的创建,文件的删除,文件的重命名,创建目录等…

  2. 文件内容操作
    这里就是对某一个具体的文件的内容进行读和写了,又由于文件有两种种类,所以,我们又区分了字节流操作和字符流操作。
    (1)字节流:读写文件,以字节为单位,是针对二进制文件使用的。
    (2)字符流:读写文件,以字符为单位,是针对文本文件使用的。

用一张图来看的话,是这样的:
在这里插入图片描述
这篇博客里面,讲的是文件内容操作中的字节流操作,下一篇博客,Java 文件操作 和 IO(4)-- Java文件内容操作(2)-- 字符流操作 讲的文件内容操作中的 字符流操作

2. Java文件内容操作–字节流

2.1 流概念的介绍 和 输入输出

流:

Java中,针对某一个文件中的内容的操作,主要是通过一组 “ 流对象 ” 来实现的。

那么,问题来了,什么叫做 ‘ 流 ’ ?
首先,‘流’这个词呢,本身就是一个很形象的比喻。
讲到流,我们第一反应,应该可以想到 ‘水流’,那么,水流有什么特点呢?延绵不绝,连续不断。

比如:我现在要接 100ml的水
我可以 1 次性的把 100ml的水接完
也可以分 2 次,一次接50ml
也可以分 10 次,一次接10ml
也可以分 100 次,一次接 1 ml
… … … …
所以,综上所述,我们可以有无数种接水的方式。

那么,计算机当中的流 和 水流中的流,是非常相似的

比如:我现在要从某一个具体的文件当中读取 100个字节 的数据(就像现在要接 100ml的水一样)
我可以 1 次性的把 100个字节的数据,全都读取出来
也可以分 2 次,一次读取 50个字节的数据
也可以分 10 次,一次读取 10个字节的数据
也可以分 100 次,一次读取 1个字节的数据
… … … …
所以,综上所述,读取数据的方式,我们也有无数种的方式。

正因为,我们从文件中读写数据的特点,和水流的特点,非常相似,所以就发明了流这个说法。

因此,计算机中,针对读写文件,也是使用了流(Stream)这样的词来表示。

这个说法,是操作系统层面相关的数据,和语言无关,比如:java当中,文件中的流,C语言中,文件中的流,C++中,文件中的流,都是一样的。
所以,各种编程语言操作文件,都叫 “流”。

那么,Java当中,提供了一组类,来表示流,有多少个呢?几十个!!!
但是,我们并不需要学习全部,在 本篇博客 和 Java 文件操作 和 IO(4)-- Java文件内容操作(2)-- 字符流操作中,我们主要介绍其中的 8个就行。
不要因为看到要学 8个类,就慌了,因为,文件内容操作这块,比起文件系统操作这块,好学很多,因为这八个类所提供的方法都是类似的,比较有规律,你学懂了其中的一个类,其他的,都大差不差。

针对上述所说的几十个类,又分成了两个大的类别:

  1. 字节流:读写文件,以字节为单位,是针对二进制文件使用的。
    其中,关于字节流的类中,典型的代表有:InputStream类(输入) 和 OutputStream类(输出)
  2. 字符流:读写文件,以字符为单位,是针对文本文件使用的。
    其中,关于字符流的类中,典型的代表有:Reader类(输入) 和 Writer类(输出)

输入输出:

讲到这,我们得聊一聊,什么叫做输入,什么叫做输出?
首先,我们需要明确的知道一个点:输入输出,是以 CPU 作为参考点的。

输入输出,讲的就是以 CPU 为参考点,来看数据的流向:
硬盘 → CPU 的,叫做 输入
CPU → 硬盘 的,叫做 输出

在这里插入图片描述

举个这样的例子,你可能就会容易记点:把CPU想象成你的嘴巴,硬盘可以想象成食物的来源之类的,那么,你吃东西的时候,食物从你的嘴巴进入( 硬盘 → CPU),是不是就叫做 摄入食物(输入),嘴巴把 食物吐出来(CPU → 硬盘),是不是就叫做 吐出食物(输出)

输入:就是从文件(存储在硬盘当中的文件)当中 数据,到 CPU当中。
输出:就是CPU往文件(存储在硬盘当中的文件)当中数据。

一定要搞清楚,输入,输出,读,写,这四个词的意思和他们之间的区别,这对于你学习计算机是很有帮助的。

2.2 针对字节流对象的两个类的演示

字节流操作,主要是两个类:InputStream类OutputStream类
在讲这两个类之前,我们需要知道,这两个类的共同点:
两个类,全部都是抽象类!!!

在这里插入图片描述

抽象类有个非常大的特点:这个类,不能够实例化对象,也就是说,无法通过new关键字,创建一个对象。如图:
在这里插入图片描述
那么,我们该如何去实例化对象呢?
我们通过这两个类的子类:FileInputStream类FileOutputStream类,来实例化 InputStream类OutputStream类 这两个类的对象(通过实例化(new)父类的子类对象,传给父类的引用,这叫做向上转型,在多态的博客中详细介绍了)
如图:
在这里插入图片描述
详细的介绍呢,我们就在每个类的单独介绍中再讲。

学习这两个类之前,我们需要知道,InputStream类OutputStream类,都是抽象类,抽象类,不能够实例化本类的对象,必须通过new子类对象来进行使用。

2.2.1 字节流:InputStream类(输入)

InputStream类是一个抽象类,本身不能够实例化对象,需要用它的子类对象,来实例化对象。
InputStream类的子类,有很多,我们本篇博客使用的是:FileInputStream类。
FileInputStream类是针对二进制文件进行读操作的一个类。

在这里插入图片描述

使用 FileInputStream类 实例化对象的注意点

1. 实例化对象的时候,我们需要传入参数

传入的参数,可以是一个路径,绝对路径,相对路径都可以,也可以是一个File对象(如何创建一个File对象,并把File对象,作为参数,在Java 文件操作 和 IO(2)-- Java文件系统操作已经讲过了)
这一块,我的演示就以相对路径:"./test.txt",作为例子,表示当前的项目路径下的 test.txt 文件。
在这里插入图片描述

2. 使用FileInputStream类的时候,我们需要处理一个异常 FileNotFoundException

如果你当前传入的这个路径,计算机没有找到文件,就会抛出这个异常。

在这里插入图片描述
这里处理异常的方式,直接在main( )方法 的后面 加 throws FileNotFoundException,或者使用 catch捕捉异常,就可以了,抛出异常时,交给JVM处理就行(这块不懂的,可以看看我写的JAVA 异常)。

2.2.2.1 打开文件
InputStream inputStream = new FileInputStream("/test.txt");

一旦这条语句,执行成功,也就是,创建对象的操作,一旦成功,就相当于“ 打开文件 ”这个的操作。

进行文件操作,不是一上来就能进行读写操作的,而是需要先打开,然后才能进行读写操作,这个是由操作系统定义的流程,也就是说,不同的编程语言,进行文件内容操作的时候,都是需要走这个流程的。

你可以认为,这句代码所表示的打开文件操作,就是根据你传入的 文件路径File对象 所对应的路径,定位到计算机的硬盘空间中的某一个文件,然后打开

2.2.2.2 关闭文件

我们先不着急对文件内容进行读写操作,我们还需要讲一下,与打开文件相对应的
关闭文件 ” 操作。

打开 相当于从系统中申请一块资源,关闭 就相当于释放资源,这样的操作,是C++代码经常有的操作。

关闭文件,我们使用的是: close()方法。

inputStream.close();

使用 close()方法还需要注意一个点:处理IOException异常
在这里插入图片描述

这里还需要知道一点:IOException异常是 FileNotFoundException异常的父类,当我们处理IOException异常的时候,其实,等同于把FileNotFoundException异常也解决了。
在这里插入图片描述
但是,你光是写了 close()方法 还不够,我们还必须要让 close()方法 执行成功!!!
比如,当我们这个程序中,写了一个 return语句,导致了 包含的close()方法 的一系列代码,没有执行,也就是没有执行 关闭文件的操作,也是不行的!!!
在这里插入图片描述

那么,如何确保close()方法,一定会执行呢?
使用 finally 关键字

finally关键字,在JAVA 异常这篇博客有详细的介绍到,大家可以跳转过去看看。

但是,有 finally 就一定可以了吗?
在这里插入图片描述
注意:try代码块里面的代码,和finally代码块里面的代码,并不是共用的

此时需要把变量的声明,放到 try 代码块的上面(外边),定义成 null。
在这里插入图片描述

现在的这段代码,就可以完完全全的确保,close()方法(文件关闭操作),一定会被执行到了

但是,写到这,这个代码虽然能解决问题,但是,它又引入了一个新的问题:代码不美观!代码太丑,也不行!

这时,就需要引入一个语法,叫做:try with resource 语法

2.2.2.3 try with resource 语法的简单介绍

try with resource 的语法是怎么样的呢?

我们先看我们写过的代码:

public class demo1 {public static void main(String[] args) throws IOException {InputStream inputStream = null;try {inputStream = new FileInputStream("/test.txt");}finally {inputStream.close();}}
}

然后,我把一部分代码注释掉,用 try with resource 语法,来等效的替换它。

public class demo1 {public static void main(String[] args) throws IOException {//        InputStream inputStream = null;
//        try {
//             inputStream = new FileInputStream("/test.txt");
//        }finally {
//            inputStream.close();
//        }try(InputStream inputStream = new FileInputStream("/test.txt")) {}}
}

在这里插入图片描述
这就是 try with resource 的语法演示。

具体语法如下:

try (ResourceType resource = new ResourceType()) {
// 使用资源
} catch (ExceptionType e) {
// 处理异常
}

try with resource 语法,就是把需要进行关闭的资源(需要执行关闭操作 close方法 的类),放到 try 后面的括号里面,只要出了 try 的代码块,就会自动调用该资源的 close方法。
这个语法,不仅可以达到关闭文件资源的操作,而且,也简化了代码,使代码看起来更加美观!

但是,也不是所有的类,都可以使用 try with resource 语法(需要执行关闭操作的类放到 try 后面的括号里面去的()),这里有一个要求:要求这个类,需要实现 Closeable接口!!!

比如:我们这里示范的这个 InputStream类,它是实现了 Closeable接口,才可以使用 try with resource 语法的
在这里插入图片描述

为什么必须要求这个类实现 Closeable接口 才能使用 try with resource 语法呢?
我们 Ctrl + 鼠标 点击 Closeable接口,可以看到,这个Closeable接口里面,就只有一个方法:close()方法

所以说,使用 try with resource 语法 的前提这个类 实现了 Closeable接口约定好这个类,一定有 close()方法,从而在出了 try 代码块之后,可以让 JVM 自动调用 close()方法!!!

这个 try with resource 语法,try括号后面,还可以写多个对象,不同对象之间,使用 ;进行分开。如:
在这里插入图片描述

总结: try with resource 语法,十分建议大家重点掌握,如果你未来是从事开发岗位或者其他岗位,这种简洁的代码语法,是十分常用的。

在下面的代码演示中,我会以 try with resource 语法 的形式,进行文件的打开和关闭操作。

2.2.2.4 不关闭文件会造成的后果

Java 当中,我们对于关闭操作,可能见的就比较少了,但对于 C++ 来说,确实用的非常多

C++当中,申请内存,释放内存,这是 C++程序员日常写程序需要思考的问题。这就相当于 你开的车是手动挡,需要不停的踩离合,挂挡。
Java当中,只需要申请内存就可以了,释放的话,交给 GC(‌GC(Garbage Collection)在Java中指的是垃圾收集或垃圾回收机制‌) 来处理就可以了。这就相当于 你开的车是自动挡,只需要踩油门,踩刹车就可以了。

但是 文件资源是文件资源,内存资源是内存资源,也就是说:文件资源 不等同于 内存资源
虽然 GC 能够自动管理内存资源,但是,不能够自动管理文件资源文件资源,需要我们手动释放!!!
如果不手动释放,就会引起“ 文件资源泄露 ”,类似于“ 内存泄漏 ”。有个特别形象的比喻叫做:占着茅坑不上厕所。

那么文件资源到底占用的是计算机中的什么资源呢?(这块的内容,看看就好了,知道有这么个东西就行)
在进程中,有一个描述进程的结构,叫 PCB,PCB中,有一个重要的属性,叫做文件描述符表(可以看作是一个固定长度的顺序表)。
每次程序打开一个文件,就会在文件描述符表中,申请一个表项(占个坑),如果光是打开,不关闭,就会使这里的文件描述符表中的表项,很快就会耗尽。耗尽了之后,如果你再次打开文件,就会打开失败!当前程序之后的很多逻辑,就会出现 bug。

相信大家或多或少的听过,Java当中,有自动扩容,那为什么不能给文件描述符表进行自动扩容呢?但是,站在内核的开发角度来说,自动扩容需谨慎!(这块的内容,也是看看就好了,知道有这么个东西就行)
内核里的每个操作,都是要给所有的进程提供服务的,如果你自动扩容的话,指不定你那次插入操作,刚刚好触发了自动扩容,导致这个的插入操作,耗费的时间很长,造成程序卡顿,对于用户来说,就会感觉到明显的卡顿。所以,进行自动扩容,这样就会进一步的加大内核操作中的不可控因素。
至于更详细的东西,这里就不展开讲了,有兴趣的可以自己去百度查一查。

但是,就算能够为文件描述符表自动扩容,也解决不了文件资源泄露的问题,因为文件资源泄露,是一个持续性的过程,而计算机的内存,也是有限的,为文件描述符表自动扩容一次,就会消耗一次内存资源,迟早有一天,内存资源也会耗光。

总结来说:关闭文件,非常非常重要!!

2.2.2.5 读取文件的操作(三种 read方法)

由于是第一次讲解对文件内容进行操作,会讲的比较细致一点,导致,这篇文章的字数太多,所以,我将 三种 read方法 的介绍,单独分离出来一篇博客:

字节流操作:InputStream类 读取文件的操作(三种 read 方法)

请你先看点击这个链接,跳转到另一篇博客中,看完那篇博客,再回来看下面的内容。

2.2.2 字节流:OutputStream类(输出)

OutputStream类是一个抽象类,本身不能够实例化对象,需要用它的子类对象,来实例化对象。
OutputStream类子类,有很多,我们本篇博客使用的是:FileOutputStream类。
FileOutputStream类是针对二进制文件进行写操作的一个类。

在这里插入图片描述
当然,针对 FileOutputStream类 的使用,同样需要注意两点:
1. FileOutputStream类的括号里面需要传入参数

传入的参数,可以是一个路径,绝对路径,相对路径都可以,也可以是一个File对象(如何创建一个File对象,并把File对象,作为参数,在Java 文件操作 和 IO(2)-- Java文件系统操作已经讲过了)

这里我就以 “ output.txt ” 为例子(就算你项目路径下没有这个文件,你使用OutputStream类的时候,也会自动创建,这个后面讲)
在这里插入图片描述
2. 需要处理异常

处理异常这里,就不细说了,和 InputStream类 开头介绍注意事项的处理异常那块所讲的大差不差。

写文件的操作(三种 write方法):

大前提:此处写文件的操作,写入的都是字节数据,写入到 output.txt 这个文本文件中,会自动解码,转换成有意义的文字信息。

1. 带 int 参数的 write()方法

在这里插入图片描述

这个方法表示的就是说:一次写入一个字节
没有返回值

应该有人会疑惑,不是写入一个字节吗?怎么括号里面的参数,怎么是 int类型的,不应该是 byte类型吗?

这是因为,在 java 开发过程中,在此处希望的参数的取值范围是 0~255,主要目的是和 InputStream类 中提供的 read()方法 相匹配。

如果使用的是 byte类型,作为参数的类型,那么这个参数的取值范围是:-128~127(至于为什么是这么个范围,这里就不展开讲了,自行百度即可),那么这个范围,和它对应的 read()方法 的范围:0~255,是不匹配的。
主要也是因为,java当中,没有 unsigned类型(有符号和无符号,C语言中的)。

演示操作:
我们就以 把 “ abc ” 三个字母output.txt 文件当中,并且,我当前的项目路径,是没有这个文件的
在这里插入图片描述

abc,这三个字母所对应的是 ASCII码中的 97,98,99。

演示代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class demo4 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("./output.txt")){
//            操作文件
//            向output.txt文件当中,写入 a,b,c 三个字母outputStream.write(97);outputStream.write(98);outputStream.write(99);} catch (IOException e) {throw new RuntimeException(e);}}
}

运行结果:
在这里插入图片描述
用红线划出的代码句,会有两种情况:
第一种:如果项目路径中,存在目标文件,则正常写入数据
第二种:如果项目路径当中,没有目标文件,则会自动创建出该文件,然后再写入数据。

在这里插入图片描述
自动创建出来的 output.txt 文件中,成功写入了 a,b,c 这三个英文字母。

2. 带 byte[ ] 参数的 write( )方法

在这里插入图片描述

括号里面的是 byte[ ] 数组的引用,可以是 b 也可以是 bytes ,是你创建 byte[ ] 数组时的引用。

此处的 byte[ ] 数组 ,存放的是要写入目标文件的数据

这里的演示,目的是把 c,b,a 这三个字母,按顺序的写入到 output.txt文件 当中。

演示代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class demo5 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("./output.txt")) {
//            操作文件
//            向output.txt文件当中,写入 a,b,c 三个字母byte[] bytes = new byte[]{99,98,97};outputStream.write(bytes);} catch (IOException e) {throw new RuntimeException(e);}}
}

运行结果:
在这里插入图片描述
成功地把 c,b,a 这三个字母,按顺序的写入到output.txt文件当中。

3. 带 三个参数的 write( )方法

在这里插入图片描述
这里的三个参数,和 InputStream类 当中的带三个参数的 read( )方法,是相似的。

byte[ ] 数组 :是你准备要写入目标文件的数据

int off :是数组下标,是你要从 byte[ ] 数组 的哪个数组下标开始进行写操作,可以对数组内的数据,选择性的写入文件。

int len:表示的是,你准备从 byte[ ]数组中,取多少(len)个字节的数据往目标文件中写入。

演示操作:

我这里有一个 字节数组 bytes,存放着 a, b, c, d, e 五个英文字母所对应的 ASCII值:97,98,99,100,101。
想在,我想从该数组的 1 下标开始进行写操作,只写 3 个字节大小的数据(一个英文字母,占一个字节的大小),也就是按顺序写入三个英文字母

最终的结果应该是:output.txt文件中,显示的是 b, c, d 这三个英文。

演示代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class demo6 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("./output.txt")) {//操作文件//创建字节数组,往里面存放数据 a, b, c, d, ebyte[] bytes = new byte[]{97,98,99,100,101};//从 1 下标开始进行写写操作,只写 3 个字节大小的数据outputStream.write(bytes,1,3);} catch (IOException e) {throw new RuntimeException(e);}}
}

运行结果:
在这里插入图片描述
数据写入完成。

遗留的问题

看到这,你应该是没有什么问题,也基本可以理解。

那不知道你有没有发现:每当我进行写操作的时候,上一次的数据,消失不见了呢?
在这里插入图片描述

文件写入覆盖 和 文件追加写入

对于文件写入操作来说,每一次程序所执行的写入操作,都是会清除上次程序执行写入操作所写入的文件内容的,也就是说,本次运行程序,写入的文件内容,再次执行程序后,会清除上次写入的文件内容,当打开文件(程序执行)的一瞬间,上次文件里面的内容,就会被清空了!!!

注意:这里的文件覆盖,指的是相同的写文件程序两次运行的结果!

这种现象,不仅仅是Java的有,C语言的文件操作中,按照写方式(写入操作)来打开文件,也会有同样的现象产生。

这种现象,是操作系统的行为你使用什么语言来进行文件操作是没有关系的。

那么,如何让文件内容不清空,能够让我们继续写呢?
我们可以采取追加写的模式,避免文件内容被清空

追加写模式:在new OutputStream对象的时候,往括号里面写上一个 true,就表示采用追加写模式了,平常不写true的时候,默认是false

在这里插入图片描述
此时,我们再一次执行代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class demo6 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("./output.txt",true)) {//操作文件//创建字节数组,往里面存放数据 a, b, c, d, ebyte[] bytes = new byte[]{97,98,99,100,101};//从 1 下标开始进行写写操作,只写 3 个字节大小的数据outputStream.write(bytes,1,3);} catch (IOException e) {throw new RuntimeException(e);}}
}

运行结果:
在这里插入图片描述
注意:追加写模式,说的是两次程序运行的结果。
也就是说,追加写模式,是让上次程序执行写文件操作所写入的文件内容,再次执行程序时,不会清除该文件已经写入的内容。
说的直白点:只要你采用追加写,无论执行多少次同一个写文件程序,文件中的内容都不会被清除

到这里,就讲完了 OutputStream类 的简单基本用法了。

3. 总结

这一篇博客,就先讲这么多,因为我写的实在是有点太多了,字数已经超过 16900+ 了,再写下去,恐怕你们都不一定能有多少耐心看下去。

关于 文件内容操作中字符流操作的部分,我就在Java 文件操作 和 IO(4)-- Java文件内容操作(2)-- 字符流操作中,再进行讲解吧。

本篇博客,主要是在 字节流的 InputStream类 中,讲了很多,希望看到这里的读者,能慢慢地消化这篇博客的知识,把代码都自己写一写。

最后,如果这篇博客能帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!


http://www.hkcw.cn/article/suFhxUyfti.shtml

相关文章

MySQL进阶篇(存储引擎、索引、视图、SQL性能优化、存储过程、触发器、锁)

MySQL进阶篇 存储引擎篇MySQL体系结构存储引擎简介常用存储引擎简介存储引擎的选择 索引篇索引简介索引结构(1)BTree索引(2)hash索引 索引分类索引语法SQL性能分析指标(1)SQL执行频率(2)慢查询日志(3)profile详情(4)explain或desc执行计划 索引使用引起索引的失效行为SQL提示覆…

造血干细胞移植中,选择合适供者需综合多因素考量

KIR 单体型即杀伤细胞免疫球蛋白样受体(KIR)单体型,是指 KIR 基因在染色体上特定的组合形式 。主要内容如下: 分类 着丝粒单体型(C 型):含有较多的抑制性 KIR 基因,这些基因编码的…

四.MySQL数据类型

数据类型分类 一.数值类型 1.tinyint类型 MySQL 整数类型范围(有符号 / 无符号) 类型字节最小值(有符号/无符号)最大值(有符号/无符号)TINYINT1-128 / 0127 / 255SMALLINT2-32,768 / 032,767 / 65,535ME…

深度解构:Profinet转Profibus网关如何重塑产品分离装置的控制逻辑

PROFINET是一种基于以太网的工业以太网通讯协议,而PROFIBUS则是一种国际化的现场总线标准。在很多工业生产环境中,这两种通讯方式都有其各自的应用场合和优势。当产品分离装置需要同时使用PROFINET和PROFIBUS进行通信时,无锡耐特森PROFINET转…

EasyVoice:开源的文本转语音工具,让文字“开口说话“

名人说:博观而约取,厚积而薄发。——苏轼《稼说送张琥》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、EasyVoice是什么?1. 核心特性一览2. 技术架构概览 二、安装部署指南…

外航飞机疑盲降国内在建跑道 机组认错跑道复飞

5月28日,有网友发帖称,一架外国航空公司的飞机在降落西安咸阳国际机场时发生意外状况,疑似盲降正在建设中的跑道,接地后复飞。该事件引发网友关注。据网友所述,该飞机在准备降落时,地面指令让落23L(南一跑道),结果落向24L(正在建的南二跑道),然后指挥复飞了,最后落…

[Redis] Redis:高性能内存数据库与分布式架构设计

标题:[Redis] 浅谈分布式系统 水墨不写bug 文章目录 一、什么是Redis?一、核心定位二、核心优势三、典型应用场景四、Redis vs 传统数据库 二、架构选择与设计1、单机架构(应用程序 数据库服务器)2、应用程序和数据库服务器分离3…

论坛项目测试报告

一、项目背景 1.1 测试目标 验证论坛功能完整性,确保用户个人中心、发布/删除管理、模块分类控制、搜索功能等核心模块 符合需求。 1.2 项目技术栈 后端:Spring Boot/Spring MVC 数据库:MySQL 前端:原生 HTML/CSS/AJAX 二、…

(LeetCode 每日一题)3373. 连接两棵树后最大目标节点数目 II(贪心+深度优先搜索dfs)

题目:3373. 连接两棵树后最大目标节点数目 II 思路:贪心深度优先搜索dfs,时间复杂度0(nm)。 第二棵树:对每个节点进行分类,0或1,相邻的节点肯定不同啦,这样就可以统计出0和1 各自的节点个数。 …

开疆智能Profinet转Profibus网关连接EC-CM-P1 PROFIBUS DP从站通讯模块配置案例

本案例是通过开疆智能Profibus转Profinet网关将正弦研发的Profibus从站模块连接的EM600变频器接入到西门子1200PLC的配置案例。 配置过程 1. 打开网关配置软件“”新建项目并添加模块PN2DPM并设置参数 2. 设置网关的Profibus参数。如站地址,波特率等。(…

【计算机常识】--环境变量

在 Linux/Unix 系统中,​​环境变量(Environment Variables)​​是操作系统或用户设置的全局参数,用于存储系统或程序的配置信息。其中,​​PATH​​ 是最重要的环境变量之一,它决定了系统在哪些目录中查找…

孙颖莎含泪感谢邱贻可 坚定追求大满贯梦想

孙颖莎含泪感谢邱贻可 坚定追求大满贯梦想!5月29日,在多哈世乒赛上,孙颖莎实现了混双三连冠并卫冕女单冠军。她坦言为自己感到骄傲与感动。当被问及是否还怀揣着实现大满贯的梦想时,孙颖莎坚定回答:“必须的!”采访中,她眼含热泪向邱贻可指导表示感谢,并表示希望未来能…

行为型:观察者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 5、注意事项 1、核心思想 目的:针对被观察对象与观察者对象之间一对多的依赖关系建立起一种行为自动触发机制,当被观察对象状态发生变化时主动对外发起广播&…

中国已不是美留学生第一大来源国 印度反超夺魁

中国已不是美留学生第一大来源国 印度反超夺魁!赴美留学的国际学生中,中国已不再是最多的。根据最新数据,印度已成为美国高校留学生的第一大来源国,占比29.4%(约33.1万人),而中国排在第二位,占比24.6%(约27.7万人)。两国留学生人数合计已经超过一半。过去,中国长期占…

Unity-QFramework框架学习-MVC、Command、Event、Utility、System、BindableProperty

QFramework QFramework简介 QFramework是一套渐进式、快速开发框架,适用于任何类型的游戏及应用项目,它包含一套开发架构和大量的工具集 QFramework的特性 简洁性:QFramework 强调代码的简洁性和易用性,让开发者能够快速上手&a…

【代码训练营Day02】数组part2

文章目录 长度最小的子数组螺旋矩阵II数组总结 长度最小的子数组 题目链接:209. 长度最小的子数组 滑动窗口法的解题思路: 首先初始化双指针,都指向数组头部end指针依次向后滑,每向后滑一项就加一项,直到满足要求达到…

千年后中国人又在举国之力挖运河 新运河时代来临

千年后中国人又在举国之力挖运河 新运河时代来临!近日,浙江《关于高水平建设“航运浙江”的实施意见》正式实施,明确提出“谋划推进浙赣运河”。这一消息再次引起热议。作为浙赣粤运河的一部分,浙赣运河途经浙江杭州、衢州和江西上饶、鹰潭、南昌等城市,规划全长约760公里…

网关Gateway

目录 Gateway作用 Gateway使用 Gateway作用 在微服务项目中,没有引入网关时,项目架构如下: 引入网关后,架构如下: 引入网关后,有如下优势: 1、客户端请求经过网关向后台统一分发请求&#xff0c…

Python打卡训练营-Day15-复习日

浙大疏锦行 作业: 尝试找到一个kaggle或者其他地方的结构化数据集,用之前的内容完成一个全新的项目,这样你也是独立完成了一个专属于自己的项目。 要求: 有数据地址的提供数据地址,没有地址的上传网盘贴出地址即可。尽…

使用MFC 写dap上位机在线烧写FLASH

1.使用BUS Hound 抓取KEIL5 正常烧写的通讯包协议 2.结束DAP 源码分析每条数据,主要通讯靠05 和06 3.动态加载FLM烧写算法. 最终效果