Day23-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\InOut

递归

递归公式

递归结束语句

package com.recursion;

public class RecursionTest1 {
    public static void main(String[] args) {
        test1();
    }
    public static void test1(){
        System.out.println("------test1------");
        test1();//直接方法递归
        //StackOverflowError 栈溢出
    }
    public static void test2(){
        System.out.println("------test2------");
        test3();
    }
    public static void test3(){
        test2();//间接递归
    }
}

直接递归(常用)

间接递归

package com.recursion;

public class RecursionTest2 {
    public static void main(String[] args) {
        int f5 = f(5);
        System.out.println("5的阶乘是"+f5);
        int f6 = f1(6);
        System.out.println("1到6的累加求和是"+f6);
    }

    public static int f(int n){
        //终结点
        if(n==1){
            return 1;
        }else {
            return f(n-1)*n;
    }
  }
  public  static int f1(int n){
        if(n==1){
            return 1;
        }else  {
            return f1(n-1)+n;
        }
  }
}

文件搜索

package com.recursion;

import java.io.File;
import java.io.IOException;

public class RecursionTest3 {
    public static void main(String[] args) throws IOException {
        searchFile(new File("C:/"),"aaa");
    }

    /**
     * 去目录下搜索某个文件
     * @param dir 目录
     * @param fileName 要搜索的文件名称
     */
    public static void searchFile(File dir,String fileName) throws IOException {
        //1、先把非法的情况拦截
        if(dir == null||!dir.exists()||!dir.isDirectory()){
            //❗ 原代码此处有 bug:!dir.isFile() 会导致当 dir 是文件夹时也被拦截(因为文件夹的 isFile() 返回 false),导致搜索无法执行。需修正为 !dir.isDirectory()(判断是否为文件夹)。
            return;//代表无法搜索
        }
        //2、dir不是null,存在,一定是目录对象
        File[] files = dir.listFiles();

        //3、判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象
        if(files!=null&&files.length>0){
            //4、遍历全部一级文件对象
            for (File file : files) {
                //判断文件是否为文件,还是文件夹
                if(file.isFile()){
                    if(file.getName().contains(fileName)){
                        System.out.println("找到了"+fileName+"的文件路径:"+file.getAbsolutePath());
                        Runtime runtime = Runtime.getRuntime();//这两行是文件启动程序,exec是启动
                        runtime.exec(file.getAbsolutePath());//这两行是文件启动程序,gc是JVM执行垃圾回收

                    }
                }else if(file.isDirectory()){
                    //是文件夹,重复这个过程
                    searchFile(file,fileName);
                }
            }
        }
    }
}

ASCII字符集

使用一个字节(8位)存储,首位是0,一共有2^7

GBK字符集

一个中文字符编码成两个字节,GBK兼容了ASCII字符集,包含了两万多个字符

GBK规定:汉字的第一个字节的第一位必须是1,一共2^15,32768个

Unicode字符集

是国际组织制定的,可以容纳世界上所有文字、符号的字符集

UTF-32

四个字节表示一个字符

UTF-8

可变长度的编码方案,共分为四个长度区:1个字节、2个字节、3个字节、4个字节

  1. 英文和数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节
  2. image-20251025105228813
  3. image-20251025105948952

IO流

Input和Output

image-20251025111858295

image-20251025112637851

FileInputStream(文件字节输入流)

以内存为基准,可以把磁盘中文件的数据以字节的形式读入到内存中去

每次只读取一个字节,读取性能较差,并且读取汉字输出会乱码

image-20251025150053960

package Basic.src.com.InOut;

import javafx.application.Application;
import javafx.stage.Stage;

import java.io.*;

public class FileInputStreamTest1  {
    public static void main(String[] args) throws IOException {
        //1、创建文件字节输入流管道,与源文件接通
        //InputStream is = new FileInputStream(new File("Basic\\src\\itheima01.txt"));
        //下面是简化写法,推荐使用
        InputStream is = new FileInputStream("Basic\\src\\itheima01.txt");

//        //2、开始读取文件的字节数据
//        int b1 = is.read();
//        System.out.println(b1);
//        System.out.println((char)b1);
//
//        int b2 = is.read();
//        System.out.println((char)b2);
//
//        int b3 = is.read();
//        System.out.println(b3);//返回-1通知文件已经读完了
//        System.out.println((char)b3);

        //3、使用循环改造上述
        int b;//用于记住上述代码
        while ((b = is.read()) != -1) {
            System.out.print((char)b);
        }

        //读取数据的性能很差!
        //应该尽量减少系统调用硬盘中的数据的频次
        //读取汉字输出会乱码!无法避免
        //流使用完毕后,必须关闭!释放系统资源!
        is.close();

    }
}

释放内存

try-catch-finally

在finally区释放内存,无论try中的程序是正常执行了还是出现异常,最后都一定会执行finally区,除非JVM终止

一般用于在程序执行完成后进行资源的释放操作(专业做法)

package Basic.src.com.InOut;

import java.io.*;

public class Test2 {
    public static void main(String[] args)  {
        InputStream is = null;
        OutputStream os =null;
        try {
            //在is和os被赋值之前出现异常的话会使得is和os在null的情况下被close,出现空指针异常
            //需求:复制照片
            //1、创建一个字节输入管道与源文件接通
            is = new FileInputStream("Basic\\src\\itheima03.txt");
            //2、创建一个字节输出管道与目标字节接通
            os = new FileOutputStream("Basic\\src\\itheima03copy.txt");
            //3、创建一个字节数组专用字节数据
            byte[] buffer = new byte[1024];//1KB
            //4、从字节输入流中读取字节数据,写出去到字节输出流中,读多少写出去多少
            int len;//记住每次读取多少个字节
            while((len = is.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            
            //后创建的流要先关掉,先创建的流要后关掉
            System.out.println("复制完成");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (os!=null)os.close();//避免因为is和os被赋值前出现异常导致的提前调用
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                if (is!=null)is.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

try-with-resource

开始于JDK7

把要用的流对象放在try后面的( )里面,可以不需要使用finally

( )内只能放置资源,否则报错,资源指的是最终实现了AutoCloseable接口,重写了close()方法

package Basic.src.com.InOut;

import java.io.*;

public class Test3 {
    public static void main(String[] args) throws Exception {
        try(
                //在is和os被赋值之前出现异常的话会使得is和os在null的情况下被close,出现空指针异常
                //需求:复制照片
                //1、创建一个字节输入管道与源文件接通
                InputStream is = new FileInputStream("Basic\\src\\itheima03.txt");
                //2、创建一个字节输出管道与目标字节接通
                OutputStream  os = new FileOutputStream("Basic\\src\\itheima03copy.txt");

                //这里只能放置资源型对象(比如流对象)
                //什么是资源呢?资源都是会实现AutoCloseable接口
                //用完之后会自动被调用close方法完成释放资源的操作
                //public abstract class OutputStream implements Closeable, Flushable
                //public interface Closeable extends AutoCloseable
                MyConnection connection = new MyConnection()//因为Myconnection类实现了AutoCloseable接口并重写了close()方法,被视为资源型
                ) {
            //在is和os被赋值之前出现异常的话会使得is和os在null的情况下被close,出现空指针异常
            //3、创建一个字节数组专用字节数据
            byte[] buffer = new byte[1024];//1KB
            //4、从字节输入流中读取字节数据,写出去到字节输出流中,读多少写出去多少
            int len;//记住每次读取多少个字节
            while((len = is.read(buffer))!=-1){
                os.write(buffer,0,len);
            }

            //后创建的流要先关掉,先创建的流要后关掉
            System.out.println("复制完成");
            System.out.println(connection);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
package Basic.src.com.InOut;

public class MyConnection implements AutoCloseable{

    @Override
    public void close() throws Exception {
        System.out.println("释放了与某个硬件的连接资源");
    }
}

字符流

适合读写文本文件的内容

FileReader

把文件(磁盘或网络)中的数据以字符的形式读取到内存中

image-20251025192439555

package Basic.src.com.InOut.FileReaderWriter;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;

public class FileReaderTest1 {
    public static void main(String[] args) throws Exception {
        try (
                //创建一个文件字符输入流管道与源文件接通
             Reader fr = new FileReader("Basic\\src\\com\\InOut\\FileReaderWriter\\itheima01.txt");
             ){
//            //2、读取文本文件的内容
//            int c;
//            while ((c = fr.read()) != -1) {//read返回的是int
//                System.out.print((char)c);
//            }
            //3、每次读取多个字符
            char[] buffer = new char[3];
            int len;
            while((len = fr.read(buffer))!= -1) {
                String str = new String(buffer, 0, len);
                System.out.print(str);
            }
            //性能是比较不错的!
        } catch (Exception e) {
            e.printStackTrace();;
        }
    }
}
posted @ 2025-10-25 19:47  David大胃  阅读(5)  评论(0)    收藏  举报