文件过滤器- 递归- 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-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: 字节输入转换流,将输入字节流转换为输入字符流
构造方法:
InputStreamReader(InputStream in): 将传入的字节流转换字符流
InputStreamReader(InputStream in,String charsetName): 设置字符流的编码集
OutputStreamWriter:字节输出转换流,将输出字节流转换为输入字符流
构造方法:
OutputStreamWriter(OutputStream out): 创建一个使用默认字符编码的OutputStreamWriter。
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;
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!