File&递归&IO流总结

发布时间 2023-12-28 20:48:43作者: ZWJAS

总结

文件过滤器

1、文件过滤器:将不要文件过滤掉,剩下我们需要
FilenameFilter:文件过滤器
FileFilter:文件过滤

public class FileDemo1 {
    public static void main(String[] args) {
        File file = new File("e:/pp");
//        File[] files = file.listFiles(); // 没有过滤器
//        for (File f : files) {
//                if(f.isFile() && f.getName().endsWith(".ppt"))
//                    System.out.println(f);
//        }
//        File[] files = file.listFiles(new FilenameFilter() { // 带有文件过滤器
//            @Override
//            public boolean accept(File dir, String name) {
//                return new File(dir, name).isFile();
//            }
//        });
        File[] files = file.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isFile() && pathname.getName().endsWith(".txt");
            }
        });
        for (File f : files) {
            f.delete();
        }
//        String[] list = file.list(); // 获取所有的文件和文件夹
//        for (String s : list) {
//            // 进行过滤,只要ppt文件
//            if(s.endsWith(".ppt"))
//                System.out.println(s);
//        }
//        String[] list1 = file.list(new MyFilter());// 有过滤器
//        for (String s : list1) {
//            System.out.println(s);
//        }

//        String[] list2 = file.list(new FilenameFilter() {
//            @Override
//            public boolean accept(File dir, String name) {
//                return new File(dir, name).isFile();
//            }
//        });
//        System.out.println(Arrays.toString(list2));
    }
}
  • 复制文件

    /**
     * 复制文件
     */
    public class FileDemo2 {
        public static void main(String[] args) throws IOException {
            File file = new File("e:/pp");
            // 只需要ppt文件
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isFile() && pathname.getName().endsWith(".ppt");
                }
            });
            // 遍历创建文件
            for (File f : files) {
                File ff = new File("e:/aa", f.getName());
                // 创建文件
                ff.createNewFile();
            }
        }
    }
    

方法的递归调用

简单理解就是方法的一种特殊调用,自己方法调用自己

递归:第一个动作是:(调自己),一直递会造成栈溢出
第二个动作是:(不再调用自己,递的终点,然后再逐层返回结果)

递归的性能很差,一般不用递归,解决无限级问题

public class RecursionDemo1 {
    // 设计一个方法来计算1-n的和
    public static int getSum(int n) {
//        int sum = 0;
//        for (int i = 1; i <= n; i++) {
//            sum += i;
//        }
        if(n == 1) {
            return 1;
        }
        return n + getSum(n - 1); // 调用的方法是自己,这就是递归调用
    }
    // 分析:1-n的和等于 n + 1到(n-1)的和
    /*
        n = 5,1到5的和 = 1 + 2 + 3 + 4 + 5
        n + 1到4的和 = 5 + 1 + 2 + 3 + 4
     */

    public static void main(String[] args) {
        int sum = getSum(5);// StackOverflowError:栈溢出
        System.out.println(sum);
    }
}
  • 递归应用的案例:删除 e:/pp文件夹
/**
 * 递归应用的案例
 * 删除 e:/pp文件夹
 */
public class RecursionDemo2 {
    public static void remove(File file) {
        // 获取file对象(文件夹)里面所有File对象
        File[] files = file.listFiles();
        for (File f : files) {
            // f如果是文件夹
            if(f.isDirectory())
                // 递归调用
                remove(f);
            // 删除
            f.delete();
        }
        // 删除最外的文件夹0
        file.delete();
    }




    public static void main(String[] args) {
//        remove(new File("e:/pp"));

    }

}

IO流

:具有流动性,操作数据

  • I:InputStream:输入流,读取文件内容
    怎么读取文件的?
    1)、使用输入流和文件建立连接
    2)、将文件里面的内容加载到流里面
    3)、从流对象中取出内容
    读文件数据的流动方向:从硬盘到内存

  • O:OutputStream:输出流,向文件写入内容
    怎样向文件写入内容?
    1)、使用输出流和文件建立连接
    2)、将内容写入输出流对象里面
    3)、将流里面内容写到文件里面
    写文件数据的流动方向:从内存到硬盘

IO:输出输出流,对文件进行读写操作的

  • 讲解IO的分类

    • 按操作单位来分:
      字节流:按照字节为单位来操作文件,一次读一个字节或者写一个字节
      字符流:按照字符为单位来操作文件,一次读一个字符或者写一个字符
      注意:一个中文占2个或3个字节,字节流读取中文不友好,字节流一般不用操作文本文件
      一个中文,字母,数字都是一个字符,字符流读取中文没有问题,字符流一般用来读取文本 文件

    • 按数据流动的方向来分:
      输入流:用来读文件
      输出流:用来向文件写入的

字节输入流(read(byte[] b))

讲解字节流(重点)
InputStream:字节输入流的父类
FileInputStream:文件字节输入流(读取的数据源是一个文件)

**构造方法 **: FileInputStream(String name)

public class IODemo2 {
    public static void main(String[] args) throws IOException {
        // 创建FileInputStream对象
//        FileInputStream fis = new FileInputStream("E:/1.txt");
        FileInputStream fis = new FileInputStream(new File("e:/1.txt")); // 字节输入流和文件的连接
        // 从流里面取出一个字节 read():读一个字节
//        int data = fis.read();// 从流里面读一个字节
//        System.out.println(data);
//        int data2 = fis.read();// 从流里面读二个字节
//        System.out.println(data2);
//        int data3 = fis.read();// 从流里面读三个字节
//        System.out.println(data3);
//        int data4 = fis.read();// 从流里面读四个字节
//        System.out.println(data4);
//        int data5 = fis.read();
//        System.out.println(data5); // 返回-1说明文件已经读完了
        int data;
        while((data = fis.read()) != -1) {
            System.out.print((char)data);
        }
        // read():一次读一个字节性能比较低

        // read(byte[] b):连接一次可以多多个字节,将数据读到一个字节数组中,返回的数读到字节个数
    }
public class IODemo3 {
    public static void main(String[] args) throws IOException {
        // 创建文件字节输入流
        FileInputStream fis = new FileInputStream("e:/1.txt");
        // 创建一个字节数组
        byte[] bytes = new byte[3];
        int count; // 存储读取的字节个数
        while((count = fis.read(bytes)) != -1) {
//            System.out.println(Arrays.toString(bytes));
            // 将bytes转换为字符串
            String s = new String(bytes,0,count);
            System.out.print(s);
        }
        // count:表示读取的字节个数,从流里面读取的数据,放到bytes数组里面
//        int count = fis.read(bytes);  // 连接一次文件读取三个字节
//        System.out.println(Arrays.toString(bytes));
//        System.out.println("第一次读取的字节数:" + count);
//
//        int count2 = fis.read(bytes);
//        System.out.println(Arrays.toString(bytes));
//        System.out.println("第二次读取的字节数:" + count2);
//
//        int count3 = fis.read(bytes);
//        System.out.println(Arrays.toString(bytes));
//        System.out.println("第三次读取的字节数:" + count3);
//
//        int count4 = fis.read(bytes);
//        System.out.println(count4); // 返回字节个数为-1,表示文件读完了



    }
}
  • 文件字节输入流,读取多个字节 : read(byte[] b, int off, int len)
/**
 * 文件字节输入流,读取多个字节
 * read(byte[] b, int off, int len)
 */
public class IODemo4 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("e:/1.txt");
        byte[] bytes = new byte[3];
        int count;
        while((count = fis.read(bytes,1,2)) != -1) {
            System.out.println(Arrays.toString(bytes));
        }
    }

}
  • 字节流读中文
/**
 * 字节流读中文
 */
public class IODemo5 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("e:/1.txt");
//        int data;
//        while((data = fis.read()) != -1) {
//            System.out.println((char)data);
//        }
//        byte[] bytes = new byte[3];
//        int count; // 保存读取字节个数
//        while((count = fis.read(bytes)) != -1) {
//            String s = new String(bytes, 0, count);
//            System.out.print(s);
//        }

    }
}
  • 读图片的性能比较
/**
 * 读图片的性能比较
 */
public class IODemo6 {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("e:/2.webp");
        int data;
        while((data = fis.read()) != -1) {

        }
        long end = System.currentTimeMillis();
        System.out.println("用时:" + (end - start) + "毫秒");

        long start2 = System.currentTimeMillis();
        FileInputStream fis2 = new FileInputStream("e:/2.webp");
        byte[] bytes = new byte[1024]; // 1kb
        int count;
        while((count = fis2.read(bytes)) != -1) {

        }
        long end2 = System.currentTimeMillis();
        System.out.println("用时:" + (end2 - start2) + "毫秒");
    }
}

字节输出流

OutputStream:所有字节输出流的父类
FileOutputStream:文件字节输出流,向文件写入内容,字节流是自动刷新
1、构造方法
FileOutputStream(String name):覆盖流
创建文件输出流以指定的名称写入文件。
FileOutputStream(String name, boolean append): 追加流
创建文件输出流以指定的名称写入文件。

FileOutputStream(File file)
创建文件输出流以写入由指定的 File对象表示的文件。

注意:写入的文件不存在时,会自动创建目的文件

public class IODemoOut1 {
    public static void main(String[] args) throws IOException {
        // 创建FileOutputStream(文件字节输出流)
        FileOutputStream fos = new FileOutputStream("e:/2.txt");// 写入的文件不存在,会自动创建
        // 常用的方法:write(int b):一次写入一个字节
//        fos.write(66); // 将A写入到fos流里面
//        fos.write(66); // 将A写入到fos流里面
//        fos.write(66); // 将A写入到fos流里面
//        fos.write(66); // 将A写入到fos流里面
//        fos.flush(); // 刷新流,将流里面的数据写入文件里面

        // write(byte[] b):写入多个字节
//        String str = "范德萨范德萨发生的范德萨发生发生的发的所发生的";
//        fos.write(str.getBytes()); // str.getBytes():将字符串转换字节数组

        // write(byte[] b, int off, int len):将数组中指定数据写入
        fos.write("abcdefghijk".getBytes(),2,5);


    }


}
  • 文件字节输出流的案例
/**
 * 文件字节输出流的案例
 */
public class IODemoOut2 {
    public static void main(String[] args)throws IOException {
        // 产生10个100以内不重复的数字,将这数字写入一个文件中
        HashSet<Integer> hs = new HashSet<>();
        while(hs.size() < 10) {
            hs.add((int)(Math.random() * 100 + 1));
        }
        // 创建文件字节输出流
        FileOutputStream fos = new FileOutputStream("e:/number.txt");
        // 遍历集合
        Iterator<Integer> it = hs.iterator();
        while (it.hasNext()) {
            Integer next = it.next();
            fos.write(String.valueOf(next + "    ").getBytes());
        }

    }
}
  • 复制图片案例(输入输出流都要用)
public class CopyImage {
    public static void copy(String src,String dest) {
        try {
            // 创建文件字节输入流
            FileInputStream fis = new FileInputStream(src);
            byte[] bytes = new byte[1024];
            int count; // 保存读取字节个数
            // 创建文件字节输出流
            FileOutputStream fos = new FileOutputStream(dest);
            while ((count = fis.read(bytes)) != -1) {
                // 将数据写入fos流
                fos.write(bytes,0,count);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public static void main(String[] args) {
        copy("e:/2.webp","e:/3.webp");
    }
}
  • 关闭流

    流对象用完要关闭
    注意关闭流的顺序:先用的后关

/**
 * 讲解关闭流
 * 流对象用完要关闭
 * 注意关闭流的顺序:先用的后关
 */
public class CloseDemo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("e:/1.txt");
            int data = fis.read();
            fos = new FileOutputStream("e:/3.txt");
            fos.write(data);
            // 关闭流:close();
//            fis.close(); // 代码有可能执行不到
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 释放锁,关闭流
            if(fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }finally {
                    if(fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                    }
                }
            }
        }
    }
}
  • 自动关流

    注意:要关闭的流必须支持自动关流

    自动关流的语法
    try(创建流的代码) {
    流要执行代码

/**
 * 自动关流
 * 注意:要关闭的流必须支持自动关流
 *
 * 自动关流的语法
 * try(创建流的代码) {
 *     流要执行代码
 * }
 */
public class CloseDemo2 {
    public static void main(String[] args) {
       try(
               FileInputStream fis = new FileInputStream("e:/1.txt");
               FileOutputStream fos = new FileOutputStream("e:/3.txt");
       ) {
           fis.read();
           fos.write("abc".getBytes());
       } catch (FileNotFoundException e) {
           throw new RuntimeException(e);
       } catch (IOException e) {
           throw new RuntimeException(e);
       }
    }
}