【JavaEE初阶】 文件内容的读写 —— 数据流

news2025/3/3 17:59:53

文章目录

  • 🌴数据流的概念
    • 🚩数据流分类
  • 🌳字节流的读写
    • 🛫InputStream(从文件中读取字节内容)
      • 🚩实例一
      • 🚩实例二
      • 🚩利用 Scanner 进行字符读取
    • 🛬OutputStream(向文件中写内容)
      • 🚩实例一
      • 🚩实例二
      • 🚩实例三
  • 🎄字符流的读写
    • 🛫Reader(读操作)
    • 🛬Writer(写操作)
  • 😎小程序练习
    • ⚽练习一
    • 🏀练习二
    • ⚾练习三
  • ⭕总结

🌴数据流的概念

在这里插入图片描述

数据流是一串连续不断的数据的集合,就象水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。

数据写入程序可以是一段、一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。

不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。

“流是磁盘或其它外围设备中存储的数据的源点或终点。”

在电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。这里总结从外存读取数据到内存以及将数据从内存写到外存中。

对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。那又怎样把放在外存这个容器内的数据读取到内存这个容器以及怎么把内存这个容器里的数据存到外存中呢?

在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:

标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。

流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。

总结的基本概念如下:

  • 数据流:一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。
  • 输入流(Input Stream):程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道
  • 输出流(Output Stream):程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

采用数据流的目的就是使得输出输入独立于设备。Input Stream不关心数据源来自何种设备(键盘,文件,网络)Output Stream不关心数据的目的是何种设备(键盘,文件,网络)

🚩数据流分类

流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:

  • 字节流:数据流中最小的数据单元是字节

  • 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。

🌳字节流的读写

🛫InputStream(从文件中读取字节内容)

该类提供的方法有以下几种

修饰符及返回值类型方法签名说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了
intread(byte[] b,int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流

注意:InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream

FileInputStream 的 构造方法

签名说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

我们在使用该实例化对对象进行操作时我们该可以分为以下几步

  1. 打开文件

  2. 进行读写操作

  3. 关闭文件

但是这里我们需要注意的是,每一次打开文件都会消耗一些相应的资源,而每一个进程的资源时有限的,所以我们一定要注意关闭文件操作,但是关闭文件操作可能会因为某些情况忘记写,或者没执行到。这时候就会出现问题

这时候我们想到一个办法,使用final进行执行这一步操作

InputStream reader = new FileInputStream("D:/tmp.txt");
try {
	//一系列读写操作
} finally {
	reader.close();
}

但是这样写太繁琐,代码也不美观,所以Java里面提供了以下写法

try(InputStream reader = new FileInputStream("D:/tmp.txt")) {
	//	一系列操作
}

这里虽然没有写会执行到close,但是在try执行结束后就会执行到;

这是因为该类实现了Closeable接口
在这里插入图片描述

🚩实例一

首先我们准备一个文件内容和路径如下:
在这里插入图片描述

接下来展示两种文件读的方式

  • 方式一:一个一个读
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("D:/tmp.txt")) {
            while (true) {
                int b = is.read();
                if (b == -1) {
                // 代表文件已经全部读完
                    break;
                }
                System.out.print((char)b + "");
            }
        }
    }
}

结果如下:
在这里插入图片描述

  • 方式二:缓冲区读法

先将一部分读取字节装入一个字节数组里,然后再读取数组里面的数据

代码如下:

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("D:/tmp.txt")) {
            while (true) {
                byte[] buffer = new byte[1024];
                int b = is.read(buffer);
                if (b == -1) {
                // 代表文件已经全部读完
                    break;
                }
                for(int i = 0; i < b ; i ++) {
                    System.out.print((char) buffer[i] + "");
                }
            }
        }
    }
}

结果如下:
在这里插入图片描述

  • 两种方式对比:

更推荐方式二,效率更高,就比如你练习网球发球,你需要不断的发球,一大筐网球放在体育教材室里面,你现在有两种做法,第一种一次:拿一个来发球,发完了,又回去拿,第二种:一次拿一筐放在脚边不断发球

很明显第二种效率更高,上述两种方式也是如此

🚩实例二

这里我们把文件内容中填充中文看看,tmp.txt 中填写 “你好中国”
在这里插入图片描述
注意:写中文的时候使用 UTF-8 编码。如果强转为char会出现乱码问题。

我们使用16进制对结果进行输出时,就输出的是它们各自对应的 UTF-8 编码,如下所示:
在这里插入图片描述
三个字节表示一个字

这里我们就可以利用了这几个中文的 UTF-8 编码后长度刚好是 3 个字节和长度不超过 1024 字节的现状,但这种方式并不是通用的

代码如下:

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("D:/tmp.txt")) {
            while (true) {
                byte[] buffer = new byte[1024];
                int b = is.read(buffer);
                if (b == -1) {
                // 代表文件已经全部读完
                    break;
                }
                // 每次使用 3 字节进行 utf-8 解码,得到中文字符
                // 利用 String 中的构造方法完成
                // 这个方法了解下即可,不是通用的解决办法
                for (int i = 0; i < b; i += 3) {
                    String s = new String(buffer, i, 3, "UTF-8");
                    System.out.printf("%s", s);
                }
            }
        }
    }
}

结果入下:
在这里插入图片描述

🚩利用 Scanner 进行字符读取

上述例子中,我们看到了对字符类型直接使用 InputStream 进行读取是非常麻烦且困难的,所以,我们使用一种我们之前比较熟悉的类来完成该工作,就是 Scanner 类

构造方法说明
Scanner(InputStream is, String charset)使用 charset 字符集进行 is 的扫描读取

代码实现如下:

import java.io.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        try (InputStream is = new FileInputStream("d:/tmp.txt")) {
            try (Scanner scanner = new Scanner(is, "UTF-8")) {
                while (scanner.hasNext()) {
                    String s = scanner.next();
                    System.out.print(s);
                }
            }
        }
    }
}

结果如下:
在这里插入图片描述

🛬OutputStream(向文件中写内容)

该类的方法有:

修饰符及返回值类型方法签名说明
voidwrite(int b)写入要给字节的数据
voidwrite(byte[]b)将 b 这个字符数组中的数据全部写入 os 中
intwrite(byte[]b, int off,int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,所以使用 FileOutputStream,构造方法与上述FileInputStream构造方法一样的,与实现都是一样的,这里就不做过多诠释

接下来简单展示一下几个实例

我们先准备该路径下的该文件
在这里插入图片描述

🚩实例一

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class IODemo1 {
    public static void main(String[] args) {
        try(OutputStream writ = new FileOutputStream("D:/tmp.txt")) {
            writ.write('A');
            writ.write('B');
            writ.write('C');
            writ.write('D');
            writ.write('E');
            writ.flush();
        }  catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

结果如下:
在这里插入图片描述
注意:此处的write操作会先清除该文件里面的内容再进行填充

那么如何才能不清除文件而实现续写呢?其实很简单,我们只需要在构造对象时,使用带有true参数的构造方法就好

比如以下代码对上述文件进行续写操作

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class IODemo1 {
    public static void main(String[] args) {
        try(OutputStream writ = new FileOutputStream("D:/tmp.txt",true)) {
            writ.write('F');
            writ.write('F');
            writ.write('F');
            writ.write('F');
            writ.write('F');
            writ.flush();
        }  catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

结果如下:
在这里插入图片描述
最后注意一点:

  • 我们在写操作完成后,一定要flush冲刷一下,也就是刷新一下

🚩实例二

使用字符数组

  • 代码一

import java.io.*;

public class IOdemo2 {
    public static void main(String[] args) throws FileNotFoundException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            byte[] b = new byte[] {
                    (byte)'G', (byte)'o', (byte)'o', (byte)'d'
            };
            os.write(b);
            // 不要忘记 flush
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
  • 代码二
import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            byte[] b = new byte[] {
                    (byte)'G', (byte)'o', (byte)'o', (byte)'d', (byte)'B',
                    (byte)'a', (byte)'d'
            };
            os.write(b, 0, 4);
            // 不要忘记 flush
            os.flush();
        }
    }
}
  • 代码三
import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            String s = "Nothing";
            byte[] b = s.getBytes();
            os.write(b);
            // 不要忘记 flush
            os.flush();
        }
    }
}

这里就不展示结果了

🚩实例三

写入汉字

import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        try (OutputStream os = new FileOutputStream("output.txt")) {
            String s = "遇事问春风";
            byte[] b = s.getBytes("utf-8");
            os.write(b);
            // 不要忘记 flush
            os.flush();
        }
    }
}

结果如下:
在这里插入图片描述

🎄字符流的读写

字符流的操作比字节流操作更加简单,而且方法类似,下面只是简单展示一下基本用法。不做过多赘述

🛫Reader(读操作)

这里是需要实例化一个 FileReader进行操作,可使用的方法参考字节流

这里的字符流操作与字节流操作类似,这里不做过多赘述,直接看代码

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class IODemo3 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("D:/tmp.txt")) {
            while(true) {
                int n = reader.read();
                if(n == -1) {
                    break;
                }
                System.out.print((char)n + "");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

结果如下:
在这里插入图片描述
再来一个数组版本的吧

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class IODemo3 {
    public static void main(String[] args) {
        char[] arr = new char[1024];
        try(Reader reader = new FileReader("D:/tmp.txt")) {
            while(true) {
                int n = reader.read(arr);
                if(n == -1) {
                    break;
                }
                for(int i = 0; i < n ; i ++) {
                    System.out.print(arr[i] + "");
                }

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

结果如下:
在这里插入图片描述

🛬Writer(写操作)

准备文件路径内容如下:
在这里插入图片描述
实例代码如下:

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class IODemo4 {
    public static void main(String[] args) {
        try(Writer writ = new FileWriter("D:/tmp.txt")) {
            writ.write("祝遇事问春风乄博主早日成为大牛!");
            writ.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

结果展示如下:
在这里插入图片描述

😎小程序练习

这里不做过多赘述,只展示代码,有需要讲解的小伙伴可以私信博主

⚽练习一

扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要
删除该文件

import java.io.*;
import java.util.*;
public class Test1 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要扫描的根目录(绝对路径 OR 相对路径): ");
        String rootDirPath = scanner.next();
        File rootDir = new File(rootDirPath);
        if (!rootDir.isDirectory()) {
            System.out.println("您输入的根目录不存在或者不是目录,退出");
            return;
        }
        System.out.print("请输入要找出的文件名中的字符: ");
        String token = scanner.next();
        List<File> result = new ArrayList<>();
// 因为文件系统是树形结构,所以我们使用深度优先遍历(递归)完成遍历
        scanDir(rootDir, token, result);
        System.out.println("共找到了符合条件的文件 " + result.size() + " 个,它们分别是");
        for (File file : result) {
            System.out.println(file.getCanonicalPath() + " 请问您是否要删除该文件?y/n");
                    String in = scanner.next();
            if (in.toLowerCase().equals("y")) {
                file.delete();
            }
        }
    }
    private static void scanDir(File rootDir, String token, List<File> result) {
        File[] files = rootDir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                scanDir(file, token, result);
            } else {
                if (file.getName().contains(token)) {
                    result.add(file.getAbsoluteFile());
                }
            }
        }
    }
}

🏀练习二

进行普通文件的复制

import java.io.*;
import java.util.*;
public class Test2 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要复制的文件(绝对路径 OR 相对路径): ");
        String sourcePath = scanner.next();
        File sourceFile = new File(sourcePath);
        if (!sourceFile.exists()) {
            System.out.println("文件不存在,请确认路径是否正确");
            return;
        }
        if (!sourceFile.isFile()) {
            System.out.println("文件不是普通文件,请确认路径是否正确");
            return;
        }
        System.out.print("请输入要复制到的目标路径(绝对路径 OR 相对路径): ");
        String destPath = scanner.next();
        File destFile = new File(destPath);
        if (destFile.exists()) {
            if (destFile.isDirectory()) {
                System.out.println("目标路径已经存在,并且是一个目录,请确认路径是否正确");
                return;
            }
            if (destFile.isFile()) {
                System.out.println("目录路径已经存在,是否要进行覆盖?y/n");
                String ans = scanner.next();
                if (!ans.toLowerCase().equals("y")) {
                    System.out.println("停止复制");
                    return;
                }
            }
        }
        try (InputStream is = new FileInputStream(sourceFile)) {
            try (OutputStream os = new FileOutputStream(destFile)) {
                byte[] buf = new byte[1024];
                int len;
                while (true) {
                    len = is.read(buf);
                    if (len == -1) {
                        break;
                    }
                    os.write(buf, 0, len);
                }
                os.flush();
            }
        }
        System.out.println("复制已完成");
    }
}

注意:此处复制时,只需要源文件存在就行,目的文件如果不存在,目的文件路径下会自动创建一个文件

⚾练习三

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

注意:我们现在的方案性能较差,所以尽量不要在太复杂的目录下或者大文件下实验

import java.io.*;
import java.util.*;
public class Test3 {
    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要扫描的根目录(绝对路径 OR 相对路径): ");
        String rootDirPath = scanner.next();
        File rootDir = new File(rootDirPath);
        if (!rootDir.isDirectory()) {
            System.out.println("您输入的根目录不存在或者不是目录,退出");
            return;
        }
        System.out.print("请输入要找出的文件名中的字符: ");
        String token = scanner.next();
        List<File> result = new ArrayList<>();
		// 因为文件系统是树形结构,所以我们使用深度优先遍历(递归)完成遍历
        scanDirWithContent(rootDir, token, result);
        System.out.println("共找到了符合条件的文件 " + result.size() + " 个,它们分别是");
        for (File file : result) {
            System.out.println(file.getCanonicalPath());
        }
    }
    private static void scanDirWithContent(File rootDir, String token,
                                           List<File> result) throws IOException {
        File[] files = rootDir.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                scanDirWithContent(file, token, result);
            } else {
                if (isContentContains(file, token)) {
                    result.add(file.getAbsoluteFile());
                }
            }
        }
    }
    // 我们全部按照utf-8的字符文件来处理
    private static boolean isContentContains(File file, String token) throws
            IOException {
        StringBuilder sb = new StringBuilder();
        try (InputStream is = new FileInputStream(file)) {
            try (Scanner scanner = new Scanner(is, "UTF-8")) {
                while (scanner.hasNextLine()) {
                    sb.append(scanner.nextLine());
                    sb.append("\r\n");
                }
            }
        }
        return sb.indexOf(token) != -1;
    }
}

⭕总结

关于《【JavaEE初阶】 文件内容的读写 —— 数据流》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

数据持久化的利器,Python中的pickle模块详解

Python数据序列化和反序列化时&#xff0c;pickle模块是一个非常有用的工具。它允许将Python对象转换为字节流&#xff0c;以便存储在文件中或通过网络传输&#xff0c;然后将这些字节流重新转换回Python对象。 什么是Pickle&#xff1f; pickle是Python标准库中的一个模块&a…

2023最新最全【Android studio】安装入门教程(非常详细)手把手教你安装使用!【附安装包】

软件下载 软件&#xff1a;Android Studio版本&#xff1a;2022语言&#xff1a;英文大小&#xff1a;1G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨下载链接&#xff1a;https://pan.baidu.com/…

go中“哨兵错误”的由来及使用建议

“哨兵错误&#xff08;sentinel error&#xff09;”这个词的出处。之前我也只是在一些书籍和资料中见到过&#xff0c;也没深究。当这个网友问了我之后&#xff0c;就深入的翻了翻资料&#xff0c;在golang的官方博客中找到了这个词的提法&#xff0c;也算是比较官方的了吧。…

公众号快速配置AI智能问答,在公众号集成类似ChatGPT的AI聊天机器人

目录 前言 一、使用步骤 1、助手体验 2、助手训练 2、公众号集成 前言 今天无意间发现一个名为“天书AI”的产品&#xff0c;是一款AI知识库产品&#xff0c;可以集成在微信公众号消息接口中。可以将公众号基于自己的知识内容升级为智能问答工具&#xff0c;提供类似ChatGPT的…

苹果相机怎么磨皮 苹果手机怎么磨皮

相信使用苹果相机的小伙伴都有这样的疑惑&#xff0c;苹果相机怎么磨皮&#xff1f;其实可以通过相机的参数进行设置从而达到磨皮的效果&#xff0c;如果觉得相机自带的设置磨皮效果不够好&#xff0c;可以下载磨皮软件来对照片磨皮。今天的文章就来给大家介绍苹果相机怎么磨皮…

MetaAI提出全新验证链框架CoVE,大模型也可以通过“三省吾身”来缓解幻觉现象

​ 论文名称&#xff1a; Chain-of-Verification Reduces Hallucination in Large Language Models 论文链接&#xff1a; https://arxiv.org/abs/2309.11495 曾子曰&#xff1a;“吾日三省吾身” --出自《论语学而》 时至今日&#xff0c;生成幻觉&#xff08;hallucination&…

LeetCode刷题---合并两个有序数组

该题用到了归并排序&#xff0c;正常的归并排序算法是两个数组依次比对元素大小&#xff0c;最后按照要求将比对结果放入新的数组中&#xff0c;但是此题题目中要求将结果放入第一个数组中。 解题思路:可以定义两个指针&#xff0c;分别指向两个数组中的有效元素的最后一个元素…

什么是TCP三次握手和四次挥手?

三次握手是建立TCP连接时使用的一种协议。它确保了通信双方可以建立可靠的连接。大致流程如下&#xff1a; 第一次握手&#xff08;SYN&#xff09;&#xff1a;客户端发送一个带有SYN标志的请求连接&#xff08;SYN包&#xff09;给服务器&#xff0c;并指明客户端的初始序列号…

跨境电商大作战:2023黑色星期五准备指南

黑色星期五&#xff0c;作为全球购物狂欢的象征&#xff0c;已经成为了电商业务的一年一度的重要节点。尤其对于跨境电商来说&#xff0c;这一天意味着巨大的商机和挑战。为了在这个竞争激烈的时刻脱颖而出&#xff0c;跨境电商必须做好充分的准备。Nox聚星在这里给大家分享几个…

电平信号、脉冲信号

简单来说&#xff0c;电平信号是表示某种特定状态的信号&#xff0c;而脉冲信号则是用来进行状态转移或者激发操作的信号 一、电平&#xff1a;数字电路的输入输出端某一时刻电压的高低&#xff0c;高低电平是相对的、人为的&#xff0c;例如可以规定低电平为0V&#xff0c;相…

Microsoft Edge不能工作了,可能原因不少,那么如何修复呢

Microsoft Edge打不开或不能加载网页是用户在Windows 10、Android、Mac和iOS设备上的网络浏览器上遇到的许多错误之一。其他Microsoft Edge问题可能包括浏览器窗口和选项卡冻结、网站崩溃、互联网连接错误消息以及丢失Microsoft Edge书签、收藏夹、密码和收藏。 Microsoft Edg…

【广州华锐互动】3D初中化学线上实验室定制开发

在科学的世界中&#xff0c;理论和实践一直起着至关重要的作用。然而&#xff0c;传统的化学实验通常需要复杂的设备和昂贵的材料&#xff0c;这在一定程度上限制了学生的实验能力和科学探索的热情。在这种背景下&#xff0c;3D初中化学线上实验室应运而生&#xff0c;它使用计…

基于51单片机篮球计时器计分器设计(源码+原理图+PCB+仿真+设计报告+讲解视频)

# 基于51单片机篮球计分器proteus仿真 51单片机篮球计分器proteus仿真&#xff08;源码原理图PCB仿真设计报告讲解视频&#xff09; 仿真&#xff1a;proteus 7.8 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 编号C0004 51单片机篮球计分器 讲解视频1…

数据结构学习笔记——链式表示中的双链表及循环单/双链表

一、双链表 &#xff08;一&#xff09;双链表的定义 双链表是在单链表结点上增添了一个指针域prior&#xff0c;指针域prior指向当前结点的前驱结点&#xff0c;即此时链表的每个结点中都有两个指针域prior和next&#xff0c;从而可以很容易通过后继结点找到前驱结点&#x…

win11 以太网和WLAN冲突 连接网线时导致WiFi掉线 解决

由于特殊情况&#xff0c;电脑需要同时连接网线和WiFi。 网线&#xff08;以太网卡&#xff09;是一个网段。WiFi&#xff08;WLAN无线网卡&#xff09;是另一个网段。 目的是让电脑同时连接两种网段的网络。 出现问题&#xff1a;当已经连接WiFi时&#xff0c;再插入网线&a…

闪站侠洗衣洗鞋店专用管理软件,支持APP扫码洗衣、洗鞋、收衣、出入库、收衣拍照、手机报表、线上会员等功能。

闪站侠洗衣洗鞋店专用管理软件&#xff0c;支持APP扫码洗衣、洗鞋、收衣、出入库、收衣拍照、手机报表、线上会员等功能。它直观管理库存&#xff0c;快速整理数据&#xff0c;一站式全方位提升洗衣效率&#xff01;洗衣洗鞋店管理软件精选商品&#xff0c;热卖材质&#xff0c…

基于联合表示学习、用户聚类和模型自适应的个性化联合推荐

[Personalized Federated Recommendation via Joint Representation Learning, User Clustering, and Model Adaptation] (https://dl.acm.org/doi/abs/10.1145/3511808.3557668) CIKM2022(CCF-B) 论文精读 文章主要创新点(消融实验分析的三个点)&#xff1a; 联合表示学习 …

数据结构(超详细讲解!!)第十八节 串(堆串)

1.定义 假设以一维数组heap &#xff3b;MAXSIZE&#xff3d; 表示可供字符串进行动态分配的存储空间&#xff0c;并设 int start 指向heap 中未分配区域的开始地址(初始化时start 0) 。在程序执行过程中&#xff0c;当生成一个新串时&#xff0c;就从start指示的位置起&#…

电脑上数据恢复的详细操作

在日常使用电脑过程中&#xff0c;我们可能会遇到数据丢失的情况。无论是因为误删除、格式化、病毒攻击还是硬件故障&#xff0c;数据恢复都是我们迫切需要解决的问题。本文将介绍电脑数据恢复的详细操作步骤&#xff0c;帮助读者在面临数据丢失时能够迅速地恢复重要文件。 一…

将WebP转换为GIF的各种图像转换器,当然是免费的方式

第 1 部分。什么是 WebP Web 图片格式 (WebP) 是一种图像格式&#xff0c;可为网站上的照片提供卓越的无损压缩。该网站将使用这种格式运行得更快&#xff0c;创建更小、更丰富的图像。此格式比 PNG 图像小 26%&#xff0c;比 JPEG 图像小 25-24%。这样一来&#xff0c;它使网站…