JAVAEE初阶相关内容第十三弹--文件操作 IO

news2024/11/20 7:29:32

写在前

终于完成了!!!!内容不多·就是本人太拖拉!

这里主要介绍文件input,output操作。File类,流对象(分为字节流、字符流)

需要掌握每个流对象的使用方式:打开、读写、关闭

熟练使用API并知道这些API起到的效果

这里涉及到的经典面试题需要注意:

抽象类和接口的区别[4.2]

还需要重点去看的一个是4.2.8中的案例一,重点体会其中的递归·操作!!!

目录

文件操作--IO

1.认识文件

1.1狭义上的文件

1.2广义上的文件

2.文件路径

2.1绝对路径

2.2相对路径

3.文件类型

3.1文本文件

3.2二进制文件

4.Java中操作文件

4.1File类

4.1.1属性

4.1.2构造方法

4.1.3代码示例

(1)获取相应的路径

(2)普通文件的创建

​(3)普通文件的删除

(4)创建目录

(5)文件重命名

4.2文件内容操作

经典面试题--- 抽象类和接口什么区别?

4.2.1使用字节流来读取文件

(1)完整代码展示:

(2)buffer版本代码:

4.2.2使用字节流来写文件

完整代码实现:

4.2.3怎样理解这里说的读与写?【约定】

​4.2.4关于close操作

(1)理解

​(2)如果close操作没写会如何?

(3)确保close被执行?

try-ctach

try with resources

4.2.5使用字符流读文件

完整代码展示:

4.2.6使用字符流写文件

(1)完整代码展示:

(2)flush-冲刷

​4.2.7Scanner

4.2.8两个小案例的实现

(1)扫描指定目录

(2)文件拷贝


文件操作--IO

1.认识文件

1.1狭义上的文件

硬盘上的文件和目录(文件夹)  本篇博客记录的就是狭义上的文件。

1.2广义上的文件

泛指计算机中的很多软硬件资源。操作系统中,把很多的硬件设备和软件资源抽象成文件,按照文件的方式统一管理。

2.文件路径

2.1绝对路径

以c:  d:  盘符开头的路径

2.2相对路径

以当前所在的目录为基准,以 . 或者 .. 开头,(.有时可以省略),找到指定的路径。【当前所在的目录称为是工作目录,每个程序运行的时候,都有一个工作目录,,在控制台里通过命令操作的时候是特别明显的,后期进化到图形化界面,工作目录就不那么直观了。

举个例子:如下图,假定当前的工作目录是 f:/Code,定位到111这个目录上就可以表示为

./111    其中./表示为当前的目录 

如果工作目录不同,定位到同一个文件,相对路径的写法是不同的。

我们同样希望定位到  111 这里

几种相对路径的写法
工作目录相对路径
f:/./Code/111
f:/Code./111
f:/Code/222../111
f:/Code/222/bbb../../111

../表示当前目录的上级目录。

3.文件类型

word;exe;图片;视频;音频;源代码;动态库等等,这些不同的文件整体可以归纳为两类

3.1文本文件

存的是文本,字符串【字符串,由字符构成,每个字符都是通过一个数字来表示的。这个文本文件里存储的数据一定是合法的,都是在指定字符编码的码表之内的数据。】

3.2二进制文件

存的是二进制数据,不一定是字符串【没有任何限制,可以存储任何想要的数据。】

小思考?  当我们有一个文件,如何区分是文本文件还是二进制文件?

直接使用记事本打开,如果乱码了就说明是二进制文件,如果没有乱码就是文本。

4.Java中操作文件

主要有两类操作,第一类是针对文件系统的操作(文件的创建、删除、重命名);第二类是针对文件内容操作(文件的读和写)。

Java中通过java.io.File类来对一个文件(包括目录)进行抽象的描述,有File对象并不代表真实存在该文件。

4.1File类

4.1.1属性
修饰符及类型属性说明
static StringpathSeparator依赖于系统路径分隔符,String类型的表示
static charpathSeparator依赖于系统的路径分隔符,char类型的表示
4.1.2构造方法
签名说明
File(File parent,String child)根据父目录+孩子文件路径,创建一个新的File实例
File(String pathname)根据文件路径创建一个新的File实例,路径可以是绝对路径或者是相对路径
File(String parent,String child)

根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示

parent表示当前文件所在的目录,child是自身文件名。

在new File对象的时候,构造方法参数中,可以指定一个路径,此时File对象就代表这个路径对应的文件。

4.1.3方法【不需要背】

返回修饰符及返回值类型方法签名说明
Stringgetparent()返回File对象父目录文件路径
StringgetName()返回File对象的纯文件名称
StringgetPath()返回File对象的文件路径
StringgetAbsolutePath()返回File对象的绝对路径
String

getCanonicalPath()

返回File对象的修饰过的绝对路径【绝对路径更加化简的表示方式】
booleanexists()判断File对象描述的文件是否真实存在
booleanisDirectory()判断File对象代表的文件是否是一个目录
booleanisFile()判断File对象代表的文件是否是一个普通文件
booleancreateNewFile()根据File对象,自动创建一个空文件。成功创建后返回true
booleandelete()根据File对象,删除该文件。成功删除后返回true
voiddeleteOnExit()根据File对象,标注文件将被删除,删除动作会到JVM运行结束后才会进行
String[]list()返回File对象代表的目录下的所有文件名
File[]listFiles()返回File对象代表目录下的所有文件,以File对象表示
booleanmkdir()创建File对象代表的目录
booleanmkdirs()创建File对象代表的目录,如果必要,会创建中间目录
boolean

renameTo(File dest)

进行文件改名,也可以视为我们平时的剪切、粘贴操作
boolean

canRead()

判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限
4.1.3代码示例
(1)获取相应的路径
public class IOD1 {
    public static void main(String[] args) throws IOException {
        File file = new File("d:/test.txt");//这里的路径不需要真实的存在、
        System.out.println(file.getPath());
        System.out.println(file.getName());
        System.out.println(file.getParent());
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getCanonicalPath());
    }
}

运行输出结果:

(2)普通文件的创建
public class IOD2 {
    public static void main(String[] args) throws IOException {
        File file = new File("d:/hello.txt");
        System.out.println(file.exists());
        System.out.println(file.isFile());
        System.out.println(file.createNewFile());
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());

    }
}

运行输出结果:

(3)普通文件的删除
public class IOD3 {
    public static void main(String[] args) {
        File file = new File("d:/hello.txt");
        System.out.println(file.delete());
    }
}

运行输出结果:

延申:关于deleteOnExit 不会立即删除,是在程序运行完关闭之后才进行的删除。

(4)创建目录

需要注意的是:mkdir()  mk是make的缩写!

public class IOD4 {
    public static void main(String[] args) {
        File dir = new File("d:/study");
        dir.mkdir();
    }
}

运行程序后就会在d盘生成一个名字为study的文件夹。

如果我们想创建多级目录。例如创建"d:/test/aaa/bbb",需要使用makedirs。

public class IOD4 {
    public static void main(String[] args) {
        File d = new File("d:/aaa/ddd/m");
        d.mkdirs();
    }
}

运行后的文件夹显示:

(5)文件重命名
public class IOD5 {
    public static void main(String[] args) {
        File dest = new File("./testAAA");
        File file = new File("./test");

        dest.renameTo(file);
    }
}

创建一个名为testAAA的文件和一个名为test的文件,将testAAA改名为test;

4.2文件内容操作

针对文件内容,使用流对象进行操作。[流对象 可以类比于 水流]

Java标准库的流对象,从类型上,可以分为两个大类,一类是字节流,一类是字符流。

字节流[操作二进制文件]:InputStream   OutputStream  (FileInputStream FileOutputStream)    

字符流[操作文本数据]:Reader Writer(FileReader FileWriter )

这些类的使用方式是非常固定的,核心操作就是四个:

(1)打开文件[构造对象]

(2)关闭文件[close]

(3)读文件[read针对InputStream 和 Reader]

(4)写文件[write针对OutputStream和Writer]

需要注意的是:InputStream   OutputStream  Reader Writer 都是抽象类,不能直接new

经典面试题--- 抽象类和接口什么区别?

抽象类比接口更抽象,抽象类的功能比接口更多。抽象类和普通的类相比差别不大,只不过抽象类不能new实例,带有抽象方法。抽象类可以有普通方法,也可以有抽象的方法。大部分的东西都是确定的有几个属性有几个方法,大部分都是明确的,只有一小部分是抽象方法。

接口里面都是抽象方法,接口中大部分都是不确定的,有什么属性都不知道,方法也都是抽象方法(不考虑default的情况)

因此,接口提供的信息更少,视为接口比抽象类更抽象。

4.2.1使用字节流来读取文件

(1)完整代码展示:
public class IOD6 {
    //使用字节流来读取文件
    public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("f:/test.txt");

        while(true){
            int b = inputStream.read();
            if(b == -1){
                break;
            }
            System.out.println(""+(byte)b);

        }
        inputStream.close();
    }
}

输出结果:

read() 一次读一个字节,但是这里使用的是int类型,原因:因为要表述”读取完毕“这样的情况,看起来是int,其实是byte,把int转为byte进行使用,另外需要判断当前的值是否是-1,是-1说明读取完毕,也就可以结束循环了。

(2)buffer版本代码:
public class IOD6 {
    //使用字节流来读取文件
    public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("f:/test.txt");

        while (true) {
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            if (len == -1) {
                break;
            }
            for (int i = 0; i < len; i++) {
                System.out.printf("%x\n", buffer[i]);
            }
        }
        inputStream.close();
    }
}

一次读1024个字节,并使用十六进制形式打印出来。

buffer理解:

缓冲区,缓和冲突,减少冲击的次数

存在的意义:为了提高IO的操作效率,单词的IO操作,就是要访问硬盘/IO设备,单次操作是比较消耗时间的,如果频繁的进行这样的IO操作,耗时肯定就更多了。

单次IO时间是一定的,如果缩短IO的次数,此时就可以提高程序整体的效率了。

以上第一个版本的代码是一次读一个字节,循环次数就比较高,read次数也很高

第二个版本的代码是一次读1024个字节,循环次数就降低了很多,read次数变少了。

4.2.2使用字节流来写文件

写文件有三个版本:

完整代码实现:
public class IOD7 {
    //进行写文件
    public static void main(String[] args) throws IOException {
        OutputStream outputStream = new FileOutputStream("f:/test.txt");
        outputStream.write(97);
        outputStream.write(98);
        outputStream.write(97);
        outputStream.write(98);

        outputStream.close();
    }
}

现在在我们的f盘txt文件夹中的内容是:

当我们运行程序后再次打开txt文件,看到运行结果:

可以看到的是记事本中的内容发生了改变,输入的内容分别对应a和b的ASCII码值。

需要注意的是在outputStream进行写操作的时候总是将文件中的内容进行清空,再进行写入,如果不想清空,需要进行“追加写”操作。

4.2.3怎样理解这里说的读与写?【约定】
4.2.4关于close操作
(1)理解

close,关闭文件,释放资源。

进程在内核里,使用PCB这样的数据结构来表示进程。

一个线程可以对应一个PCB,一个进程可以对应一个PCB也可以对应多个。

PCB有一个重要的属性是文件描述符表。(相当于一个数组,记录了该进程打开了哪些文件)即使一个进程里面有多个PCB也没关系,这些PCB共用同一个文件描述符表。

(2)如果close操作没写会如何?

如果没有close,对应的表项没有及时释放,虽然Java有GC,GC操作会在回收这个outputStream对象的时候去完成释放操作,但是GC不一定及时,如果不手动释放会导致文件描述符表可能很快被占满(文件描述符表不能自动扩容,是存在上线的),再次打开文件就会打开失败。

close一般来说是要执行的,但是如果程序要自始至终的使用,不关闭的问题也是不大的,随着进程结束,PCB销毁,文件描述符表也被销毁了,对应的资源操作系统就自动回收。如果close后程序立刻结束不执行close也没关系,但是在写代码的过程中还是需要注意这个close,如何确保close被执行到?

(3)确保close被执行?
try-ctach

我们首先可以想到的是使用try-catch执行:

可以但是不够美观,更推荐的一种写法是将变量的定义写到try( )里面,后面将不需要写close语句。

try with resources

没有显式的写close,但是实际上是会执行close的,只要try语句块执行完毕,就可以自动的执行到close,这个语法在Java中被称为是try with resources。

注意:不是随便拿一个对象放到try里面就可以自动释放的,需要满足的要求是实现Closeable接口,才可以。这个接口提供的方法就是close方法。

4.2.5使用字符流读文件
完整代码展示:
public class IOD8 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("f:/test.txt")) {
            while(true){
                int ch =reader.read();
                if(ch == -1){
                    break;
                }
                System.out.println("" +(char)ch);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

如果输入汉字不能正确读取的话可能是编码的问题,需要改为utf-8编码。

4.2.6使用字符流写文件
(1)完整代码展示:
public class IOD9 {
    public static void main(String[] args) {
        //使用字符流写一个字符串
       try(Writer writer = new FileWriter("f:/text.txt")){
           writer.write("hello123");
       } catch (IOException e) {
           e.printStackTrace();
       }
    }
}

有的时候可以发现写的文件内容没有真的在文件中出现,很大可能是缓冲区的问题。

类似于这样的操作,其实是先写到缓冲区中(缓冲区有很多种形态,自己写的代码中有缓冲区,标准库中也可以有缓冲区,操作系统内核中也存在缓冲区),在写操作执行完后,内容可能在缓冲区中,还没真正的进入硬盘。

close操作,会触发缓冲区的“冲刷”(冲刷操作,就是把缓冲区里的内容写到硬盘中)

(2)flush-冲刷

除了close之外,也可以通过flush方法,也可以起到刷新缓冲区的效果。close操作后就关闭用不了了,flush操作还可以继续使用。

4.2.7Scanner

点进去可以发现:inputStream,输入流对象【字节流】

Scanner不仅仅可以针对键盘的输入进行读取。

public class IOD10 {
    public static void main(String[] args) {
        //Scanner scanner = new Scanner(System.in);
        try(InputStream inputStream = new FileInputStream("f:/test.txt")){
            Scanner scanner = new Scanner(inputStream);
            scanner.next();
        }catch (IOException e){
            e.printStackTrace();
        }
    
    }
}

Scanner的close本质上是要关闭内部包含的这个流对象,此时内部的inputStream对象已经被try()关闭了,里面的这个Scanner不关闭也是没问题的。

4.2.8两个小案例的实现
(1)扫描指定目录

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

 完整代码实现:

public class IOD11 {
    private static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        //首先让用户输入一个指定搜索的目录
       // Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要搜索的路径");
        String basePath = scanner.next();
        //针对用户的输入进行一个简单的判定
        File root = new File(basePath);
        //判断是不是目录
        if(!root.isDirectory()){
            //路径不存在或者只是一个普通文件。无法进行搜索
            System.out.println("当前输入的目录错误!");
            return;
        }
        //让用户再输入一个要删除的文件名
        System.out.println("请输入要删除的文件名");
        //此处使用的是next来读字符串而不是nextln!!
        //next是读到空白符就算是读完了。空白符包括换行,也可以是制表符,回车符
        //nextln仅仅是去找换行符
        //在控制台中,nextln是很难控制的
        String nameToDelete = scanner.next();

        //针对指定的路径进行扫描【递归操作】
        //从根目录出发(root)
        //先判断一下,当前的这个目录中是否包含要删除的文件,存在即删除,否则继续下一个
        //如果当前目录中包含了一些目录,则针对子目录进行递归

        scanDir(root,nameToDelete);
    }

    private static void scanDir(File root, String nameToDelete) {
        System.out.println("[scanDir]" +root.getAbsolutePath());
        //1.首先列出当前目录下包含的内容
        File[] files = root.listFiles();  //看一下当前的目录中有啥,好比文件资源管理器双击目录打开
        if(files == null){
            //当前root目录下没东西,是一个空目录
            //结束继续递归
            return;
        }
        //2.遍历当前的列出结果
        for(File f:files){
            if(f.isDirectory()){
                //如果是目录就进一步递归
                scanDir(f,nameToDelete);

            }else{
                //如果是普通文件判定是否要删除
                if(f.getName().contains(nameToDelete)){
                    System.out.println("确认删除?" +f.getAbsolutePath());
                    String choice = scanner.next();
                    if(choice.equals("y") || choice.equals("Y")){
                        f.delete();
                        System.out.println("删除成功");
                    }else{
                        System.out.println("取消删除操作");
                    }

                }
            }
        }

    }
}

控制台输出结果:

需要注意的是:

 

这里使用File对象表示列出的结果,结果有多个,使用数组表示。相当于看一下当前的目录中有什么,打开文件资源管理器,文件资源管理器中显示的这些结果,就相当于是listFiles得到的内容。

list方法也有类似的功效,但是list得到的只是String类型的文件名。

(2)文件拷贝

把第一个文件按照字节依次读取,把结果写入到另一个文件中。

需要构建“源路径”和”目标路径“两个路径,对于源路径来说要看源是不是存在,对于目标路径来说要看目标路径是不是不存在。

需要注意一下代码中读一个字节写一个字节的部分

完整代码实现:

public class IOD12 {
    public static void main(String[] args) {
        //输入两个路径
        //第一个路径表示拷贝谁(源-src),第二个路径表示需要拷贝到哪里去(目的-dest)
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要拷贝哪个文件?");
        String srcPath = scanner.next();
        System.out.println("请输入要拷贝到哪个地方?");
        String destPath = scanner.next();

        //针对路径进行判定
        File srcFile = new File(srcPath);
        if(!srcFile.isFile()){
            //如果源不是一个文件(是个目录或者不存在)
            //此时就不做任何操作
            System.out.println("当前输入的源路径错误!");
            return;
        }
        File destFile = new File(destPath);
        if(destFile.isFile()){
            //如果已经存在了,认为也不能拷贝
            System.out.println("当前输入的目标路径错误!");
            return;
        }
        //进行拷贝操作
        //try()语法支持多个流对象,写几个都可以进行关闭
        //多个流对象之间使用分号进行分割就可以
        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(destFile)) {
            //进行读文件操作

            while(true){
                //读一个字节,写一个字节!!
                int b = inputStream.read();
                if(b == -1){
                    break;
                }
                outputStream.write(b);
            }

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

    }
}

OutputStream在进行写文件的时候,文件不存在就会自动创建。

InputStream不行,文件不存在就会抛异常了。

到这里文件IO部分就大体结束啦!下一部分将开启网络部分的内容~

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

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

相关文章

MySQL jdbc,事务,连接池

​​​ 3-MySQL jdbc,事务,连接 1 jdbc 1.1 jdbc概述# JDBC&#xff08;Java DataBase Connectivity,java数据库连接技术&#xff09;是一种用于执行SQL语句的Java API。 JDBC是Java访问数据库的标准规范&#xff0c;可以为不同的关系型数据库提供统一访问&#xff0c;它由一…

php对接微信支付简要流程?面试时你会描述吗?

一、微信支付申请&#xff1a;微信公众号平台-->功能中找到微信支付-->申请接入 1.如果没有微信支付商会号&#xff0c;需要进行申请 提交营业执照、身份证、银行账户 2.如果有微信支付商会号 可进行直接关联 登录微信商户平台—产品中心—APPID授权管理—新增授权申…

视频编辑软件 Premiere Pro 2024 macv24.0中文版 (pr2024)

Premiere Pro 2024 mac编辑任何现代格式的素材&#xff0c;从8K到虚拟现实。广泛的原生文件支持和简单的代理工作流程可以轻松使用您的媒体&#xff0c;即使在移动工作站上也是如此。提供针对任何屏幕或平台优化的内容比以往任何时候都快。 Premiere Pro 2024 Mac版软件介绍 视…

深度强化学习 第 2 章 蒙特卡洛

2.1随机变量 强化学习中会经常用到两个概念&#xff1a; 随机变量、 观测值。 本书用大写字母表示随机变量&#xff0c;小写字母表示观测值&#xff0c;避免造成混淆。 下面我们定义概率质量函数&#xff08;probability mass function&#xff0c;缩写 PMF&#xff09;和概率…

SpringBoot面试题5:SpringBoot Starter的工作原理是什么?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot Starter的工作原理是什么? Spring Boot Starter 是一种便捷的方式来为 Spring Boot 应用程序引入一组特定功能的依赖项。它简化了项目…

【Java并发】聊聊LongAdder应用场景及其原理

应用场景 我们知道在实际的应用场景中&#xff0c;可能会对某个商品进行浏览次数进行迭代&#xff0c;或者抖音视频的点击&#xff0c;那么如何高效记录呢&#xff0c;首先如果是使用普通的num 进行多线程操作的话&#xff0c;那么一定会带来数据一致性问题&#xff0c;所以一…

【Unity基础】6.动画状态机

【Unity基础】6.动画状态机 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;Animator Controller组件 &#xff08;1&#xff09;创建组件 Animator Controller组件是unity用于控制管…

【细读经典】delay model and timing analysis

Technology-Dependent LogicOptimization, part 1 序言 如图所示是现代工业流程中对于一个高层次的抽象描述如何到最后的芯片的流程图&#xff0c;其中逻辑综合作为一个非常重要的部分&#xff0c;主要被分为两个阶段&#xff1a; 工艺无关的优化(technology-independent opt…

shell脚本学习笔记03(小滴课堂)

在shell脚本中&#xff0c;表示变量除了可以使用$a(a是一个变量)&#xff0c;还可以使用${a} 那这两种表示方式有什么区别么&#xff1f; 花括号可以和其它字符或者字母区分开来。 >追加内容 我们发现使用>会把原来的内容覆盖。 我们使用>>就不会覆盖了&#xff…

MAYA教程之模型的UV拆分与材质介绍

什么是UV 模型制作完成后&#xff0c;需要给模型进行贴图&#xff0c;就需要用到UV功能 UV编译器介绍 打开UI编译器 主菜单有一个 UV->UV编译器&#xff0c;可以点击打开 创建一个模型&#xff0c;可以看到模型默认的UV UV编译器功能使用 UV模式的选择 在UV编译器中…

从裸机启动开始运行一个C++程序(八)

前序文章请看&#xff1a; 从裸机启动开始运行一个C程序&#xff08;七&#xff09; 从裸机启动开始运行一个C程序&#xff08;六&#xff09; 从裸机启动开始运行一个C程序&#xff08;五&#xff09; 从裸机启动开始运行一个C程序&#xff08;四&#xff09; 从裸机启动开始运…

【C++】C++11 ——lambda表达式

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】C11…

阿里云香港云服务器公网带宽价格表及测试IP地址

阿里云服务器香港地域公网带宽价格表&#xff0c;1M带宽价格是30.0元/月&#xff0c;按使用流量1GB价格是1.0元&#xff0c;阿里云香港服务器测试IP地址&#xff1a;47.75.18.101&#xff0c;阿里云百科aliyunbaike.com来详细说下阿里云香港服务器1M带宽、5M带宽、6M带宽、10M带…

民宿酒店订房房态商城小程序的作用是什么

外出旅游出差&#xff0c;酒店民宿总是很好的选择&#xff0c;随着经济复苏&#xff0c;各地旅游及外出办公人次增多&#xff0c;酒店成绩随之增加&#xff0c;市场呈现多品牌酒店经营形式。 区别于以前&#xff0c;如今互联网深入各个行业&#xff0c;酒店经营也面临着困境。…

删除字符串特定的字符(fF)C语言

代码&#xff1a; #include <stdio.h> void funDel(char *str) {int i, j;for (i j 0; str[i] ! \0; i)if (str[i] ! f && str[i] ! F)str[j] str[i];str[j] \0; }int main() {char str[100];printf("请输入一个字符串&#xff1a;");gets(str);pr…

转化限制+分析变量变化引起的答案变化:Gym - 104065D

https://vjudge.net/contest/587311#problem/H 先转化一波条件&#xff1a; p i ≥ 1 X p_i\ge \frac 1 X pi​≥X1​ p i ≤ 1 1 − Y p_i\le \frac 1 {1-Y} pi​≤1−Y1​ 所以我们按 p p p 排序&#xff0c; s u m x sum_x sumx​ 必然是后缀&#xff0c; s u m y sum_y …

Python算术运算符:加减乘除 整除 取余 幂指数 小括号

运算案例 需求&#xff1a;用户手工输入梯形的上底、下底以及高&#xff0c;能直接通过Python打印出梯形的面积为多少。 做这个需求前&#xff0c;首先要知道Python的算数运算符有哪些。 2、算术运算符 所谓的算数运算符就是我们日常生活中的加减乘除等待。 运算符描述实例…

汉服商城小程序的作用是什么

汉服在日常生活中越来越常见&#xff0c;大街小巷也有不少年轻人装扮甚是漂亮帅气&#xff0c;有些地区甚至还有相关的比赛等&#xff0c;作为近几年曝光的服饰&#xff0c;汉服市场规模持续增加中&#xff0c;各地线上线下商家也多了起来。 然而在实际经营中&#xff0c;汉服…

Anylogic 读取和写入Excel文件

1、选择面板-连接-Excel文件&#xff0c;拖入到视图中 然后在excel文件的属性中进行绑定外部excel文件。 绑定完之后&#xff0c;在你需要读取的地方进行写代码&#xff0c; //定义开始读取的行数 //这里设为2&#xff0c;是因为第一行是数据名称 int row12; //读取excel文件信…

SpringBoot-黑马程序员-学习笔记(六)

目录 76.常用计量单位使用 77.bean属性校验 81.测试表现层 82.发送虚拟请求 94.springboot读写redis的客户端 100.ElasticSearch&#xff08;简称ES&#xff09; 一个分布式全文搜索引擎 76.常用计量单位使用 Data Component ConfigurationProperties(prefix "serve…