Java笔记(20):IO流(02)
Posted 花醉红尘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java笔记(20):IO流(02)相关的知识,希望对你有一定的参考价值。
1、递归概述和注意事项
/* * 递归:方法定义中调用方法本身的现象 * * 方法的嵌套调用,这不是递归。 * Math.max(Math.max(a,b),c); * * public void show(int n) { * if(n <= 0) { * System.exit(0); * } * System.out.println(n); * show(--n); * } * * 注意事项: * A:递归一定要有出口,否则就是死递归 * B:递归的次数不能太多,否则就内存溢出 * C:构造方法不能递归使用 */
2、递归求阶乘的代码实现及内存图解
1 package cn.itcast_02; 2 3 /* 4 * 需求:请用代码实现求5的阶乘。 5 * 下面的知识要知道: 6 * 5! = 1*2*3*4*5 7 * 5! = 5*4! 8 * 9 * 有几种方案实现呢? 10 * A:循环实现 11 * B:递归实现 12 * a:做递归要写一个方法 13 * b:出口条件 14 * c:规律 15 */ 16 public class DiGuiDemo { 17 public static void main(String[] args) { 18 int jc = 1; 19 for (int x = 2; x <= 5; x++) { 20 jc *= x; 21 } 22 System.out.println("5的阶乘是:" + jc); 23 24 System.out.println("5的阶乘是:"+jieCheng(5)); 25 } 26 27 /* 28 * 做递归要写一个方法: 29 * 返回值类型:int 30 * 参数列表:int n 31 * 出口条件: 32 * if(n == 1) {return 1;} 33 * 规律: 34 * if(n != 1) {return n*方法名(n-1);} 35 */ 36 public static int jieCheng(int n){ 37 if(n==1){ 38 return 1; 39 }else { 40 return n*jieCheng(n-1); 41 } 42 } 43 }
练习:不死神兔问题案例
1 package cn.itcast_02; 2 3 /* 4 * 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少? 5 * 分析:我们要想办法找规律 6 * 兔子对数 7 * 第一个月: 1 8 * 第二个月: 1 9 * 第三个月: 2 10 * 第四个月: 3 11 * 第五个月: 5 12 * 第六个月: 8 13 * ... 14 * 15 * 由此可见兔子对象的数据是: 16 * 1,1,2,3,5,8... 17 * 规则: 18 * A:从第三项开始,每一项是前两项之和 19 * B:而且说明前两项是已知的 20 * 21 * 如何实现这个程序呢? 22 * A:数组实现 23 * B:变量的变化实现 24 * C:递归实现 25 * 26 * 假如相邻的两个月的兔子对数是a,b 27 * 第一个相邻的数据:a=1,b=1 28 * 第二个相邻的数据:a=1,b=2 29 * 第三个相邻的数据:a=2,b=3 30 * 第四个相邻的数据:a=3,b=5 31 * 看到了:下一次的a是以前的b,下一次是以前的a+b 32 */ 33 public class DiGuiDemo2 { 34 public static void main(String[] args) { 35 // 定义一个数组 36 int[] arr = new int[20]; 37 arr[0] = 1; 38 arr[1] = 1; 39 // arr[2] = arr[0] + arr[1]; 40 // arr[3] = arr[1] + arr[2]; 41 // ... 42 for (int x = 2; x < arr.length; x++) { 43 arr[x] = arr[x - 2] + arr[x - 1]; 44 } 45 System.out.println(arr[19]);// 6765 46 System.out.println("----------------"); 47 48 int a = 1; 49 int b = 1; 50 for (int x = 0; x < 18; x++) { 51 // 临时变量存储上一次的a 52 int temp = a; 53 a = b; 54 b = temp + b; 55 } 56 System.out.println(b); 57 System.out.println("----------------"); 58 59 System.out.println(fib(20)); 60 } 61 62 /* 63 * 方法: 返回值类型:int 参数列表:int n 出口条件: 第一个月是1,第二个月是1 规律: 从第三个月开始,每一个月是前两个月之和 64 */ 65 public static int fib(int n) { 66 if (n == 1 || n == 2) { 67 return 1; 68 } else { 69 return fib(n - 1) + fib(n - 2); 70 } 71 } 72 }
练习:递归输出指定目录下所有的java文件的绝对路径案例
1 package cn.itcast_03; 2 3 import java.io.File; 4 5 /* 6 * 需求:请大家把E:\\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。 7 * 8 * 分析: 9 * A:封装目录 10 * B:获取该目录下所有的文件或者文件夹的File数组 11 * C:遍历该File数组,得到每一个File对象 12 * D:判断该File对象是否是文件夹 13 * 是:回到B 14 * 否:继续判断是否以.java结尾 15 * 是:就输出该文件的绝对路径 16 * 否:不搭理它 17 */ 18 public class FilePathDemo { 19 public static void main(String[] args) { 20 // 封装目录 21 File srcFolder = new File("E:\\\\JavaSE"); 22 23 // 递归功能实现 24 getAllJavaFilePaths(srcFolder); 25 } 26 27 private static void getAllJavaFilePaths(File srcFolder) { 28 // 获取该目录下所有的文件或者文件夹的File数组 29 File[] fileArray = srcFolder.listFiles(); 30 31 // 遍历该File数组,得到每一个File对象 32 for (File file : fileArray) { 33 // 判断该File对象是否是文件夹 34 if (file.isDirectory()) { 35 getAllJavaFilePaths(file); 36 } else { 37 // 继续判断是否以.java结尾 38 if (file.getName().endsWith(".java")) { 39 // 就输出该文件的绝对路径 40 System.out.println(file.getAbsolutePath()); 41 } 42 } 43 } 44 } 45 }
练习:递归删除带内容的目录案例
1 package cn.itcast_03; 2 3 import java.io.File; 4 5 /* 6 * 需求:递归删除带内容的目录 7 * 8 * 目录我已经给定:demo 9 * 10 * 分析: 11 * A:封装目录 12 * B:获取该目录下的所有文件或者文件夹的File数组 13 * C:遍历该File数组,得到每一个File对象 14 * D:判断该File对象是否是文件夹 15 * 是:回到B 16 * 否:就删除 17 */ 18 public class FileDeleteDemo { 19 public static void main(String[] args) { 20 // 封装目录 21 File srcFolder = new File("demo"); 22 // 递归实现 23 deleteFolder(srcFolder); 24 } 25 26 private static void deleteFolder(File srcFolder) { 27 // 获取该目录下的所有文件或者文件夹的File数组 28 File[] fileArray = srcFolder.listFiles(); 29 30 if (fileArray != null) { 31 // 遍历该File数组,得到每一个File对象 32 for (File file : fileArray) { 33 // 判断该File对象是否是文件夹 34 if (file.isDirectory()) { 35 deleteFolder(file); 36 } else { 37 System.out.println(file.getName() + "---" + file.delete()); 38 } 39 } 40 41 System.out 42 .println(srcFolder.getName() + "---" + srcFolder.delete()); 43 } 44 } 45 }
3、FileOutputStream写出数据
1 package cn.itcast_01; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 /* 9 * IO流的分类: 10 * 流向: 11 * 输入流 读取数据 12 * 输出流 写出数据 13 * 数据类型: 14 * 字节流 15 * 字节输入流 读取数据 InputStream 16 * 字节输出流 写出数据 OutputStream 17 * 字符流 18 * 字符输入流 读取数据 Reader 19 * 字符输出流 写出数据 Writer 20 * 21 * 注意:一般我们在探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。 22 * 23 * 需求:我要往一个文本文件中输入一句话:"hello,io" 24 * 25 * 分析: 26 * A:这个操作最好是采用字符流来做,但是呢,字符流是在字节流之后才出现的,所以,今天我先讲解字节流如何操作。 27 * B:由于我是要往文件中写一句话,所以我们要采用字节输出流。 28 * 29 * 通过上面的分析后我们知道要使用:OutputStream 30 * 但是通过查看API,我们发现该流对象是一个抽象类,不能实例化。 31 * 所以,我们要找一个具体的子类。 32 * 而我们要找的子类是什么名字的呢?这个时候,很简单,我们回想一下,我们是不是要往文件中写东西。 33 * 文件是哪个单词:File 34 * 然后用的是字节输出流,联起来就是:FileOutputStream 35 * 注意:每种基类的子类都是以父类名作为后缀名。 36 * XxxOutputStream 37 * XxxInputStream 38 * XxxReader 39 * XxxWriter 40 * 查看FileOutputStream的构造方法: 41 * FileOutputStream(File file) 42 * FileOutputStream(String name) 43 * 44 * 字节输出流操作步骤: 45 * A:创建字节输出流对象 46 * B:写数据 47 * C:释放资源 48 */ 49 public class FileOutputStreamDemo { 50 public static void main(String[] args) throws IOException { 51 // 创建字节输出流对象 52 // FileOutputStream(File file) 53 // File file = new File("fos.txt"); 54 // FileOutputStream fos = new FileOutputStream(file); 55 // FileOutputStream(String name) 56 FileOutputStream fos = new FileOutputStream("fos.txt"); 57 /* 58 * 创建字节输出流对象了做了几件事情: 59 * A:调用系统功能去创建文件 60 * B:创建fos对象 61 * C:把fos对象指向这个文件 62 */ 63 64 //写数据 65 fos.write("hello,IO".getBytes()); 66 fos.write("java".getBytes()); 67 68 //释放资源 69 //关闭此文件输出流并释放与此流有关的所有系统资源。 70 fos.close(); 71 /* 72 * 为什么一定要close()呢? 73 * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了 74 * B:通知系统去释放跟该文件相关的资源 75 */ 76 //java.io.IOException: Stream Closed 77 //fos.write("java".getBytes()); 78 } 79 }
4、FileOutputStream的三个write()方法
1 package cn.itcast_01; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 /* 7 * 字节输出流操作步骤: 8 * A:创建字节输出流对象 9 * B:调用write()方法 10 * C:释放资源 11 * 12 * public void write(int b):写一个字节 13 * public void write(byte[] b):写一个字节数组 14 * public void write(byte[] b,int off,int len):写一个字节数组的一部分 15 */ 16 public class FileOutputStreamDemo2 { 17 public static void main(String[] args) throws IOException { 18 // 创建字节输出流对象 19 // OutputStream os = new FileOutputStream("fos2.txt"); // 多态 20 FileOutputStream fos = new FileOutputStream("fos2.txt"); 21 22 // 调用write()方法 23 //fos.write(97); //97 -- 底层二进制数据 -- 通过记事本打开 -- 找97对应的字符值 -- a 24 // fos.write(57); 25 // fos.write(55); 26 27 //public void write(byte[] b):写一个字节数组 28 byte[] bys={97,98,99,100,101}; 29 fos.write(bys); 30 31 //public void write(byte[] b,int off,int len):写一个字节数组的一部分 32 fos.write(bys,1,3); 33 34 //释放资源 35 fos.close(); 36 } 37 }
5、FileOutputStream写出数据实现换行和追加写入
1 package cn.itcast_01; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 6 /* 7 * 如何实现数据的换行? 8 * 为什么现在没有换行呢?因为你值写了字节数据,并没有写入换行符号。 9 * 如何实现呢?写入换行符号即可呗。 10 * 刚才我们看到了有写文本文件打开是可以的,通过windows自带的那个不行,为什么呢? 11 * 因为不同的系统针对不同的换行符号识别是不一样的? 12 * windows:\\r\\n 13 * linux:\\n 14 * Mac:\\r 15 * 而一些常见的个高级记事本,是可以识别任意换行符号的。 16 * 17 * 如何实现数据的追加写入? 18 * 用构造方法带第二个参数是true的情况即可 19 */ 20 public class FileOutputStreamDemo3 { 21 public static void main(String[] args) throws IOException { 22 // 创建字节输出流对象 23 // FileOutputStream fos = new FileOutputStream("fos3.txt"); 24 // 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。 25 FileOutputStream fos = new FileOutputStream("fos3.txt", true); 26 27 // 写数据 28 for (int x = 0; x < 10; x++) { 29 fos.write(("hello" + x).getBytes()); 30 fos.write("\\r\\n".getBytes()); 31 } 32 33 // 释放资源 34 fos.close(); 35 } 36 }
6、FileOutputStream写出数据加入异常处理
1 package cn.itcast_01; 2 3 import java.io.FileNotFoundException; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 /* 8 * 加入异常处理的字节输出流操作 9 */ 10 public class FileOutputStreamDemo4 { 11 public static void main(String[] args) { 12 // 分开做异常处理 13 // FileOutputStream fos = null; 14 // try { 15 // fos = new FileOutputStream("fos4.txt"); 16 // } catch (FileNotFoundException e) { 17 // e.printStackTrace(); 18 // } 19 // 20 // try { 21 // fos.write("java".getBytes()); 22 // } catch (IOException e) { 23 // e.printStackTrace(); 24 // } 25 // 26 // try { 27 // fos.close(); 28 // } catch (IOException e) { 29 // e.printStackTrace(); 30 // } 31 32 // 一起做异常处理 33 // try { 34 // FileOutputStream fos = new FileOutputStream("fos4.txt"); 35 // fos.write("java".getBytes()); 36 // fos.close(); 37 // } catch (FileNotFoundException e) { 38 // e.printStackTrace(); 39 // } catch (IOException e) { 40 // e.printStackTrace(); 41 // } 42 43 // 改进版 44 // 为了在finally里面能够看到该对象就必须定义到外面,为了访问不出问题,还必须给初始化值 45 FileOutputStream fos = null; 46 try { 47 // fos = new FileOutputStream("z:\\\\fos4.txt"); 48 fos = new FileOutputStream("fos4.txt"); 49 fos.write("java".getBytes()); 50 } catch (FileNotFoundException e) { 51 e.printStackTrace(); 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } finally { 55 // 如果fos不是null,才需要close() 56 if (fos != null) { 57 // 为了保证close()一定会执行,就放到这里了 58 try { 59 fos.close(); 60 } catch (IOException e) { 61 e.printStackTrace(); 62 } 63 } 64 } 65 } 66 }
7、FileInputStream读取数据
1 package cn.itcast_02; 2 3 import java.io.FileInputStream; 4 import java.io.IOException; 5 6 java缓冲字符字节输入输出流:java.io.BufferedReaderjava.io.BufferedWriterjava.io.BufferedInputStreamjava.io.(代码片段