【JavaEE精炼宝库】文件操作(2)——文件内容读写 | IO流

news2024/9/22 21:15:38

文章目录

  • 一、输入流
    • 1.1 InputStream 概述:
    • 1.2 read 方法详解:
    • 1.3 close 方法:
    • 1.4 利用 Scanner 进行读操作:
    • 1.5 Reader:
  • 二、输出流
    • 2.1 OutputStream 概述:
    • 2.2 write 方法详解:
    • 2.3 利用 PrintWriter 进行写操作:
  • 三、小程序练习
    • 3.1 程序1:
    • 3.2 程序2:
    • 3.3 程序3:

在上一篇文章主要讲述了 Java 针对文件系统进行操作(创建文件,删除文件,创建目录,重命名文件)。本文章是上一篇文章的续集,主要讲述 Java 针对文件内容进行操作(读文件,写文件)。

读写操作就涉及到流的概念,Java 中通过 ‘流’(stream)这样的一组类,进行上述的文件内容操作。
在这里插入图片描述

主要分为输入流(InputStream)和输出流(OutputStream)这两类。

一、输入流

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

1.1 InputStream 概述:

  • 方法:
修饰符及返回值类型方法签名说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了。
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数量。-1 代表已经读完了。
intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量。-1 代表已经读完了。
voidclose()关闭字节流。
  • 构造方法:
签名说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

1.2 read 方法详解:

不难看到 read 方法有 3 种使用的版本,接下来我会分别给大家演示前两种(第 3 种就是第 2 种加上起点),并进行讲解。
在这里插入图片描述

  • 版本一:无参数,一次读取一个字节。读取到的内容,就通过返回值来进行表示。
    在这里插入图片描述

​​注意:这里的返回值是 int 类型,这是为什么呢?既然一次读取一个字节,返回值不是 byte 就行了?

答:注意有以下三个原因:

  1. 为了能够有额外的空间表示 “到达末尾” -1 这样的情况。
  2. 确保读取到的数据都是正数:从原则上来说,“字节” 这样的概念,本身就是 “无符号”,但是 byte 是带有符号的,使用 int 就可以确保读取出来的字节都是正数。按照 “无符号”的方式来处理了。
  3. 为什么不使用 short,而是使用 int?答:虽然使用 int 较 short 是浪费了 2 个字节。但是还是不建议使用 short 类型,这个类型随着硬件的升级,正在逐渐被取代。对于 32 位 CPU,一次处理 4 个字节的数据,使用 short,操作系统内部还是要把 short 转化成 int 来处理,32 位 CPU 如此,对于 64 位 CPU,short 就更加没有意义了。

案例演示:
关于为什么 inputStream 的创建为什么能为什么要写在try()里面,在后面会有详细解释,这里主要看 read 的使用。

import java.io.*;
public class demo2 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("./text.txt")){//推荐这样的写法。
            while(true){
                int n = inputStream.read();
                if(n == -1) break;
                System.out.printf("0x%x ",n);//按照十六进制打印
            }
        }
    }
}

案例演示结果:
在这里插入图片描述

  • 版本二:带有一个参数 byte[]。
    在这里插入图片描述

版本二和版本一的返回值的含义不太一样,具体差别如下:版本二的返回值代表读入 byte 数组的长度,如果返回 -1 表示读取完毕。 这个写法在 Java 中不太常见,这是一种属于 C++ 式的写法。用参数来作为函数的返回结果(输出型参数)。

一次读取多少,取决于数组的长度和文件内容多少,read 会尽可能把数组填满。

案例演示:

import java.io.*;
public class demo3 {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("./text.txt")){
            byte[] bytes = new byte[1024];
            int n = 0;
            while(true){
                n = inputStream.read(bytes);
                if(n == -1) break;
                for(int i = 0;i < n;i++){
                    System.out.printf("0x%x ",bytes[i]);
                }
            }
        }
    }
}

案例演示结果:
将文件完全读完的两种方式。相比较而言,后一种的 IO 次数更少,性能更好。
在这里插入图片描述

1.3 close 方法:

关闭文件是一个非常关键的操作。

为什么要关闭文件?

答:没关闭文件大部分情况下我们是感知不到的,但是一旦出现问题,就是大事(能击碎年终奖😭)。在打开文件的时候,会在操作系统内核,PCB 结构体(进程)中给“文件描述符表(长度存在上限,并且不能自动扩容)”添加一个元素,这个元素就是表示当前打开文件的相关信息。一旦占满了之后,再尝试打开,就会打开文件失败。(其他的操作,网络通信相关的操作就可能收到影响)。

inputStream.close();

上面的这种写法是一般的关闭文件的方式。但是这样写不太好,因为如果代码前面出现异常或者 return,此时 close 就执行不到了。虽然使用 try finally 可以解决问题,但是写出来的代码不太优化

try(){
	........
}finally{
		inputStream.close();
}

对于老程序猿来说代码是语文,要追求优雅。于是 Java 实现了把流对象的创建写到 try()里,代码执行出了 try{}时,就会自动调用 inputStreamclose 了。

写法如下:

try(InputStream inputStream = new FileInputStream("./text.txt"))

要抛异常(这里没写)。

注意:务必要实现 Closeable 接口的类,才能够放到 try() 里。
在这里插入图片描述

1.4 利用 Scanner 进行读操作:

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

构造方法说明
Scanner(InputStream is)构造一个新的 Scanner ,产生从指定输入流扫描的值。
Scanner(InputStream is, String charset)构造一个新的 Scanner ,产生从指定输入流扫描的值。使用 charset 字符集进行 is 的扫描读取。

示例如下:

public static void main(String[] args) throws IOException {
        try(InputStream inputStream = new FileInputStream("./text.txt")){
            try(Scanner in = new Scanner(inputStream)){

            }
        }
    }

1.5 Reader:

以字符为单位读取数据,在 InputStream 中,虽然可以通过 Scanner 传入字符集来达到读取字符的效果,但是这种办法并不是通用的。我们更推荐使用 Reader 来实现读取字符。
由于 Reader 的使用方法和 InputStream 类的使用方式基本一致,所以这里只叙述 read 方法。

在这里插入图片描述
注意:这里传入的是 char 类型的数组,这样就有足够的内存来保存字符了。

由于写法基本一样,这里就演示版本二(带字符数组)。

import java.io.*;
public class demo2 {
    public static void main(String[] args) throws IOException {
        try(Reader reader = new FileReader("./text.txt")){
            char[] chars = new char[1024];
            while(true){
                int n = reader.read(chars);
                if(n == -1) break;
                for(int i = 0;i < n;i++){
                    System.out.print(chars[i]);
                }
            }
        }
    }
}

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

二、输出流

说明:OutputStream 只是一个抽象类,要使用还需要具体的实现类。关于 OutputStream 的实现类有很多,基本可以认为不同的输出设备都可以对应一个 OutputStream 类,我们现在只关心写文件,所以使用 FileOutputStream。

2.1 OutputStream 概述:

  • 方法:
修饰符及返回值类型方法签名说明
voidwrite(int b)将指定的字节写入此输出流。
voidwrite(byte[] b)b.length字节从指定的字节数组写入此输出流。
intwrite(byte[] b,int off,int len)从指定的字节数组写入 len个字节,从偏移 off开始输出到此输出流。
voidclose()关闭此输出流并释放与此流相关联的任何系统资源。
voidflush()刷新此输出流并强制任何缓冲的输出字节被写出。

解释一下 flush:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用flush(刷新)操作,将数据刷到设备中。

  • 构造方法:
构造方法说明
FileOutputStream(String name)创建文件输出流,以指定的名称写入文件
FileOutputStream(String name,boolean append)创建文件输出流,以指定的名称是否追加写入文件。

注意:在使用 FileOutputStream 创建指定文件对象的时候,如果不在文件名后面加上 true,原有的文件内容会被清空,如果加上 true 就是在原文件内容上追加写。

案例如下:
在这里插入图片描述
执行完try(OutputStream outputStream = new FileOutputStream("./text.txt"))后变成:
在这里插入图片描述

2.2 write 方法详解:

在这里插入图片描述
和 read 一样有三种版本,并且没有返回值,这里就只演示版本二(带byte 数组)。

  • 版本二:一次 write 若干字节。会把参数数组里所有的字节都写入文件中。

代码案例如下:

public class demo5 {
    public static void main(String[] args) throws IOException {
        try(OutputStream outputStream = new FileOutputStream("./text.txt")){
            byte[] bytes = new byte[4];
            for(int i = 0;i < 4;i++){
                bytes[i] = (byte)(97 + i);//对应是字符 abcd
            }
            outputStream.write(bytes);
            outputStream.flush();//不要忘记,flush 刷新缓存
        }
    }
}

案例演示结果:
在这里插入图片描述

2.3 利用 PrintWriter 进行写操作:

注意:OutputStream 也有 close 操作,这里没有单独写,是因为使用和注意点都一样。

上述,我们其实已经完成输出工作,但总是有所不方便,我们接来下将 OutputStream 处理下,使用 PrintWriter 类来完成输出,因为 PrintWriter 类中提供了我们熟悉的 print/println/printf 方法。

案例演示如下:

public class demo6 {
    public static void main(String[] args) throws IOException {
        try(OutputStream outputStream = new FileOutputStream("./text.txt")){
            try(PrintWriter printWriter = new PrintWriter(outputStream)){
                printWriter.print("abcd");
                printWriter.flush();
            }
        }
    }
}

案例演示结果:
在这里插入图片描述

还有一个对应的字符写类 Writer 使用的方法是一样的,就不再赘述了。

三、小程序练习

我们学会了文件的基本操作 + 文件内容读写操作,接下来,我们实现一些小工具程序,来锻炼我们的能力。

3.1 程序1:

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

步骤如下:

  1. 提示用户输入
  2. 找到名称包含指定字符的所有普通文件
  3. 是否删除

源码如下(有详细注释):

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

//扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否
//要删除该⽂件
public class demo1 {
    static Scanner in = new Scanner(System.in);
    public static void main(String[] args) {
        //1提示用户输入
        System.out.println("请输入要查找的文件目录:");
        String dirName = in.next();
        List<File> result = new ArrayList<>();
        //2找到名称包含指定字符的所有普通文件
        File file = new File(dirName);
        //判断输入是否合法
        if(!file.isDirectory()){
            System.out.println("输入的目录不存在");
            return;
        }
        System.out.println("请输入要查找的指定字符:");
        String searchWord = in.next();
        searchFile(file,searchWord,result);
        System.out.println("一共找到了" + result.size() + "种结果");
        for(int i = 0;i < result.size();i++){
            System.out.println((i + 1) + "号:" + result.get(i).getAbsolutePath());
        }
        List<Integer> list = new ArrayList<>();//存储用来删除的下标
        System.out.println("请输入要删除第几号文件(输入0停止删除):");
        int y = in.nextInt();
        while(y != 0){
            y--;
            if(!result.get(y).exists()){
                System.out.println("已经被删除过来");
            }else{
                result.get(y).delete();
                System.out.println("删除成功");
            }
            y = in.nextInt();
        }

    }
    //查找目录底下的所有文件
    public static void searchFile(File file,String searchWord,List<File> result){
        if(file == null) return;//递归出口
        File[] files = file.listFiles();//返回目录底下的文件
        for(int i = 0;i < files.length;i++){
            if(files[i].isDirectory()){//目录的情况
                searchFile(files[i],searchWord,result);
            }else{
                //走到这里说明是普通文件
                //找文件名字是否包含关键字
                if(searchWord(files[i],searchWord)){
                    //包含关键字的情况
                    result.add(files[i]);
                }
            }
        }
    }
    //查找文件名是否包含关键字
    private static boolean searchWord(File file, String searchWord) {
        String fileName = file.getName();
        return fileName.contains(searchWord);
    }
}

程序运行结果如下:可以在电脑上单独创建一个文件夹来测试。
在这里插入图片描述

3.2 程序2:

  • 程序要求:进行普通文件的复制。

步骤如下:

  1. 提示用户输入
  2. 检查输入是否合法
  3. 进行复制

源码如下:

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

//进⾏普通⽂件的复制
public class demo1 {
    public static void main(String[] args) throws IOException {
        Scanner in = new Scanner(System.in);
        //1.提示读入
        System.out.println("请输入要复制的文件");
        String srcFileRoot = in.next();
        //检查输入是否合法
        File srcFile = new File(srcFileRoot);
        if (!srcFile.isFile()) {
            System.out.println("输入的不是普通文件路径");
            return;
        }
        //已经是文件了
        System.out.println("请输入要复制到的文件路径");
        String destFileRoot = in.next();
        File destFile = new File(destFileRoot);
        //检查输入是否合法
        if (destFile.isDirectory()) {
            System.out.println("输入的不是普通文件(路径)");
            return;
        }
        //进行复制
        copyFile(srcFile, destFile);
        System.out.println("复制完毕");
    }
    //复制文件
    public static void copyFile(File srcFile, File destFile) throws IOException {
        try (InputStream inputStream = new FileInputStream(srcFile)) {
            try (OutputStream outputStream = new FileOutputStream(destFile)) {
                byte[] bytes = new byte[1024];
                while (true) {
                    int n = inputStream.read(bytes);
                    if (n == -1) break;
                    outputStream.write(bytes, 0, n);//起点和要复制的长度
                }
                outputStream.flush();
            }
        }
    }
}

程序运行结果如下:
在这里插入图片描述

3.3 程序3:

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

步骤如下:

  1. 提示读入数据
  2. 检查输入是否合法
  3. 查找指定文件

源码如下:


//案例三
//目的:扫描指定⽬录,并找到内容中包含指定字符的所有普通⽂件(不包含⽬录)
import java.util.*;
import java.io.*;
public class demo2 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //提示读入数据
        System.out.println("请输入要搜索的目录:");
        String dirRoot = in.next();
        File dirFile = new File(dirRoot);
        if(!dirFile.isDirectory()){
            System.out.println("目录输入错误");
            return;
        }
        System.out.println("请输入要查找的指定内容");
        String serWord = in.next();
        //查找指定文件
        searchFile(dirFile,serWord);
    }

    private static void searchFile(File dirFile,String serWord) {
        File[] files = dirFile.listFiles();
        //这里不用判断为空
        for(int i = 0;i < files.length;i++){
            if(files[i].isFile()){
                //查找指定内容
                searchWord(files[i],serWord);
            }else if(files[i].isDirectory()){
                //递归进行查找
                searchFile(files[i],serWord);
            }
        }
    }
    private static void searchWord(File file, String serWord) {
        //查找文件内容
        StringBuilder sd = new StringBuilder();
        try(InputStream inputStream = new FileInputStream(file)){
            //读取数据
            while(true){
                int n = inputStream.read();
                if(n == -1) break;
                sd.append((char)n);
            }
            if(sd.indexOf(serWord) >= 0){
                //找到了
                System.out.println("文件路径为:" + file.getAbsolutePath());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

程序运行结果如下:
在这里插入图片描述

结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

在这里插入图片描述

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

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

相关文章

【Sql Server】sql server 2019设置远程访问,外网服务器需要设置好安全组入方向规则

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言1、无法链接…

47、lvs之DR

1、DR模式&#xff1a; 1.1、lvs三种模式&#xff1a; nat 地址转换 DR 直接路由模式 tun 隧道模式 1.2、DR模式的特点&#xff1a; 调度器在整个lvs集群当中是最重要的&#xff0c;在nat模式下&#xff0c;即负载接收请求&#xff0c;同时根据负载均衡的算法转发流量&…

2024 China Joy 前瞻 | 腾讯网易发新作,网易数智携游戏前沿科技、创新产品以及独家礼盒,精彩不断!

今年上半年&#xff0c;CES、MWC和AWE三大国际科技展轮番轰炸&#xff0c;吸引全球科技爱好者的高度关注&#xff0c;无论是新潮的科技产品&#xff0c;还是对人工智能的探索&#xff0c;每一项展出的技术和产品都引起了市场的热议。而到了下半年&#xff0c;一年一度的China J…

springboot商城综合项目自动化系统-计算机毕业设计源码051018

摘 要 目前电商系统商城项目管理极其频繁,迫切地需要自动化测试来代替人工繁琐而又重复的劳动。自动化测试相关的研究已经很多,但多数只是针对某一方面,比如单一接口或者单一页面或者性能等,而缺乏将接口、页面、持续集成系统和缺陷管理系统整合的自动化测试平台。本研究采用混…

ROS——六轴机械臂建模

创建工作空间及目录&#xff08;my_arm&#xff09; 创建launch、urdf文件夹 urdf launch Arm_Model.xacro <?xml version"1.0"?> <robot name"marm" xmlns:xacro"http://www.ros.org/wiki/xacro"><!-- Defining the c…

【Python3】自动化测试_Playwright的安装教程

安装playwright库&#xff1a; pip install playwright 安装内置浏览器&#xff1a; # Install All playwright install# Install chromium playwright install chromium# Install firefox playwright install firefox# Install WebKit playwright install webkit 安装系统…

32.同步FIFO-IP核的调用

&#xff08;1&#xff09;FIFO&#xff08;First In First Out&#xff0c;即先进先出&#xff09;&#xff0c;是一种数据缓冲器&#xff0c;用来实现数据先入先出的读写方式。 &#xff08;2&#xff09;FIFO存储器主要是作为缓存&#xff0c;应用在同步时钟系统和异步时钟系…

深入解析发生 OOM 的三大场景

深入解析 OOM 的三大场景 什么是 OOM&#xff1f;一、堆内存溢出 ( Heap OOM )原因分析解决方案 二、栈内存溢出&#xff08;Stack OOM&#xff09;原因分析解决方案 三、方法区内存溢出&#xff08;Metaspace OOM&#xff09;原因分析解决方案 在Java应用程序开发中&#xff0…

CORDIC Translate

随便记录一下下&#xff1a; Cordic IP核使用说明以及避坑记录-CSDN博客 本次只用到了Translate&#xff0c;记录一下自己遇到的坑坑 实际配置&#xff1a; timescale 1ns / 1nsmodule cordic_tb();reg clk;wire m_axis_dout_tvalid;reg s_axis_cartesian_tvalid 0;wire [31…

三分钟了解什么是消费返利

消费返利作为一种创新的营销手段&#xff0c;不仅增强了消费者的购物体验&#xff0c;还为电商平台及商家带来了更多的用户粘性和复购率。什么是消费返利&#xff0c;其背后的运作机制又是如何的呢&#xff1f; 返利的定义: 返利即是一种消费激励措施&#xff0c;当消费者在指…

网络安全防御 -- 防火墙安全策略用户认证综合实验

实验拓扑&#xff1a; 实验目的&#xff1a; 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问。 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网。 3、办公区设备10.0.2.10不允许访问DM…

ns3-gym入门(一):代码结构和简单例子

ns3-gym真的好难学&#xff0c;网上可以参考的例子也太少了&#xff0c;如果有用这个做路由的麻烦联系我交流一下吧&#xff0c;太痛苦了 一、安装 之前的文章已经提到过了&#xff0c;这里不赘述了 二、运行简单的例子 用两个终端的方式运行感觉更加直观&#xff0c;但是仍然…

白嫖3个域名用cloudeflare托管

这也是看到别的up主分享得到的&#xff0c;我也分享一下给你们。 浏览器打开官网 https://register.us.kg/ 然后注册 根据信息填地址电话可以去另一个网页生成&#xff0c;名字姓名之类的可以填自己喜欢的&#xff0c;注意一下&#xff0c;我尝试了一下谷歌的邮箱&#xff0…

webstorm问题解决:无法识别 @

问题解决tsconfig.json 问题 本地的 vite.config.ts 已经配置 路径 但是&#xff0c;我用webstorm 上识别不了 解决 新增文件tsconfig.json&#xff0c;添加 baseUrl 和 paths 的配置&#xff0c;以告诉 TypeScript 和 WebStorm 如何解析路径别名 tsconfig.json {&quo…

以设备为核心的状态自动采集、人工运维和预测性维护为一体的智能管理系统

中服云设备全生命周期管理系统充分利用物联网、人工智能、机器学习、大数据等新一代技术&#xff0c;实现对企业生产设备从采购、安装、调试、使用、维护、维修、改造、更新直到报废全生命周期的智能化、数字化、可视化的实时管控&#xff0c;支持设备运行状态的自动采集和人工…

SketchUp Pro 2023: 强大的跨平台建模软件

SketchUp Pro 2023 是一款广受建筑设计师、工程师和创意设计师欢迎的专业建模软件&#xff0c;它结合了直观的用户界面和强大的功能&#xff0c;为用户提供了创造、设计和分享他们的想法的理想平台。无论是初学者还是经验丰富的专业人士&#xff0c;SketchUp Pro 2023 都能够满…

JVM是如何管理内存的?图文详解GC垃圾回收算法

前言&#xff1a;在C/C中对于变量的内存空间一般都是由程序员手动进行管理的&#xff0c;往往会伴随着大量的 malloc 和 free 操作&#xff0c;常常会有很多问题困扰开发者&#xff0c;这个代码会不会发生内存泄漏&#xff1f;会不会重复释放内存&#xff1f;但是在Java开发中我…

python作业二

# 二进制转化为十进制 num input("num:")def binaryToDecimal(binaryString):he 0length len(binaryString)for i in range(length):he int(binaryString[i]) * 2 ** (length - i - 1)return heprint(binaryToDecimal(num))代码运行如下&#xff1a; import math…

数据结构4.0——串的定义和基本操作

串的定义(逻辑结构) 串&#xff0c;即字符串(String)是由零个或多个字符组成的有序数列。 一般记为Sa1a2....an(n>0) 其中&#xff0c;S是串名&#xff0c;单引号括起来的字符序列是串的值;ai可以是字母、数字或其他字符&#xff1b;串中字符的个数n称为串的长度。n0时的…

印尼Facebook直播网络需要达到什么要求?

在全球化浪潮的推动下&#xff0c;海外直播正受到企业、个人和机构的广泛关注和青睐。无论是用于营销、推广还是互动&#xff0c;海外直播为各种组织提供了更多机会和可能性。本文将探讨在进行印尼Facebook直播前&#xff0c;需要满足哪些网络条件以确保直播的质量和用户体验。…