十、字节缓冲流、字符流、转换流、对象操作流、对象序列化流

news2024/9/23 23:33:12

字节缓冲流

构造方法

  • 字节缓冲流介绍

    • BufferedOutputStream:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
    • BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
  • 构造方法:

    方法名说明
    BufferedOutputStream(OutputStream out)创建字节缓冲输出流对象
    BufferedInputStream(InputStream in)创建字节缓冲输入流对象
  • 读写和关闭流的方法 同字节输入输出流

代码

  • 用BufferedOutputStream写数据到文件
  • 用BufferedInputStream把刚才写入的文件读出来
//缓冲字节输出流对象 创建
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("module01/aaa.txt"));

//写入
bos.write(99);
bos.write(100);
bos.write(101);
//关闭
bos.close();


//缓冲字节输入流对象 创建   用来读取aaa.txt
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("module01/aaa.txt"));

//循环读取aaa.txt
int b;
while ((b = bis.read()) != -1) {
    System.out.println((char)b);
}
//关闭流
bis.close();

缓冲流原理

  • 减少了对硬盘的操作,写入数据到数组

  • 1 数组满了之后,才会自动写入到硬盘

  • 2 主动调用flush后 也会写入到硬盘 注意close方法中 已经调用了flush
    在这里插入图片描述

  • 每次从数组里读,这样操作的是内存,效率高,直到把数组内容读完,数组在去硬盘获取

在这里插入图片描述

flush方法

  • 调用flush方法,可以主动把数据写入到硬盘
  • close方法里也调用了flush方法

字节缓冲流复制一个视频练习

一次一个字节代码

    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("module01/music/无间道.mp3"));
        //缓冲字节输出流对象 创建
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("module01/music/无间道1.mp3"));
        int b;
        while ((b = bis.read()) != -1) {
            //把读取的内容写入到无间道1.mp3
            bos.write(b);
        }
        bos.close();
        bis.close();
    }

一次一个数组代码

    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("module01/music/无间道.mp3"));
        //缓冲字节输出流对象 创建
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("module01/music/无间道1.mp3"));
        byte[] b = new byte[1024];
        int len;
        while ((len = bis.read(b)) != -1) {
            //把读取的内容写入到无间道1.mp3
            bos.write(b, 0, len);
        }
        bos.close();
        bis.close();
    }

字符流

介绍

  • 由于字节流操作中文不是特别的方便,所以Java就提供字符流
    • 字符流 = 字节流 + 编码表
  • 中文的字节存储方式
    • 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
    • 汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数

编码表(了解)

  • 什么是字符集

    是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等

    l计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等

  • 常见的字符集

    • ASCII字符集:

      lASCII:是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)

      基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等

    • GBXXX字符集:

      GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等

    • Unicode字符集:

      UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码

编码规则:

  • 128个US-ASCII字符,只需一个字节编码
  • 拉丁文等字符,需要二个字节编码
  • 大部分常用字(含中文),使用三个字节编码
  • 其他极少使用的Unicode辅助字符,使用四字节编码

字符串中的编码解码问题(会使用)

  • 相关方法

    方法名说明
    byte[] getBytes()使用平台的默认字符集将该 String编码为一系列字节
    byte[] getBytes(String charsetName)使用指定的字符集将该 String编码为一系列字节
    String(byte[] bytes)使用平台的默认字符集解码指定的字节数组来创建字符串
    String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组来创建字符串

代码

  • encode编码 decode解码
String str01 = "我爱我的祖国";
byte[] bytes = str01.getBytes("utf-8");
System.out.println(Arrays.toString(bytes));

byte[] bytes1 = str01.getBytes("gbk");
System.out.println(Arrays.toString(bytes1));


String str02 = new String(bytes,"utf-8");
System.out.println(str02);

String str03 = new String(bytes1,"gbk");
System.out.println(str03);

idea设置编码

在这里插入图片描述

字符流类

  • Writer和Reader

  • 字节流 操作一切文件

  • 字符流 操作文本文件 操作汉字时更方便

FileWriter

  • Writer: 用于写入字符流的抽象父类
  • FileWriter: 用于写入字符流的常用子类

构造方法

方法名说明
FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(File file, boolean append)根据给定的 File 对象构造一个 FileWriter 对象
FileWriter(String fileName)根据给定的文件名构造一个 FileWriter 对象
FileWriter(String fileName, boolean append)根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象

jdk11后构造方法可以指定编码

    public static void main(String[] args) throws IOException {
        //jdk11后 支持指定编码解码方式
        //参数2指定编码为utf-8 注意语法是Charset.forName()
        FileWriter fw = new FileWriter("qqqqqq.txt", Charset.forName("utf-8"));
        fw.write("开心的文字 拆迁啦");
        fw.close();

        //参数2 指定解码方式为utf-8
        FileReader fr = new FileReader("qqqqqq.txt", Charset.forName("utf-8"));
        char[] cs = new char[1000];
        int len = fr.read(cs);
        fr.close();
        System.out.println(new String(cs, 0, len));
    }

成员方法

方法名说明
void write(int c)写一个字符
void write(char[] cbuf)写入一个字符数组
void write(char[] cbuf, int off, int len)写入字符数组的一部分
void write(String str)写一个字符串
void write(String str, int off, int len)写一个字符串的一部分

刷新和关闭的方法

方法名说明
flush()刷新流,之后还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

代码

//FileWriter fw = new FileWriter(new File("module01/ccc.txt"));
FileWriter fw = new FileWriter("module01/ccc.txt");

fw.write(100);
char[] cs = {'a', 'g', '啊', '吃'};
fw.write(cs);

fw.write("饭了,吃烤鸭,吃宫爆鸡丁,吃鱼香肉丝");

fw.write("\r\n"); //写入换行
fw.write("abcdefg", 1, 3);//跳过1个写入3个

fw.close();

FileWrite本身就有缓冲区

  • 如果write少量数据,没有flush也没有close,会发现没有写入文件
  • close方法执行后,不能继续使用流对象了

FileReader

  • Reader: 用于读取字符流的抽象父类
  • FileReader: 用于读取字符流的常用子类

构造方法

方法名说明
FileReader(File file)在给定从中读取数据的 File 的情况下创建一个新 FileReader
FileReader(String fileName)在给定从中读取数据的文件名的情况下创建一个新 FileReader

成员方法

方法名说明
int read()一次读一个字符数据
int read(char[] cbuf)一次读一个字符数组数据

代码演示

//FileReader fr = new FileReader(new File("module01/ccc.txt"));
FileReader fr = new FileReader("module01/ccc.txt");

//int a;
//while ((a = fr.read()) != -1) {
//    System.out.println(a);
//    System.out.println((char) a);
//}
//System.out.println("\r\n".toCharArray().length);

char[] cs = new char[3];
int len;
while ((len = fr.read(cs)) != -1) {
    //System.out.println(cs);
    System.out.println(new String(cs, 0, len));//转为字符串 注意要添加len长度,最后一次遍历数组可能装不满
}
fr.close();

字符流用户注册案例

  • 案例需求

    将键盘录入的用户名和密码保存到本地实现永久化存储

  • 实现步骤

    • 1获取用户输入的用户名和密码
    • 2将用户输入的用户名和密码写入到本地文件中
    • 3关流,释放资源

代码

//- 1获取用户输入的用户名和密码
//- 2将用户输入的用户名和密码写入到本地文件中
//- 3关流,释放资源
Scanner sc = new Scanner(System.in);
System.out.println("输入的用户名:");
String name = sc.next();
System.out.println("输入的密码:");
String pwd = sc.next();

try(FileWriter fw = new FileWriter("user.txt");) {
    //写入用户名
    fw.write(name);
    //换行
    fw.write("\r\n");
    //写入密码
    fw.write(pwd);
} catch (IOException e) {
    e.printStackTrace();
} 
FileOutputStream
BufferedOutputStream


FileWrite  字符流本身就有一个缓冲数组  8kb
BufferedWrite

字符缓冲流

  • 介绍

    • BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
    • BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
  • 构造方法

    方法名说明
    BufferedWriter(Writer out)创建字符缓冲输出流对象
    BufferedReader(Reader in)创建字符缓冲输入流对象

代码

  • BufferedWriter写数据
  • BufferedReader读数据
try (BufferedReader br = new BufferedReader(new FileReader("mymodule/d.txt"));
     BufferedWriter bw = new BufferedWriter(new FileWriter("mymodule/d1.txt"));) {

    //定义字符数组
    char[] cs = new char[1024];
    //定义长度
    int len = 0;
    while ((len = br.read(cs)) != -1) {
        bw.write(cs, 0, len);
    }

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

字符缓冲流特有功能

  • 方法介绍

    BufferedWriter:

    方法名说明
    void newLine()写一行行分隔符,行分隔符字符串由系统属性定义

    BufferedReader:

    方法名说明
    String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null

代码

  • 1循环写入10次hello world到文件,每次都换行
  • 2按行读取文件内容
//    - 1循环写入10次hello world到文件,每次都换行
//创建缓冲字符写入流
try(bw = new BufferedWriter(new FileWriter("module01/xxx.txt"));){
    for (int i = 0; i < 10; i++) {
        bw.write("hello world");
        //换行
        bw.newLine();
    }

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

// - 2按行读取文件内容

try( //创建缓冲字符读取流
    BufferedReader br = new BufferedReader(new FileReader("module01/xxx.txt"));) {

    //定义字符串接收读取的内容
    String line;
    //每次读取一行  内容全部读完后,如果再读 就会返回null 把循环结束
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
} 

字符缓冲流操作文件中数据排序案例

需求

  • 使用字符缓冲流读取文件中的数据,排序后再次写到本地文件
  • 文件内容是 5 32 47 7 5 22 2 12 4 8 6

步骤

  • 1将文件中的数据读取到程序中
  • 2对读取到的数据进行分割转换排序
  • 3将排序后的数据写入到文件中

代码

//1 读取文件内容  按行读取
try (
    BufferedReader br = new BufferedReader(new FileReader("mymodule/ee.txt"));
) {
    String line = br.readLine();//读取数据5 32 47 7 5 22 2 12 4 8 6
    //2 把读取的字符串 按空格切割 得到一个字符串数组
    String[] ss = line.split(" ");
    System.out.println(Arrays.toString(ss));
    //把字符串的数组转为int数组
    int[] arr = new int[ss.length];
    for (int i = 0; i < ss.length; i++) {
        arr[i] = Integer.parseInt(ss[i]);
    }
    //3 对字符串数组排序
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));


    //4 把排序完的数据写回文件
    BufferedWriter bw = new BufferedWriter(new FileWriter("mymodule/ee.txt"));
    for (int i : arr) {
        //遍历写回内容 注意加空格
        bw.write(i + " ");
    }
    //关闭流
    bw.close();
} catch (IOException e) {

}

#转换流(理解)

两个类(可以在读写时,指定编码集)

  • InputStreamReader
  • OutputStreamWriter

jdk11后使用

  • FileWriter 和FileReader

构造方法

方法名说明
InputStreamReader(InputStream in)使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset)使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out)使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset)使用指定的字符编码创建OutputStreamWriter对象

代码演示

  • 用OutputStreamWriter 写入汉字 指定编码
  • 用InputStreamReader 读取汉字 指定编码
public class ConversionStreamDemo {
    public static void main(String[] args) throws IOException {
        
        //创建写入的转换流对象 使用默认编码
        //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
        //创建写入的转换流对象  指定编码为gbk
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
        osw.write("中国");
        osw.close();

        //创建读取的转换流对象 使用默认编码
        //InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));
        //创建读取的转换流对象  指定编码为gbk
        InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
        //一次读取一个字符数据
        int ch;
        while ((ch=isr.read())!=-1) {
            System.out.print((char)ch);
        }
        isr.close();
    }
}

注意:jdk11后用文件读写流就可以指定编码了

    public static void main(String[] args) throws IOException {
        //jdk11后 支持指定编码解码方式
        //参数2指定编码为utf-8 注意语法是Charset.forName()
        FileWriter fw = new FileWriter("qqqqqq.txt", Charset.forName("utf-8"));
        fw.write("开心的文字 拆迁啦");
        fw.close();

        //参数2 指定解码方式为utf-8
        FileReader fr = new FileReader("qqqqqq.txt", Charset.forName("utf-8"));
        char[] cs = new char[1000];
        //读取数据到数组
        int len = fr.read(cs);
        //关闭流
        fr.close();
        System.out.println(new String(cs, 0, len));

    }

在这里插入图片描述

对象操作流

Serializable  可序列化的  形容词
Serializer    序列化器   名词
Serialize     序列化    动词


对象 -- 》 字节序列  就可以保存 在文件里  也可以在网络中传输
 新闻
class News Implements SerializableString  tilte;
Strint content;
Date  date;News n = new News();


 //创建对象输出流
 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("news.txt"));

 //把对象写入
 oos.writeObject(n);
 //关闭流
 oos.close();
 
 
 javasscript
前端收到的是新闻的字节数据  
把字节数据 转回成对象   反序列化

对象序列化流

  • 对象序列化介绍

    • 对象序列化:把对象转换为可以存储或传输的形式的过程
    • 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
    • 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息。反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
  • 对象序列化流: ObjectOutputStream

    • 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
  • 构造方法

    方法名说明
    ObjectOutputStream(OutputStream out)创建一个写入指定的OutputStream的ObjectOutputStream
  • 序列化对象的方法

    方法名说明
    void writeObject(Object obj)将指定的对象写入ObjectOutputStream

代码

  • 动物类
public class Anima implements Serializable {

    public String name;
    protected int age;

    public Anima() {
    }

    public Anima(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Anima{" +
                "name='" + name + '\'' +
                ", age=" + age;
    }
}

测试类

public class Demo01 {
    public static void main(String[] args) throws IOException {
        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("animal.txt"));
        //Anima类要实现Serializable接口
        Anima a = new Anima("大象", 3);
        //把对象写入
        oos.writeObject(a);
        //关闭流
        oos.close();
    }
}

注意事项

  • 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
  • Serializable是一个标记接口,实现该接口,不需要重写任何方法

对象反序列化流

  • 对象反序列化流: ObjectInputStream

    • ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
  • 构造方法

    方法名说明
    ObjectInputStream(InputStream in)创建从指定的InputStream读取的ObjectInputStream
  • 反序列化对象的方法

    方法名说明
    Object readObject()从ObjectInputStream读取一个对象

代码

//创建对象输出流
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("animal.txt"));

//读取出对象 然后强转为Anima对象  这个过程也叫反序列化
Anima a = (Anima) oos.readObject();
oos.close();
//打印读取的对象
System.out.println(a);

serialVersionUID&transient

  • serialVersionUID
    • 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
      • 会出问题,会抛出InvalidClassException异常
Exception in thread "main" java.io.InvalidClassException: com.heima1.test3.Anima; local class incompatible: stream classdesc serialVersionUID = 4726774650000051461, local class serialVersionUID = -3497608134273938572
  • 如果出问题了,如何解决呢?

    • 1给对象所属的类加一个serialVersionUID

      • private static final long serialVersionUID = 42L;
    • 2重新序列化,再次测试

transient

  • 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢
    • 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程

代码

  • 学生类
public class Anima implements Serializable {

    public static final long serialVersionUID = 42L;

    public String name;
    public int age;

    //transient表示在序列化的时候,忽略当前的字段
    public transient int weight;


    public Anima(String name, int age, int weight) {
        this.name = name;
        this.age = age;
        this.weight = weight;
    }

    public Anima() {
    }

    @Override
    public String toString() {
        return "Anima{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", weight=" + weight +
                '}';
    }
  • 序列化测试
    • Anima对象 有一个400斤的体重,然后执行writeObject保存
        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("xiongda.txt"));

        //Anima类要实现Serializable接口
        Anima a = new Anima("熊大", 7, 400);
        //把对象写入
        oos.writeObject(a);

        oos.close();
  • 反序列化测试
    • 读取对象后打印,发现体重为0.0
    • 应为weight被transient修饰,数据没有被保存
        //创建对象输出流
        ObjectInputStream oos = new ObjectInputStream(new FileInputStream("xiongda.txt"));

        //读取出对象 然后强转为Anima对象  这个过程也叫反序列化
        Anima a = (Anima) oos.readObject();

        oos.close();
        //打印读取的对象
        System.out.println(a);//Anima{name='熊大', age=7, weight=0}

对象操作流练习

案例需求

  • 创建多个学生类对象写到文件中,再次读取到内存中

步骤

  • 1创建序列化流对象
  • 2创建多个学生对象
  • 3将学生对象添加到集合中
  • 4将集合对象序列化到文件中
  • 5创建反序列化流对象
  • 6将文件中的对象数据,读取到内存中

代码实现

  • 学生类
public class Student implements Serializable{
    
    private static final long serialVersionUID = 2L;

    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 测试类
public class Demo01 {
    public static void main(String[] args) {
        //创建多个学生类对象写到文件中,再次读取到内存中

        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            //- 1创建序列化流对象
            oos = new ObjectOutputStream(new FileOutputStream("module01/stu.data"));
            //- 2创建多个学生对象
            Student stu01 = new Student("xiaoming", 20);
            Student stu02 = new Student("xiaohong", 21);
            Student stu03 = new Student("pgo", 30);
            //- 3将学生对象添加到集合中
            ArrayList<Student> stus = new ArrayList<>();
            stus.add(stu01);
            stus.add(stu02);
            stus.add(stu03);

            //- 4将集合对象序列化到文件中
            oos.writeObject(stus);
            //- 5创建反序列化流对象
            ois = new ObjectInputStream(new FileInputStream("module01/stu.data"));
            //- 6将文件中的对象数据,读取到内存中
            ArrayList<Student> ss = (ArrayList<Student>) ois.readObject();
            System.out.println(ss);

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("读写失败");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("找不到class");
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

小结

字节流
FileOutputStream  FileInputStream   read  write
BufferedOutputStream  BufferedInputStream

字符流
FileReader  FileWriter
BufferedReader  readLine  BufferedWriter  newLine

转换流
InputStreamReader  OutputStreamWriter

对象流
ObjectInputStream  ObjectOutputStream

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

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

相关文章

2022年为什么要学习C语言?

为什么学习c语言 为什么学C语言逻辑&#xff1f; 为什么要学习C语言&#xff1f; 学习C语言的主要理由有以下几点&#xff1a; C语言可以作为学习计算机程序设计语言的入门语言&#xff1b; C语言是编写操作系统的首选语言&#xff0c;与计算机硬件打交道时灵巧且高效&…

labelImag安装与使用及构造数据集

在做目标检测任务时&#xff0c;需要进行标注&#xff0c;选择了LabelImg作为标注工具&#xff0c;下面是安装及使用过程。 我们使用Anconda的虚拟环境进行安装&#xff0c;激活环境后&#xff0c;执行&#xff1a; pip install labelimg -i https://pypi.tuna.tsinghua.edu.c…

代码随想录算法训练营第四天 java : 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交,142环形链表II

文章目录Leetcode 24. 两两交换链表中的节点题目链接本题思路需要注意的点AC 代码Leetcode 19.删除链表的倒数第N个节点题目链接需要注意的点AC代码Leetcode面试题 02.07. 链表相交题目链接这个略了Leetcode 142环形链表II题目链接难点:AC代码今日收获**一朵玫瑰正马不停蹄地成…

【Linux】Linux下基本指令(三)

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Linux》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1. Linux基本指令&#xff1a;&#xff08;续&#xff09; 1.1zip指令和u…

极智编程 | C++模板函数

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多笔记分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 C模板函数。 模板函数是 C 中一种特殊的函数&#xff0c;它的类型参数列表用尖括号 <> 括起来&#xff0c;放在函数名的后面。使用模板函数&a…

Go 并发

来自 《Go 语言从入门到实战》 的并发章节学习笔记&#xff0c;欢迎阅读斧正&#xff0c;感觉该专栏整体来说对有些后端编程经验的来说比无后端编程经验的人更友好。。 Thread VS Groutine 创建时默认 Stack 大小&#xff1a;前者默认 1M&#xff0c;Groutint 的 Stack 初始化…

C语言可变参数与内存管理

有时&#xff0c;您可能会碰到这样的情况&#xff0c;您希望函数带有可变数量的参数&#xff0c;而不是预定义数量的参数。C 语言为这种情况提供了一个解决方案&#xff0c;它允许您定义一个函数&#xff0c;能根据具体的需求接受可变数量的参数。下面的实例演示了这种函数的定…

LeetCode题解 二叉树(八):404 左叶子之和;513 找树左下角的值;112 路径总和;113 路径总和II

二叉树 404 左叶子之和 easy 左叶子结点也好判断&#xff0c;若某结点属于左结点&#xff0c;且无子树&#xff0c;就是左叶子结点 即也如此&#xff0c;所以如果要判断&#xff0c;必然要从父结点下手&#xff0c;涉及到三层结点的处理 如果要使用递归法&#xff0c;要使用…

(二十三)大白话数据库服务器上的RAID存储架构的电池充放电原理

文章目录 1、RAID卡的缓存2、RAID卡的缓存里的数据会突然丢失怎么办?3、锂电池存在性能衰减问题1、RAID卡的缓存 服务器使用多块磁盘组成的RAID阵列的时候,一般会有一个RAID卡,这个RAID卡是带有一个缓存的,这个缓存不是直接用我们的服务器的主内存的那种模式,他是一种跟内…

网络静态路由综合实验

1.首先分配ip,配置ip和环回 [Huawei]sysname R1 [R1]interface LoopBack 0 [R1-LoopBack0]ip add 192.168.1.33 28 [R1-LoopBack0]q [R1]int l 1 [R1-LoopBack1]ip add 192.168.1.49 28 [R1-LoopBack1]q [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 192.168.1.1 30 [R1-…

JVM与Java体系结构

目录 前言 架构师每天都在思考什么&#xff1f; Java vs C Java生态圈 字节码 多语言混合编程 虚拟机与Java虚拟机 虚拟机 Java虚拟机 JVM的位置 JVM整体结构 Java代码执行流程 JVM的架构模型 举例 字节码反编译 总结 栈 JVM生命周期 虚拟机的启动 虚拟机的…

时间从来不语,确回答了所有问题——我的2022年终总结

趁着没阳&#xff0c;趁着电脑还能开机&#xff0c;趁着还能写&#xff0c;赶紧小结过去这一年。没有别的感觉&#xff0c;就是感觉太快&#xff0c;时间太过匆匆.....最大的感触是两个字“变化”&#xff0c;如果非要说四个字是“变化太快”&#xff0c;就如当下的yi情政策&am…

多线程_进阶

文章目录线程通信概念使用方式案例单例模式阻塞式队列线程池常见的锁策略乐观锁 悲观锁CASCAS存在的问题:ABA问题读写锁自旋锁公平锁 非公平锁非公平锁公平锁synchronizedjvm对synchronized的优化:锁升级synchronized的其他优化Lock体系synchronized vs lock独占锁vs共享锁独占…

Arch/Manjaro换源+安装常用的软件+安装显卡驱动

本文将教你&#xff1a;换源安装显卡驱动&#xff0c;安装常用软件例如腾讯会议&#xff0c;QQ&#xff0c;WPS 一起交流Linux知识&#xff0c;欢迎加入Skype群&#xff1a; Join conversationhttps://join.skype.com/q6wrF3d6Usni pacman换清华源 首先安装vim&#xff0c;用来…

(二十四)大白话RAID锂电池充放电导致的MySQL数据库性能抖动的优化

案例实战:RAID锂电池充放电导致的MySQL数据库性能抖动的优化 文章目录 1、磁盘故障怎么保障数据不丢失?2、线上MySQL数据库的性能定期抖动的原因1、磁盘故障怎么保障数据不丢失? 前面经过了几天的生产经验的一些铺垫,包括MySQL磁盘读写的机制,Linux存储系统的原理,RAID磁…

垃圾佬图拉丁装机

理论知识 缩线程 amd搞了个推土机架构 两个核心公用一个浮点运算单元&#xff0c;因为浮点运算只占百分之二十。 浮点运算应该交给更适合的gpu去做 好的对比 RDP 微软的RDP本身就定位是一个远程登录和维护windows系的工具&#xff0c;它为什么要支持管理别的系统&#xff…

【mybatis generator实战】 1.crud 2.计数 3.自定义复杂mapper代码组织

1.计数 2.CRUD 增 注意&#xff1a; insert&#xff1a;一个必须全部有值。 insertSelective是&#xff1a;部分有值就行&#xff0c;用的较多。 有疑问可以看源码&#xff0c;发现xxxSelective就是拼接了一些参数。 删 改 注意&#xff1a; 4个更新方法&#xff1a; …

QML学习笔记【06】:QML与C++交互

1 QML端直接调用C端变量及函数 1、 创建继承自QObject的C类&#xff0c;对象必须继承自QObject才能在QML被使用和访问 2、在类定义中使用Q_PROPERTY导出成员的READ、WRITE、NOTIFY接口&#xff0c;这样类中的成员变量就可以在QML调用和修改了&#xff0c;同时变量被修改后也会…

剑指 Offer 18. 删除链表的节点

一、题目描述 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点&#xff0c;那么在调用了你的函数之后&#xf…

2022年最后一篇推文 | C语言编程十诫

正文大家好&#xff0c;我是bug菌~2022年最后一篇推文原本选择一篇年终总结会比较合适&#xff0c;然而坐在窗台&#xff0c;望着窗外思索了良久&#xff0c;与往年总结有点不同&#xff0c;这个时间节点有着他的特殊性&#xff0c;不出意外&#xff0c;明年会有非常多的变化、…