集合-递归,IO-文件&字节流

(1)递归
  • 递归
        方法直接或间接的调用自己
  • 注意
        递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。
    
案例
    计算n的阶乘

阶乘
    5! = 5 * 4 * 3 * 2 * 1
    4! = 4 * 3 * 2 * 1
    3! = 3 * 2 * 1
    2! = 2 * 1
    1! = 1

    n! = n * (n-1) * (n-2) *.....* 1

公式
    f(n) = f(n-1) * n
public class Demo2 {
    public static void main(String[] args) {
        int num = f(5);
        System.out.println(num);

    }

    public static int f (int n) {
        if (n==1){
            return 1;
        }else{
            return n*f(n-1);
        }

    }
}

 

案例
    计算1-n的和

阶乘
    5 = 5 + 4 + 3 + 2 + 1
    4 = 4 + 3 + 2 + 1
    3 = 3 + 2 + 1
    2 = 2 + 1
    1 = 1

    n = n + (n-1) + (n-2) +.....+ 1

公式
    f(n) = f(n-1) + n
public class Demo3 {
    public static void main(String[] args) {
        int num = f(5);
        System.out.println(num);
    }
    public  static int f(int n){
        if (n==1){
            return 1;
        }
        return n+f(n-1);
    }
}
 (2)file
  • File
        可以表示文件,也可以表示文件夹,联的路径可以存在,也可以不存在
    
  • 创建对象
        File(String pathname) 根据指定路径创建File对象
        File(String parent,String child) 跟进指定参数拼接的路径创建File对象
        File(File parent,String child)   跟进指定参数拼接的路径创建File对象
  • 文件路径分隔符写法
        1、/可以单独写
        2、|需要转义
        3、File.separator根据系统自动匹配分隔符
  • 路径的分类
        绝对路径:从盘符开始的路径
        相对路径:不带盘符,默认直接到当前工程下的目录寻找文件。
public class Demo1 {
    public static void main(String[] args) throws IOException {
        //1. 单参数创建文件
//        File file = new File("D:/uploadPath/1.txt");
//        File file = new File("D:\\uploadPath\\1.txt");
        File file = new File("D:"+File.separator+"uploadPath"+File.separator+"1.txt");
        System.out.println(file);
        //2. 多参数创建文件
        File file1 = new File("D:/uploadPath", "2.jpg");//文件夹,文件名
        System.out.println(file1);

        //2.1 构建一个文件// 夹的file对象
        File parent = new File("D:/uploadPath");//文件夹
        //2.2 创建文件对象
        File file2 = new File(parent, "2.jpg");
        System.out.println(file2);
        //3. 文件分隔符

        //4. 绝对路径 和  相对路径
        File file3 = new File("D:/uploadPath/1.txt"); //绝对路径
        File file4 = new File("day08-code/1.jpg");
        System.out.println(file4); //相对路径:相对于当前工程 + /1.jpg
        //将文件写入到磁盘
        file4.createNewFile();
    }
}
  • 常用方法1:判断文件类型、获取文件信息
        boolean exists() 判断文件路径是否存在
        boolean isFile() 判断是否是文件(不存在的都是false)
        boolean isDirectory() 判断是否是文件夹(不存在的都是false)
        String getName() 获取文件/文件名,包含后缀
        long length() 获取文件大小,返回字节个数
        long lastModified() 获取最后修改时间
        string getPath() 获取创建对象时的路径
        String getAbsolutePath() 获取对象绝对路名
public class Demo2 {
    public static void main(String[] args) {
        File f1 = new File("day08-code/test1");//文件夹-已存在
        File f2 = new File("day08-code/test1/1.txt");//文件-已存在

        File f3 = new File("day08-code/test2");//文件夹-不存在
        File f4 = new File("day08-code/test2/2.txt");//文件-不存在

        //boolean exists() 判断文件路径是否存在
//        boolean exists1 = f1.exists();
//        System.out.println(exists1); //true
//        boolean exists3 = f3.exists();
//        System.out.println(exists3); //false

        //boolean isFile() 判断是否是文件
//        System.out.println(f1.isFile());  //false
//        System.out.println(f2.isFile()); //true

        //boolean isDirectory() 判断是否是文件夹
//        System.out.println(f1.isDirectory()); //true
//        System.out.println(f2.isDirectory());  //false

        //String getName() 获取文件/文件名,包含后缀
        String name = f2.getName();
        System.out.println(name);

        //long length() 获取文件大小,返回字节个数
        long length = f2.length();
        System.out.println(length);

        //long lastModified() 获取最后修改时间
        long time = f2.lastModified();
        System.out.println(new Date(time));

        //string getPath() 获取创建对象时的路径
        String path = f2.getPath();
        System.out.println(path);

        //String getAbsolutePath() 获取对象绝对路径
        String absolutePath = f2.getAbsolutePath();
        System.out.println(absolutePath);
    }
}
  • File创建和删除方法
    boolean mkdir()   创建单级文件夹,创建失败返回false
    boolean mkdirs()   创建多级文件夹 (常用)
    
    boolean createNewFile()  创建文件,文件存在返回false
    
    boolean delete()  删除文件或空文件夹,删除失败返回false (注意: 删除方法不走回收站,填用)
    
public class Demo3 {
    public static void main(String[] args) throws IOException {
        File f1 = new File("day08-code/test2");
        File f2 = new File("day08-code/test2/test3");
        File f3 = new File("day08-code/test2/2.txt");

        //boolean mkdir()   创建单级文件夹,创建失败返回false
        //boolean mkdir = f1.mkdir();
        //System.out.println(mkdir);

        //boolean mkdirs()   创建多级文件夹 (常用)
       // boolean mkdirs = f2.mkdirs();
        //System.out.println(mkdirs);

        //boolean createNewFile()  创建文件,文件存在返回false
        //f3.createNewFile();
        //boolean delete()  删除文件或空文件夹,删除失败返回false (注意: 删除方法不走回收站,填用)
        //此目录下如果没有任何的文件,文件夹才能删除
        //f3.delete();
        boolean delete = f2.delete();
        System.out.println(delete);
    }
}
  • 查看目录中的内容
        String[] list()    获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。
        File[] listFiles() 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回,包含隐藏文件(重点)
    
  • 注意事项
        当主调是文件,或者路径不存在时,返回null
        当主调是空文件夹时,返回一个长度为0的数组
        当主调是一个非空文件夹,但是没有权限访问该文件夹时,返回null
public class Demo4 {
    public static void main(String[] args) {

        //创建目录对象
        File parent = new File("D:\\uploadPath");

        //String[] list()  返回文件名数组
        String[] names = parent.list();
        for (String name : names) {
            System.out.println(name);
        }

        //File[] listFiles() 返回文件数组
        File[] files = parent.listFiles();
        for (File file : files) {
            System.out.print(file);
            if (file.isFile()) {
                System.out.println("文件");
            }else {
                System.out.println("文件夹");
            }
        }
    }
}
需求:
    从D:盘中,搜索“QQ.exe” 这个文件,找到后直接输出其位置。
分析:
    先找出D:盘下的所有一级文件对象
    遍历全部一级文件对象,判断是否是文件
    如果是文件,判断是否是自己想要的
    如果是文件夹,需要继续进入到该文件夹,重复上述过程
public class Demo5 {
    public static void main(String[] args) {
        File parent = new File("D:\\");
        //FeiQ.exe
        findFile(parent,"FeiQ.exe");
    }

    /**
     * 递归查找文件
     *    参数1:目录对象
     *    参数2:需要查找的文件
     * 返回值:void
     */
    public static void findFile(File parent, String fileName) {
        //1、获取当前目录下的所有文件
        File[] files = parent.listFiles();

        //2、如果当前目录下,不存在文件/文件夹,结束
        if (files == null || files.length == 0) {
            return;
        }

        //3、循环遍历所有文件/文件夹
        for (File file : files) {
            //4、判断当前file是否是文件
            if (file.isFile()) {
                //4.1 如果是文件:判断文件的名称和查找的文件是否一致
                if (file.getName().equals(fileName)) {
                    System.out.println(file.getAbsolutePath());
                }
            }else {
                //4.2 如果不是文件,进入文件夹继续查找
                findFile(file,fileName);
            }
        }
    }
}
 (3)字符集
  • 字符集
        ASCII字符集:只有英文、数字、符号等,占1个字节。
        GBK字符集:汉字占2个字节,英文、数字占1个字节。
        UTF-8字符集:汉字占3个字节,英文、数字占1个字节。
  • 注意
        技术人员在开发时都应该使用UTF-8编码!
  • 编码: 字符-->字节
        byte[] getBytes()  使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
        byte[] getBytes(String charsetName)    使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
    
  • 解码: 字节-->字符
        String(byte[] bytes)   通过使用平台的默认字符集解码指定的字节数组来构造新的String
        String(byte[] bytes, String charsetName)   通过指定的字符集解码指定的字节数组来构造新的String
    
public class Demo2 {

    public static void main(String[] args) throws UnsupportedEncodingException {
        //编码: 字符-->字节
        String str = "我ABC你";
        //byte[] bytes = str.getBytes(); //使用计算机默认的字符集
        byte[] bytes = str.getBytes("GBk");
        System.out.println(bytes.length);

        //解码: 字节-->字符
        //String content = new String(bytes); //使用计算机默认的字符集
        String content = new String(bytes,"GBK");
        System.out.println(content);
    }
}
(4)字节流
文件字节输入流
    作用:
        读取文件中的内容到程序中,结果是字节
    语法:
        FileInputStream(File file)         创建字节输入流管道与源文件接通
        FileInputStream(String pathname)   创建字节输入流管道与源文件接通
  • 方法(1次读1个字节) int read() 每次读取一个字节返回, 如果发现没有数据可读会返回-1 
public class Demo1 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo1.txt)
        FileInputStream fis = new FileInputStream("day08-code/c_demo1.txt");

        //2. 读取文件中的内容
        //2.1 定义一个文件读取的变量
        int read;
        //2.2 whlie中 读取一次,赋值到变量,判断是否!=-1
        while ((read = fis.read()) != -1) {
            //2.3 使用变量,打印字符
            System.out.println((char) read);
        }

        //3. 如果流操作完毕, 应该主动关闭流
        fis.close();
    }
}

 文件字节输入流(1次读多个字节)

    int read(byte[] buffer)    每次用一个字节数组去读取数据, 返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.
 

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo2.txt)
        FileInputStream fis = new FileInputStream("day08-code/c_demo2.txt");
        //2. 读取文件中的内容
        //2.1 定义一个byte数组,用于数据传输
        byte [] bytes = new byte[3];

        //2.2 使用while循环遍历,
        //定义一个读取的长度,默认是空
        int len;
        //在while中,读取一次赋值到长度变量,判断是否不是-1
        while ( (len = fis.read(bytes)) != -1 ) {
            String str = new String(bytes, 0, len);
            System.out.println("读取了"+len+"个字节,内容是:" + str);
        }

        //3. 如果流操作完毕, 应该主动关闭流
        fis.close();
    }
}
  • 文件字节输入流(1次读所有字节)

        方式1:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
            public int read(byte[] buffer) 每次用一个字节数组去读取,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1.

        方式2: Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
            public byte[] readAllBytes()   直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回

 

public class Demo3 {
    public static void main(String[] args) throws IOException {
        //1. 创建文件字节输入流(c_demo3.txt)
        FileInputStream fis = new FileInputStream("day08-code/c_demo3.txt");

        //2. 读取文件中的内容
        //方式1: 定义一个跟文件同样大小的数组,一次接收所有
        //File file = new File("day08-code/c_demo3.txt");
        //byte [] bytes = new byte[(int) file.length()];
        //fis.read(bytes);
        //String str = new String(bytes);
        //System.out.println(str);

        //方式2: 直接使用readAllBytes将文件中所有内容读取到数组
        byte[] bytes = fis.readAllBytes();
        //转化str
        String str = new String(bytes);
        System.out.println(str);
        //3. 如果流操作完毕, 应该主动关闭流
        fis.close();
    }
}
文件字节输出流
    作用:
        向文件中写入字节内容
    语法:
        FileOutputStream(String filepath)  创建字节输出流管道与源文件路径接通
        FileOutputStream(String filepath, boolean append)  创建字节输出流管道与源文件路径接通,可追加数据
    方法
        void write(int a)  写一个字节出去
        void write(byte[] buffer)  写一个字节数组出去
        void write(byte[] buffer, int pos, int len)  写一个字节数组的一部分出去
        void close()  关闭流
    注意:
        如果要写出换行, 需要写"\r\n"的字节数组表示形式
public class Demo4 {
    public static void main(String[] args) throws IOException {
        //创建文件字节输出流(c_demo4.txt)
        FileOutputStream fos = new FileOutputStream("day08-code/c_demo4.txt");

        //写入数据
        //写一个字节出去
        fos.write(98);

        //写一个字节数组出去
        //"我A你"
        fos.write("\r\n".getBytes()); //换行
        String str = "我A你";
        fos.write(str.getBytes());
        fos.write("\r\n".getBytes()); //换行


        //写一个字节数组的一部分出去
        byte [] bytes = {97,98,99,100,101,102};
        fos.write(bytes,1,2);//byte数组,开始索引,长度

        //关闭流
        fos.close();
    }
}

 

文件复制
    源文件-->输入流-->程序-->输出流-->目标文件

步骤:
    1. 创建文件的输入流,对应到源文件; 创建文件输出流,对应到目标文件
    2. 使用输入流读取数据,使用输出流写出数据(边读边写)
    3. 释放资源(关闭流)

 

public class Demo5 {
    public static void main(String[] args) throws IOException {
        //1、创建文件输入/输出流对象
        FileInputStream fis = new FileInputStream("D:\\uploadPath\\java.wmv");
        FileOutputStream fos = new FileOutputStream("E:\\code\\学习资料.wmv");

        //2、读取文件中的数据
        //定义一个长度
        byte [] bytes = new byte[1024];
        int len;
        //while循环,读取一次将读取长度赋值到变量上,判断是否!=-1
        while ( (len = fis.read(bytes)) != -1) {
            //3、写入到对应文件中
            fos.write(bytes,0,len);
        }

        //4、关闭数据流 (先开的后关)
        fos.close();
        fis.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值