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

2023-12-28 21:51:17

目录

文件过滤器

方法的递归调用

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;

文章来源:https://blog.csdn.net/Zyangxsir/article/details/135278178
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。