Java序列流和打印流、对象序列化

目录

1、序列流

1.1 SequenceInputStream

1.2 案例:切割mp3并合并

2、 对象的序列化

2.1 ObjectOutputStream与ObjectInputStream

2.2 Serializable

3、Properties.

4、打印流

4.1 PrintStream

5、操作基本数据类型的流对象

5.1 DataInputStream以及DataOutputStream

6、操作数组的流对象

6.1 操作字节数组

6.2 操作字符数组


1、序列流

也称为合并流。

1.1 SequenceInputStream

序列流,对多个流进行合并。

SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

注意:

构造函数

SequenceInputStream(InputStream s1, InputStream s2)

合并两个流

使用构造函数SequenceInputStream(InputStream s1, InputStream s2)

private static void testSequenceInputStream() throws IOException {

        FileInputStream fis1 = new FileInputStream("c:\\a.txt");

        FileInputStream fis2 = new FileInputStream("c:\\b.txt");

        SequenceInputStream s1 = new SequenceInputStream(fis1, fis2);

        int len = 0;

        byte[] byt = new byte[1024];

        FileOutputStream fos = new FileOutputStream("c:\\z.txt");

        while ((len = s1.read(byt)) != -1) {

            fos.write(byt, 0, len);

        }

        s1.close();

    }

合并多个流:

public static void testSequenceInputStream() throws Exception {

        InputStream in1 = new FileInputStream("c:/a.txt");

        InputStream in2 = new FileInputStream("c:/b.txt");

        InputStream in3 = new FileInputStream("c:/c.txt");

        LinkedHashSet<InputStream> set = new LinkedHashSet<InputStream>();

        set.add(in1);

        set.add(in2);

        set.add(in3);

        final Iterator<InputStream> iter = set.iterator();

        SequenceInputStream sin = new SequenceInputStream(

                new Enumeration<InputStream>() {

                    @Override

                    public boolean hasMoreElements() {

                        return iter.hasNext();

                    }

                    @Override

                    public InputStream nextElement() {

                        return iter.next();

                    }

                });

        FileOutputStream out = new FileOutputStream("c:/z.txt");

        for (int b = -1; (b = sin.read()) != -1;) {

            out.write(b);

        }

        sin.close();

        out.close();

    }

1.2 案例:切割mp3并合并

将mp3歌曲文件进行切割拷贝并合并

public class Demo2 {

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

        split(new File("c:\\a.mp3"), 10, new File("c:\\"));

        System.out.println("切割完毕");

        LinkedHashSet<InputStream> hs = new LinkedHashSet<InputStream>();  

        hs.add(new FileInputStream(new File("c:\\part.1.mp3")));

        hs.add(new FileInputStream(new File("c:\\part.2.mp3")));

        hs.add(new FileInputStream(new File("c:\\part.3.mp3")));

        hs.add(new FileInputStream(new File("c:\\part.4.mp3")));

        merage(hs, new File("c:\\merage.mp3"));

        System.out.println("合并完毕");

    }

    private static void merage(LinkedHashSet<InputStream> hs, File dest) throws IOException {

        final Iterator<InputStream> it = hs.iterator();

        FileOutputStream fos = new FileOutputStream(dest);

        SequenceInputStream seq = new SequenceInputStream(

                new Enumeration<InputStream>() {

                    @Override

                    public boolean hasMoreElements() {

                        return it.hasNext();

                    }

                    @Override

                    public InputStream nextElement() {

                        return it.next();

                    }

                });

        byte[] byt = new byte[1024 * 1024];

        int len = 0;

        while ((len = seq.read(byt)) != -1) {

            fos.write(byt, 0, len);

        }

        seq.close();

        fos.close();

    }

    // 1. 切割文件

    /*

     * 切割文件,切割份数, 切割后保存路径

     */

    private static void split(File src, int count, File dir) throws IOException {

        FileInputStream fis = new FileInputStream(src);

        FileOutputStream fos = null;

        byte[] byt = new byte[1024 * 1024];

        int len = 0;

        for (int i = 1; i <= count; i++) {

            len = fis.read(byt);

            if (len != -1) {

                fos = new FileOutputStream(dir + "part." + i + ".mp3");

                fos.write(byt, 0, len);

            }

            // fos.close();

        }

        fis.close();

    }

}

2、 对象的序列化

当创建对象时,程序运行时它就会存在,但是程序停止时,对象也就消失了.但是如果希望对象在程序不运行的情况下仍能存在并保存其信息,将会非常有用,对象将被重建并且拥有与程序上次运行时拥有的信息相同。可以使用对象的序列化。

 对象的序列化:   将内存中的对象直接写入到文件设备中

 对象的反序列化: 将文件设备中持久化的数据转换为内存对象

基本的序列化由两个方法产生:一个方法用于序列化对象并将它们写入一个流,另一个方法用于读取流并反序列化对象。

ObjectOutput

writeObject(Object obj)

          将对象写入底层存储或流。

ObjectInput

readObject()

          读取并返回对象。

2.1 ObjectOutputStream与ObjectInputStream

由于上述ObjectOutput和ObjectInput是接口,所以需要使用具体实现类。

ObjectOutput

 ObjectOutputStream被写入的对象必须实现一个接口:Serializable

否则会抛出:NotSerializableException

ObjectInput

     ObjectInputStream    该方法抛出异常:ClassNotFountException         

ObjectOutputStream和ObjectInputStream 对象分别需要字节输出流和字节输入流对象来构建对象。也就是这两个流对象需要操作已有对象将对象进行本地持久化存储。

案例:

序列化和反序列化Cat对象。

public class Demo3 {

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

            ClassNotFoundException {

        Cat cat = new Cat("tom", 3);

        FileOutputStream fos = new FileOutputStream(new File("c:\\Cat.txt"));

        ObjectOutputStream oos = new ObjectOutputStream(fos);

        oos.writeObject(cat);

        System.out.println(cat);

        oos.close();

        // 反序列化

        FileInputStream fis = new FileInputStream(new File("c:\\Cat.txt"));

        ObjectInputStream ois = new ObjectInputStream(fis);

        Object readObject = ois.readObject();

        Cat cat2 = (Cat) readObject;

        System.out.println(cat2);

        fis.close();

}

class Cat implements Serializable {

    public String name;

    public int age;

    public Cat() {

    }

    public Cat(String name, int age) {

        this.name = name;

        this.age = age;

    }

    @Override

    public String toString() {

        return "Cat [name=" + name + ", age=" + age + "]";

    }

}

例子关键点:

  1. 声明Cat类实现了Serializable接口。是一个标示器,没有要实现的方法。
  2. 新建Cat对象。
  3. 新建字节流对象(FileOutputStream)进序列化对象保存在本地文件中。
  4. 新建ObjectOutputStream对象,调用writeObject方法序列化Cat对象。
  5. writeObject方法会执行两个工作:序列化对象,然后将序列化的对象写入文件中。
  6. 反序列化就是调用ObjectInputStreamreadObject()方法。
  7. 异常处理和流的关闭动作要执行。 

2.2 Serializable

类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

所以需要被序列化的类必须是实现Serializable接口,该接口中没有描述任何的属性和方法,称之为标记接口。

如果对象没有实现接口Serializable,在进行序列化时会抛出:NotSerializableException 异常。

注意:

保存一个对象的真正含义是什么?如果对象的实例变量都是基本数据类型,那么就非常简单。但是如果实例变量是包含对象的引用,会怎么样?保存的会是什么?很显然在Java中保存引用变量的实际值没有任何意义,因为Java引用的值是通过JVM的单一实例的上下文中才有意义。通过序列化后,尝试在JVM的另一个实例中恢复对象,是没有用处的。

如下:

首先建立一个Dog对象,也建立了一个Collar对象。Dog中包含了一个Collar(项圈)

现在想要保存Dog对象,但是Dog中有一个Collar,意味着保存Dog时也应该保存Collar。假如Collar也包含了其他对象的引用,那么会发生什么?意味着保存一个Dog对象需要清楚的知道Dog对象的内部结构。会是一件很麻烦的事情。

   Java的序列化机制可以解决该类问题,挡序列化一个对象时,Java的序列化机制会负责保存对象的所有关联的对象(就是对象图),反序列化时,也会恢复所有的相关内容。本例中:如果序列化Dog会自动序列化Collar。但是,只有实现了Serializable接口的类才可以序列化。如果只是Dog实现了该接口,而Collar没有实现该接口。会发生什么?

Dog类和Collar类

import java.io.Serializable;

public class Dog implements Serializable {

    private Collar collar;

    private String name;

    public Dog(Collar collar, String name) {

        this.collar = collar;

        this.name = name;

    }

    public Collar getCollar() {

        return collar;

    }

}

class Collar {

    private int size;

    public int getSize() {

        return size;

    }

    public Collar(int size) {

        this.size = size;

    }

}

序列化

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

public class Demo4 {

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

        Collar coll = new Collar(10);

        Dog dog = new Dog(coll, "旺财");

        FileOutputStream fis = new FileOutputStream(new File("c:\\dog.txt"));

        ObjectOutputStream os = new ObjectOutputStream(fis);

        os.writeObject(dog);

    }

}

执行程序,出现了运行时异常。

Exception in thread "main" java.io.NotSerializableException: Collar

所以我们也必须将Dog中使用的Collar序列化。但是如果我们无法访问Collar的源代码,或者无法使Collar可序列化,如何处理?

两种解决方法:

一:继承Collar类,使子类可序列化

但是:如果Collar是final类,就无法继承了。并且,如果Collar引用了其他非序列化对象,也无法解决该问题。

transient

此时就可以使用transient修饰符,可以将Dog类中的成员变量标识为transient

那么在序列化Dog对象时,序列化就会跳过Collar。

public class Demo4 {

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

            ClassNotFoundException {

        Collar coll = new Collar(10);

        Dog dog = new Dog(coll, "旺财");

        System.out.println(dog.getCollar().getSize());

        FileOutputStream fis = new FileOutputStream(new File("c:\\dog.txt"));

        ObjectOutputStream os = new ObjectOutputStream(fis);

        os.writeObject(dog);

        // 反序列化

        FileInputStream fos = new FileInputStream(new File("c:\\dog.txt"));

        ObjectInputStream ois = new ObjectInputStream(fos);

        Object readObject = ois.readObject();

        Dog dog2 = (Dog) readObject;

        // Collar未序列化。

        dog2.getCollar().getSize();

    }

}

这样我们具有一个序列化的Dog和非序列化的Collar。

此时反序列化Dog后,访问Collar,就会出现运行时异常

10

Exception in thread "main" java.lang.NullPointerException

注意:序列化不适用于静态变量,因为静态变量并不属于对象的实例变量的一部分。静态变量随着类的加载而加载,是类变量。由于序列化只适用于对象。

基本数据类型可以被序列化

public class Demo5 {

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

        // 创建序列化流对象

        FileOutputStream fis = new FileOutputStream(new File("c:\\basic.txt"));

        ObjectOutputStream os = new ObjectOutputStream(fis);

        // 序列化基本数据类型

        os.writeDouble(3.14);

        os.writeBoolean(true);

        os.writeInt(100);

        os.writeInt(200);

        // 关闭流

        os.close();

        // 反序列化

        FileInputStream fos = new FileInputStream(new File("c:\\basic.txt"));

        ObjectInputStream ois = new ObjectInputStream(fos);

        System.out.println(ois.readDouble());

        System.out.println(ois.readBoolean());

        System.out.println(ois.readInt());

        System.out.println(ois.readInt());

        fos.close();

    }

}

serialVersionUID

用于给类指定一个UID。该UID是通过类中的可序列化成员的数字签名运算出来的一个long型的值。

只要是这些成员没有变化,那么该值每次运算都一样。

该值用于判断被序列化的对象和类文件是否兼容。

如果被序列化的对象需要被不同的类版本所兼容。可以在类中自定义UID。

定义方式:static final long serialVersionUID = 42L;

3、Properties.

可以和流相关联的集合对象Properties.

Map

|--Hashtable

|--Properties

Properties:该集合不需要泛型,因为该集合中的键值对都是String类型。

基本方法:

1,存入键值对:setProperty(key,value);

2,获取指定键对应的值:value getProperty(key);

3,获取集合中所有键元素:

Enumeration  propertyNames();

在jdk1.6版本给该类提供一个新的方法。

Set<String> stringPropertyNames();

4,列出该集合中的所有键值对,可以通过参数打印流指定列出到的目的地。

list(PrintStream);

list(PrintWriter);

例:list(System.out):将集合中的键值对打印到控制台。

list(new PrintStream("prop.txt")):将集合中的键值对存储到prop.txt文件中。

5,可以将流中的规则数据加载进行集合,并称为键值对。

load(InputStream):

jdk1.6版本。提供了新的方法。

load(Reader):

注意:流中的数据要是"键=值" 的规则数据。

6,可以将集合中的数据进行指定目的的存储。

store(OutputStram,String comment)方法。

jdk1.6版本。提供了新的方法。

store(Writer ,String comment):

使用该方法存储时,会带着当时存储的时间。

注意:

Properties只加载key=value这样的键值对,与文件名无关,注释使用#

public static void sysPropList() throws IOException {

        Properties prop = System.getProperties();

        // prop.list(System.out);// 目的是控制台。

        // 需求是:将jvm的属性信息存储到一个文件中。

        prop.list(new PrintStream("java.txt"));

    }

    public static void sysProp() {

        Properties prop = System.getProperties();

        Set<String> keys = prop.stringPropertyNames();

        for (String key : keys) {

            System.out.println(key + ":" + prop.getProperty(key));

        }

    }

Properties类与配置文件

Map

   |--Hashtable

      |--Properties

注意:是一个Map集合,该集合中的键值对都是字符串。该集合通常用于对键值对形式的配置文件进行操作.

配置文件:将软件中可变的部分数据可以定义到一个文件中,方便以后更改,该文件称之为配置文件。

优势: 提高代码的维护性。

Properties:  该类是一个Map的子类,提供了可以快速操作配置文件的方法

load()  :    将文件设备数据装载为Map集合数据

get(key):    获取Map中的数据

getProperty()获取Map中的数据特有方法

setProperty() 通过键修改值

store :      将集合数据加载到流中

案例:

properties 基本应用

/*

     * 将配置文件中的数据通过流加载到集合中。

     */

    public static void loadFile() throws IOException {

        // 1,创建Properties(Map)对象

        Properties prop = new Properties();

        // 2.使用流加载配置文件。

        FileInputStream fis = new FileInputStream("c:\\qq.txt");

        // 3。使用Properties 对象的load方法将流中数据加载到集合中。

        prop.load(fis);

        // 遍历该集合

        Set<Entry<Object, Object>> entrySet = prop.entrySet();

        Iterator<Entry<Object, Object>> it = entrySet.iterator();

        while (it.hasNext()) {

            Entry<Object, Object> next = it.next();

            Object key = next.getKey();

            Object value = next.getValue();

        }

        // 通过键获取指定的值

        Object object = prop.get("jack");

        System.out.println(object);

        // 通过键修改值

        prop.setProperty("jack", "888888");

        // 将集合中的数据写入到配置文件中。

        FileOutputStream fos = new FileOutputStream("c:\\qq.txt");

        // 注释:

        prop.store(fos, "yes,qq");

        fos.close();

        fis.close();

    }

      1. 案例:统计软件运行次数

练习:记录一个程序运行的次数,当满足指定次数时,该程序就不可以再继续运行了。

通常可用于软件使用次数的限定。

获取记录程序运行次数:

public class Demo6 {

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

        int count = 0;

        Properties pro = new Properties();

        File file = new File("c:\\count.ini");

        FileInputStream fis = null;

        if (!file.exists()) {

            file.createNewFile();

        }

        fis = new FileInputStream(file);

        pro.load(fis);

        String str = pro.getProperty("count");

        if (str != null) {

            count = Integer.parseInt(str);

        }

        if (count == 3) {

            System.out.println("使用次数已到,请付费");

            System.exit(0);

        }

        count++;

        System.out.println("欢迎使用本软件" + "你已经使用了:" + count + " ");

        pro.setProperty("count", count + "");

        FileOutputStream fos = new FileOutputStream(new File("c:\\count.ini"));

        pro.store(fos, "请保护知识产权");

        fis.close();

        fos.close();

    }

}

4、打印流

PrintStream可以接受文件和其他字节输出流,所以打印流是对普通字节输出流的增强,其中定义了很多的重载的print()和println(),方便输出各种类型的数据。

4.1 PrintStream

PrintWriter

1,打印流。

PrintStream:

是一个字节打印流,System.out对应的类型就是PrintStream。

它的构造函数可以接收三种数据类型的值。

1,字符串路径。

2,File对象。

3,OutputStream。

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

        PrintStream ps = System.out;

        // 普通write方法需要调用flush或者close方法才会在控制台显示

        // ps.write(100);

        // ps.close();

        // 不换行打印

        ps.print(100);

        ps.print('a');

        ps.print(100.5);

        ps.print("世界");

        ps.print(new Object());

        System.out.println("--------------");

        // 换行

        ps.println(100);

        ps.println('a');

        ps.println(100.5);

        ps.println("世界");

        ps.println(new Object());

        // 重定向打印流

        PrintStream ps2 = new PrintStream(new File("c:\\a.txt"));

        System.setOut(ps2);

        // 换行

        ps2.println(100);

        ps2.println('a');

        ps2.println(100.5);

        ps2.println("世界");

        ps2.println(new Object());

        // printf(); 格式化

        ps2.printf("%d,%f,%c,%s", 100, 3.14, '', "世界你好!!!");

        ps2.printf("%4s%8s 打价格战", "京东", "苏宁");

    }   }

注意: 打印流的三种方法

      void print(数据类型 变量)

   println(数据类型 变量)

   printf(String format, Object... args)

      可以自定数据格式

   print 和println方法的区别在于,一个换行一个不换行

   print 方法和write方法的却别在于,print提供自动刷新.

   普通的write方法需要调用flush或者close方法才可以看到数据.

JDK1.5之后Java对PrintStream进行了扩展,增加了格式化输出方式,可以使用printf()重载方法直接格式化输出。但是在格式化输出的时候需要指定输出的数据类型格式。

PrintWriter

是一个字符打印流。构造函数可以接收四种类型的值。

1,字符串路径。

2,File对象。

对于1,2类型的数据,还可以指定编码表。也就是字符集。

3,OutputStream

4,Writer

对于3,4类型的数据,可以指定自动刷新。

注意:该自动刷新值为true时,只有三个方法可以用:println,printf,format.

如果想要既有自动刷新,又可执行编码。如何完成流对象的包装?

PrintWrter pw =

new PrintWriter(new OutputSteamWriter(new FileOutputStream("a.txt"),"utf-8"),true);

如果想要提高效率。还要使用打印方法。

PrintWrter pw =

newPrintWriter(new  BufferdWriter(new OutputSteamWriter(

newFileOutputStream("a.txt"),"utf-8")),true);

public static void testPrintWriter() throws Exception {

        PrintWriter pw = new PrintWriter("c:/b.txt", "gbk");

        // pw.append("xxx");

        // pw.println(55);

        // pw.println('c');

        // pw.printf("%.1s%4s打价格战, %c", "京东","苏宁", 'a');

        pw.close();

    }

Scanner

public static void testScanner() throws Exception {

        // Scanner scanner = new Scanner(new File("c:/test.txt"));

        Scanner scanner = new Scanner(System.in);

        System.out.println(scanner.nextInt());

        System.out.println(scanner.nextBoolean());

        scanner.close();

    

5、操作基本数据类型的流对象

5.1 DataInputStream以及DataOutputStream

查看API文档DataInputStream的信息。发现从底层输入流中读取基本 Java 数据类型。查看方法,有读一个字节,读一个char读一个double 的方法,

DataInputStream 从数据流读取字节,并将它们转换为正确的基本数据类型值或字符串。

该流有操作基本数据类型的方法.

有读的,那么必定有对应的写的就是DataOutputStream 将基本类型的值或字符串转换为字节,并且将字节输出到数据流。

DataInputStream类继承FilterInputStream类,并实现了DataInput接口。DataOutputStream

类继承FilterOutputStream 并实现了DataOutput 接口。

例如:

DataInputStream

操作基本数据类型的方法:

int readInt():一次读取四个字节,并将其转成int值。

boolean readBoolean():一次读取一个字节。

short readShort();

long readLong();

剩下的数据类型一样。

String readUTF():按照utf-8修改版读取字符。注意,它只能读writeUTF()写入的字符数据。

DataOutputStream

DataOutputStream(OutputStream):

操作基本数据类型的方法:

writeInt(int):一次写入四个字节。

注意和write(int)不同。write(int)只将该整数的最低一个8位写入。剩余三个8位丢弃。

writeBoolean(boolean);

writeShort(short);

writeLong(long);

剩下是数据类型也也一样。

writeUTF(String):按照utf-8修改版将字符数据进行存储。只能通过readUTF读取。

测试:  DataOutputStream

      使用DataOutputStream写数据文件。

public static void testDataInputStream() throws Exception {

        DataOutputStream out = new DataOutputStream(new FileOutputStream(

                "c:/a.txt"));

        out.writeBoolean(true);

        out.writeByte(15); // 0x05 1 个字节

        out.writeBytes("abc"); // 0x 0041 2个字节

        out.writeChar('X'); // ??

        out.writeChars("xyz");

        out.writeLong(111);

        out.writeUTF("中国");

        out.close();

        DataInputStream in = new DataInputStream(

                new FileInputStream("c:/a.txt"));

        System.out.println(in.readBoolean());

        System.out.println(in.readByte());

        System.out.println(in.readByte());

        System.out.println(in.readByte());

        System.out.println(in.readByte());

        System.out.println(in.readChar());

        System.out.println(in.readChar());

        System.out.println(in.readChar());

        System.out.println(in.readChar());

        System.out.println(in.readLong());

        System.out.println(in.readUTF());

        in.close();

    }

6、操作数组的流对象

6.1 操作字节数组

ByteArrayInputStream以及ByteArrayOutputStream

toByteArray();

toString();

writeTo(OutputStream);

public static void testByteArrayInputStream() throws Exception {

        InputStream in = new ByteArrayInputStream(new byte[] { 65, 66, 67 });

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        for (int b = -1; (b = in.read()) != -1;) {

            out.write(b);

        }

        in.close();

        out.close();

        System.out.println(Arrays.toString(out.toByteArray()));

        System.out.println(out);

    }

6.2 操作字符数组

CharArrayReader

CharArrayWriter

对于这些流,源是内存。目的也是内存。

而且这些流并未调用系统资源。使用的就是内存中的数组。

所以这些在使用的时候不需要close

操作数组的读取流在构造时,必须要明确一个数据源。所以要传入相对应的数组。

对于操作数组的写入流,在构造函数可以使用空参数。因为它内置了一个可变长度数组作为缓冲区。

public static void testCharArrayReader() throws Exception {

        CharArrayReader reader = new CharArrayReader(new char[] { 'A', 'b', 'c' });

        CharArrayWriter writer = new CharArrayWriter();

        for (int b = -1; (b = reader.read()) != -1;) {

            writer.write(b);

        }

        reader.close();

        writer.close();

        System.out.println(writer.toCharArray());

    }

这几个流的出现其实就是通过流的读写思想在操作数组。

类似的对象同理:

StringReader

StringWriter。

public static void testStringReader() throws Exception {

        StringReader reader = new StringReader("test 中国");

        StringWriter writer = new StringWriter();

        for (int b = -1; (b = reader.read()) != -1;) {

            writer.write(b);

        }

        reader.close();

        writer.close();

        System.out.println(writer.toString());

    }

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

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

相关文章

书生·浦语大模型全链路开源体系-第6课

书生浦语大模型全链路开源体系-第6课 书生浦语大模型全链路开源体系-第6课相关资源Lagent & AgentLego 智能体应用搭建环境准备创建虚拟环境安装LMDeploy安装 Lagent安装 AgentLego Lagent 轻量级智能体框架使用 LMDeploy 部署启动并使用 Lagent Web Demo使用自定义工具获取…

呼叫系统的技术实现原理和运作流程,ai智能系统,呼叫中心外呼软交换部署

呼叫系统的技术实现原理和运作流程可以涉及多个组成部分&#xff0c;包括硬件设备、软件系统和通信协议。以下是一般情况下呼叫系统的技术实现原理和运作流程的概述&#xff1a; 硬件设备&#xff1a; 服务器&#xff1a;用于承载呼叫系统的核心软件和数据库。电话交换机&#…

学习-官方文档编辑方法

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Linux常用命令英文全称与中文解释

Linux操作系统中有许多常用的命令&#xff0c;每个命令都有其英文全称&#xff08;Full Name&#xff09;和中文解释。以下是一些常见的Linux命令及其英文全称和中文解释的列表&#xff1a; 你猜猜这个是哪个软件的快捷键↑ man: Manual 意思是手册&#xff0c;可以用这个命…

如何让指定 Windows 程序崩溃

一、为何要把人家搞崩溃呢 看到这个标题&#xff0c;大家可能觉得奇怪&#xff0c;为什么要让指定程序崩溃呢&#xff0c;难道是想作恶吗&#xff1f;&#x1f613; 哈哈&#xff0c;绝对不是&#xff0c;真实原因是这样的。如果大家用过 Windows 电脑&#xff0c;可能见过类…

【个人博客搭建】(3)添加SqlSugar ORM 以及Json配置文件读取

1、安装sqlsugar。在models下的依赖项那右击选择管理Nuget程序包&#xff0c;输入sqlsugarcore&#xff08;因为我们用的是netcore&#xff0c;而不是net famework所以也对应sqlsugarcore&#xff09;&#xff0c;出来的第一个就是了&#xff0c;然后点击选择版本&#xff0c;一…

展会媒体邀约资源,媒体宣传服务执行

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 在组织展会时&#xff0c;媒体宣传服务的执行是提升展会知名度和影响力的关键环节。 确定目标媒体&#xff1a;根据展会的主题和目标受众&#xff0c;选择适合的媒体进行邀请。这可能包…

微软 SDL 安全研发生命周期详解

微软SDL&#xff08;Security Development Lifecycle&#xff09;是一种安全软件开发的方法论&#xff0c;它强调在整个产品开发过程中融入安全考虑因素。SDL 是一个动态的过程&#xff0c;包括多个阶段和活动&#xff0c;以确保产品的安全开发、测试、部署和运行。Microsoft 要…

2023天梯赛 L3_2 完美树 【树形DP、01最大/小价值】

完美树 思路 观察发现&#xff1a;如果一颗子树 u u u&#xff0c;它刚好有偶数个节点&#xff0c;那么 0 0 0 和 1 1 1 的染色数量一定相等&#xff0c;如果有奇数个节点&#xff0c;那么 0 0 0 和 1 1 1 的数量一定恰好相差 1 1 1&#xff08;可能是 0 0 0 多&#x…

OpenHarmony多媒体-mp4parser

简介 一个读取、写入操作音视频文件编辑的工具。 编译运行 1、通过IDE工具下载依赖SDK&#xff0c;Tools->SDK Manager->Openharmony SDK 把native选项勾上下载&#xff0c;API版本>10 2、开发板选择RK3568&#xff0c;ROM下载地址. 选择开发板类型是rk3568&#xf…

高可用集群——keepalived

目录 1 高可用的概念 2 心跳监测与漂移 IP 地址 3 Keepalived服务介绍 4 Keepalived故障切换转移原理介绍 5 Keepalived 实现 Nginx 的高可用集群 5.1 项目背景 5.2 项目环境 5.3 项目部署 5.3.1 web01\web02配置&#xff1a; 5.3.2nginx负载均衡配置 5.3.3 主调度服…

碳实践|手把手教你开展组织碳核算

一、背景介绍 政府间气候变化委员会 IPCC(Intergovernmental Panel on Climate Chang)是世界气象组织(WMO)及联合国环境规划署(UNEP)于1988年联合建立的政府间机构。 IPCC在1997年和2000年分别发布了《1996 年 IPCC 国家温室气体清单指南修订本》和《国家温室气体清单优良作法…

【氮化镓】栅极漏电对阈值电压和亚阈值摆幅影响建模

本文是一篇关于p-GaN门AlGaN/GaN高电子迁移率晶体管&#xff08;HEMTs&#xff09;的研究文章&#xff0c;发表于《应用物理杂志》&#xff08;J. Appl. Phys.&#xff09;2024年4月8日的期刊上。文章的标题为“Analysis and modeling of the influence of gate leakage curren…

什么是SRE?

什么是SRE&#xff1f; SRE&#xff0c;全称为Site Reliability Engineering&#xff0c;即网站可靠性工程&#xff0c;是一种职能角色&#xff0c;它融合了软件工程和系统管理的技能与实践&#xff0c;旨在通过软件和自动化的方式来提高系统的可靠性、稳定性和扩展性。以下是…

Zabbix自定义模板、邮件报警、自动发现与注册、proxy代理、SNMP监控

目录 自定义监控内容 1.明确需要执行的 linux 命令 2.创建 zabbix 的监控项配置文件&#xff0c;用于自定义 key 3.在服务端验证新建的监控项 在 Web 页面创建自定义监控项模板 1.创建模板 2.创建应用集&#xff08;用于管理监控项的&#xff09; 3.创建监控项 4.创建…

JEECG表格选中状态怎么去掉

官网代码&#xff08;在取消选中状态的时候不生效&#xff09; rowSelection() {return {onChange: (selectedRowKeys, selectedRows) > {console.log(selectedRowKeys: ${selectedRowKeys}, selectedRows: , selectedRows);},getCheckboxProps: record > ({props: {disa…

【基础】gcc-动态库和静态库的创建和使用-命令

目录 1 动态库的建立使用2 动态库封装过程2.1 编译动态库2.2 使用动态库2.3 命令参数说明 3 静态库封装过程3.1 静态库的封装3.2 静态库的使用 1 动态库的建立使用 首先建立一个头文件&#xff0c;和三个.cpp文件&#xff0c;目的是要把这些文件链接成动态库&#xff1a; 其中…

C#创建背景色渐变窗体的方法:创建特殊窗体

目录 1.让背景渐变色的理论基础 2.让背景渐变色的方法 3.一个实施例 &#xff08;1&#xff09;Form1.Designer.cs &#xff08;2&#xff09;Form1.cs &#xff08;3&#xff09;渐变的蓝色背景 在窗体设计时&#xff0c;可以通过设置窗体的BackColor属性来改变窗口的背…

Golang | Leetcode Golang题解之第35题搜索插入位置

题目&#xff1a; 题解&#xff1a; func searchInsert(nums []int, target int) int {n : len(nums)left, right : 0, n - 1ans : nfor left < right {mid : (right - left) >> 1 leftif target < nums[mid] {ans midright mid - 1} else {left mid 1}}retu…

【mac】【python】新建项目虚拟环境后,使用命令pip出现错误:zsh: command not found: pip

【mac】【python】新建项目虚拟环境后&#xff0c;使用命令pip出现错误&#xff1a;zsh: command not found: pip 问题描述&#xff1a; 拉取或者创建新的python项目时&#xff0c;为项目添加了新的解释器&#xff0c;创建啦虚拟环境&#xff0c;但是执行pip命令的时候找不到命…