文件过滤器- 递归- IO流- Lambda表达式

目录

文件过滤器

方法的递归调用

IO流

Lambda表达式


文件过滤器

概念:将不要文件过滤掉,剩下我们需要

类型:

1. FilenameFilter:文件过滤器 如果需要使用多次可以创建一个类去实现FilenameFilter接口

File[] files = file.listFiles(new FilenameFilter() { // 带有文件过滤器
    @Override
    public boolean accept(File dir, String name) { 
        return new File(dir, name).isFile();   // 用这个方法需要新建对象
    }
}); 

2. FileFilter:文件过滤器 如果需要使用多次可以创建一个类去实现FileFilter接口

File[] files = file.listFiles(new FileFilter() {  // file.list不适用
    @Override
    public boolean accept(File pathname) {
        return pathname.isFile() && pathname.getName().endsWith(".txt");
    }
});
​

复制文件

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();
}

方法的递归调用

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

递归:

  1. 第一个动作是:递(调自己),一直递会造成栈溢出

  2. 第二个动作是:归(不再调用自己,递的终点,然后再逐层返回结果)

缺点:递归的性能很差,一般不用递归

优点:解决无限级问题

// 设计一个方法来计算1-n的和
public static int getSum(int n) {
      int sum = 0;
      for (int i = 1; i <= n; i++) {
          sum += i;
      }
    if(n == 1) {  // 当n==1的时候,停止调用自己,开始返回值,依次输出之前暂停的方法
        return 1; // 归, 没有这个会栈溢出
    }
    // getSum(n - 1) 每次执行都会调用这个方法,在栈中第一次执行的会在最下面,然后调用方法的时候,就会暂时停在那里,等有了出口的时候,就会再依次从栈的顶端返回来输出。
    return n + getSum(n - 1); // 调用的方法是自己,这就是递归调用
}
​
// 递归应用的案例
// 删除 e:/pp文件夹
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个字节,字节流读取中文不友好,字节流一般不用来操作文本文件

一个中文,字母,数字都是一个字符,字符流读取中文没有问题,字符流一般用来读取文本文件

按数据流动的方向来分:

输入流:用来读文件 输出流:用来向文件写入的

字节流(重点)

InputStream:字节输入流的父类

子类FileInputStream:文件字节输入流(读取的数据源是一个文件)

构造方法:

1)、FileInputStream(String name)

2)、FileInputStream(File file)

FileInputStream fis = new FileInputStream(new File("e:/1.txt")); // 字节输入流和文件的连接
​
方法1. read()
​
// 从流里面取出一个字节 read():读一个字节
     int data = fis.read();// 从流里面读一个字节
     System.out.println(data); // 返回-1说明文件已经读完了
// 循环读取
        int data;
     while((data = fis.read()) != -1) { // read():一次读一个字节性能比较低
         System.out.print((char)data); 
     }
​
方法2.read(byte[] b):连接一次可以读多个字节,将数据读到一个字节数组中,返回的数读到字节个数  性能远远高于read();
​
 // 创建文件字节输入流
     FileInputStream fis = new FileInputStream("e:/1.txt");
 // 创建一个字节数组
        byte[] bytes = new byte[3];
        int count; // 存储读取的字节个数
        while((count = fis.read(bytes)) != -1) {
         // 放到一个string对象里
        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);  打印3 返回字节个数为-1,表示文件读完了/*
*  字节流读中文
*/
FileInputStream fis = new FileInputStream("e:/1.txt");
byte[] bytes = new byte[3];  // 一个汉字占三个字节,必须要写3,否则会把汉字给拆开
int count; // 存储读取的字节个数
while((count = fis.read(bytes)) != -1) {
    // 放到一个string对象里
    String s = new String(bytes,0,count);
    System.out.println(s);
}
​
​

OutputStream:所有字节输出流的父类

子类FileOutputStream:文件字节输出流,向文件写入内容,字节流是自动刷新

构造方法:

1)、FileOutputStream(String name):覆盖流 创建文件输出流以指定的名称写入文件

// 创建FileOutputStream(文件字节输出流)
     FileOutputStream fos = new FileOutputStream("e:/2.txt");// 写入的文件不存在,会自动创建

2)、FileOutputStream(String name, boolean append): 追加流

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

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

// 方法1:write(int b):一次写入一个字节
FileOutputStream fos = new FileOutputStream("e:/2.txt"); // 覆盖流会覆盖
fos.write(66); // 将A写入到fos流里面
fos.write(66); // 将A写入到fos流里面
fos.flush(); // 刷新流,将流里面的数据写入文件里面

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

// 方法3:write(byte[] b, int off, int len):将数组中指定数据写入
fos.write("abcdefghijk".getBytes(),2,5); // getBytes 将结果存储到一个新的 byte 数组中
​
/**
 * 文件字节输出流的案例
 */
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 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(创建流的代码) {
 *     流要执行代码
 * }
 */
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);
       }
    }
}
​
/**
 * 复制图片案例
 * 输入输出流都要用
 */
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 FileDemo {
    public static void main(String[] args) {
        File file = new File("F:\\1117JAVA全栈班\\2023-12-26-Java加强-IO流-文件读写\\video");
        File[] fileList = getFileList(file, new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.getName().endsWith(".mp4");
            }
        });
        for (File f : fileList) {
            System.out.println(f);
        }
​
    }
    //条件过滤, 条件是调用的时候传进来的
    public static File[] getFileList(File file, FileFilter fileFilter){
        File[] files = file.listFiles();
        ArrayList<File> list = new ArrayList<>();
        for (File f : files) {
            if (fileFilter.accept(f)) {
                list.add(f);
            }
        }
        //转为File数组
        return list.toArray(new File[0]);
    }
}

字符流

概念:以字符为单位来操作文件的流

1.Reader:所有输入字符流的父类,输入字符流

        FiLeReader:文件字符输入流,用来按字符为单位读取文件

2.Writer:所有输出字符流的父类,输出字符流

        FileWriter:文件字符输出流,不会自动刷新

 // 创建FileReader对象:文件字符输入流
       
 // 读取文件
 // 0.一个一个读
        int data = fr.read();// 一次读取一个字符,返回的是字符ASCII码  返回-1表示文件读完了
​
 // 1.循环读
// 返回-1表示文件读完了
        int data;
          while((data = fr.read()) != -1) {
             System.out.print((char)data);
}
​
//  2.一次读3个字符
        char[] chars = new char[3];
        int count; // 读取字符个数
        while((count = fr.read(chars)) != -1) {
             // 创建字符创
            String s = new String(chars, 0, count);
              System.out.print(s);
}
// 3.截取一部分读
while ((count = fr.read(chars,1,2)) != -1) {
            String s = new String(chars, 1, count);
            System.out.println(s);
        }
/**
 * 字符输入流的案例
 */
public class IODemo2 {
    public static void main(String[] args) throws IOException {
        try(
            // 创建文件字符输入流
            FileReader fr = new FileReader("C:\\Users\\ITsource\\Desktop\\新建文本文档.txt");
        ) {
            char[] chars = new char[1024];
            int count;
            while ((count = fr.read(chars)) != -1) {
                String s = new String(chars, 0, count);
                System.out.println(s);
            }
        }
    }
}
​
/**
 * 字符输出流的案例
 *  FileWriter:文件字符输出流,不会自动刷新
 *  flush:刷新
 *
 */
public class IODemo3 {
    public static void main(String[] args) throws IOException {
        // 创建文件字符输出流对象
        FileWriter fw = new FileWriter("e:/4.txt");// 覆盖流
//        fw.write(34567); // 向流写入
//        fw.write(23456);
//        fw.write(65222);
//        fw.write(21345);
//        fw.flush(); // 刷新流
//        fw.write("dsgfdsfgd无关风月325432sds".toCharArray(),2,4);
        fw.write("我题序等你回~",2,5);
        fw.flush(); // 刷新流
    }
}

转换流

将字节流转换字符流的一种流

InputStreamReader: 字节输入转换流,将输入字节流转换为输入字符流

构造方法:

  1. InputStreamReader(InputStream in): 将传入的字节流转换字符流

  2. InputStreamReader(InputStream in,String charsetName): 设置字符流的编码集

OutputStreamWriter:字节输出转换流,将输出字节流转换为输入字符流

构造方法:

  1. OutputStreamWriter(OutputStream out): 创建一个使用默认字符编码的OutputStreamWriter。

  2. OutputStreamWriter(OutputStream out, String charsetName): 创建一个使用命名字符集的OutputStreamWriter。

注意:转换流只能操作字节流,不能直接操作文件

FileInputStream fis = new FileInputStream("1.txt"); // 创建文件字节输入流
// 1.将字节流转换字符流
InputStreamReader isr = new InputStreamReader(fis);
InputStreamReader isr = new InputStreamReader(fis);
        int data;
        while((data = isr.read()) != -1) {
        System.out.print((char)data);
 }
​
 //2.将字节流转换字符流,并且设置字符流的编码集是gbk
new InputStreamReader(fis,"gbk");

缓冲流

概念:自带缓冲区的流,默认的缓冲区是8K,操作文件就可以减少连接次数,从而提高的性能

作用:

字节流和字符流操作的流程

1)、和文件产生连接

​2)、开始操作 操作一次就要连接一次(连接的次数多操作性能就比较低) 为提高操作性能,用数组,减少连接次数

缓冲字节流

     缓冲字节输入流: BufferedIntputStream  操作的对象是输入字节流

     缓冲字节输出流: BufferedoutputStream

缓冲字符流

缓冲字符输入流: BufferedReader(Reader in) :创建使用默认大小的输入缓冲区的缓冲字符输入流。

方法:readLine() 读行

缓冲字符输出流: BufferedWriter(Writer out) :创建使用默认大小的输出缓冲区的缓冲字符输出流。

方法: newLine() 换行

BufferedReader br = new BufferedReader(new FileReader("e:/1.txt"));  // 创建缓冲字符输入流   
BufferedWriter bw = new BufferedWriter(new FileWriter("e:/333.txt")); // 创建缓冲字符输出流
char[] chars = new char[1024]; // 一次读1kb的数据
int count;
while ((count = br.read(chars)) != -1) {
    String s = new String(chars, 0,count); 
    System.out.print(s);
​
// readLine() 读行  输入流的方法
// newLine(); 换行  输出流的方法
String s = "";  // 需要用String来接收,读的整行
while ((s = br.readLine()) != null) { // readLine()返回null说明文件读完了
      System.out.println(s);
    bw.write(s);
    bw.newLine(); // 换行
    bw.flush(); // 刷新流
}

IO流小节:( Java要掌握的流(16个))

文件专属:

字节输入输出流 :自动刷新

Inputscream

        FileInputStream(掌握)

Outputscream

         FileOutputStream(掌握)

字符输入输出流: 需要手动刷新

Reader

        FileReader

Writer

        FileWriter

转换流:(将字节流转换成字符流)

InputStreamReader

OutputStreamWriter

缓冲流:

BufferedReader

BufferedWriter

BufferedInputStream

BufferedOutputStream

Lambda表达式

作用:简化使用匿名内部类创建函数式接口对象的代码

注意: 函数式接口只有一个抽象方法的时候可以使用

语法:()-> { }

从抽象方法的()开始简化,到这个方法的方法体,其他都不要了 ()和方法体之间需要->连接

// 正常使用匿名内部类
IDemo iDemo = new IDemo() {
         @Override   
         public int getSum(int n) {
             return 10 + n;
      }
};
​
// 使用lambda表达式
IDemo iDemo2 = (int n) ->{        // (int n):就是重写getSum()方法,方法体就是->后面
         return 10 + n;
};
​
// 创建IDemo2函数式接口的对象
IDemo2 d2 = (int a,int b) -> {return a > b ? a : b;};
​
// 创建IDemo3的函数式接口的对象
   IDemo3 d3 = () -> {
      System.out.println("hello");
};
​
// 遍历集合
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);  //   
     list.forEach((Integer pp)->{
         System.out.println(pp);
});
​
/*
*    简化lambda表达式
*    方法名已经简化了,可以省略参数的数据类型
*    如果参数的个数只有一个,可以省略()
*    ->后面的称为lambda体,如果lambda体只有一句语句,{}可以省略,如果{}里面有return,在省略{}时候一起省略
*/
IDemo id = a -> 10 + a;
IDemo2 id2 = (a,b) -> a > b ? a : b;
  • 40
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zyangxsir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值