java-day20-递归,IO流

递归

定义

方法定义中调用方法本身的现象

  • 注意
    (1) Math.max(Math.max(a,b),c); //方法的嵌套调用,这不是递归
    (2) 递归一定要有出口,否则就是死递归
    (3) 递归的次数不能太多,否则就内存溢出
    (4) 构造方法不能递归使用

举例

阶乘

public static int jieCheng(int n) {
	if(n==1) {
		return 1;
	}else {
		return n*jieCheng(n-1);
	}
}

斐波那契数列

public static int fib(int n) {
	if (n == 1 || n == 2) {
		return 1;
	} else {
		return fib(n - 1) + fib(n - 2);
	}
}

获取某个目录下所有.java结尾的文件路径

private static void getAllJavaFilePaths(File srcFolder) {
	File[] fileArray = srcFolder.listFiles();
	for (File file : fileArray) {
		if (file.isDirectory()) {
			getAllJavaFilePaths(file);
		} else {
			if (file.getName().endsWith(".java")) {
				System.out.println(file.getAbsolutePath());
			}
		}
	}
}

删除某文件夹包括内部所有文件或文件夹

private static void deleteFolder(File srcFolder) {
	File[] fileArray = srcFolder.listFiles();
	
	for(File file:fileArray) {
		if(file.isDirectory()) {
			deleteFolder(file);
		}else {
			System.out.println(file.getName()+"---"+file.delete());
		}
	}
	System.out.println(srcFolder.getName()+"---"+srcFolder.delete())	
}

IO流

IO流的分类

  • 定义: IO用于在设备间进行数据传输的操作

  • 分类

    • 流向:
      • 输入流: 读取数据
      • 输出流: 写出数据
    • 数据类型:
      • 字节流:
        • 字节输入流: 读取数据
        • 字节输出流: 写出数据
      • 字符流:
        • 字符输入流: 读取数据
        • 字符输出流: 写出数据
  • 注意:
    (1) 一般我们在探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。
    (2) 如果你操作的数据是文本数据,就用字符流。把你要操作的文件用windows自带的记事本打开,如果打开后数据你是可以读懂的,就可以使用字符流,如果不能读懂,就用字节流。
    如果你什么都不知道,就用字节流。

字节输出流操作

操作步骤

A: 创建字节输出流对象
B: 写数据
C: 释放资源

举例

FileOutputStream fos = new FileOutputStream("fos.txt");
/*
 * 创建字节输出流对象做了几件事情 
 * A:调用系统功能去创建文件 
 * B:创建fos对象 
 * C:把fos对象指向这个文件
 */

// 写数据
fos.write("hello.IO".getBytes());
fos.write("java".getBytes());

// 释放资源
fos.close();
/*
 * 为什么一定要close()呢?
 * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了
 * B:通知系统去释放跟该文件相关的资源
 */

FileOutputStream方法

  • 方法
public void write(int b) // 写一个字节
public void write(byte[] byte) // 写一个字节数组
public void write(byte[] b,int off,int len) // 写一个字节数组的一部分
  • 举例
// 创建字节输出流对象
FileOutputStream fos = new FileOutputStream("fos2.txt");

// 调用write()方法
fos.write(97);
fos.write(57);// 字符9
fos.write(55);// 字符7

// public void write(byte[] b)
byte[] bys = {97,98,99,100,101};
fos.write(bys);

// public void write(byte[] b,int off,int len)
fos.write(bys, 1, 3);

// 结果:a97abcdebcd
  • 如何实现数据的换行?
    Windows: \r\n
    Linux: \n
    Mac: \r
  • 如何实现数据的追加写入?
    用构造方法带第二个参数是true的情况即可

加入异常处理的字节输出流操作举例

// 分开做异常处理
// FileOutputStream fos = null;
// try {
// fos = new FileOutputStream("fos4.txt");
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// try {
// fos.write("java".getBytes());
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// try {
// fos.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }

// 一起做异常处理
// try {
// FileOutputStream fos = new FileOutputStream("fos4.txt");
// fos.write("java".getBytes());
// fos.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }

// 改进版
// 为了在finally里面能够看到该对象,就必须定义到外面,为了
// 访问不出问题,还必须给初始化值
FileOutputStream fos = null;
try {
	fos = new FileOutputStream("fos4.txt");
	fos.write("java".getBytes());
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {
	// 为了保证close()一定会执行,就放到这里了
	if (fos != null) {
		try {
			fos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

字节输入流操作

操作步骤

A: 创建字节输入流对象
B: 调用read()方法读取数据,并把数据显示在控制台
C: 释放资源

举例

FileInputStream fis = new FileInputStream("fis.txt");
int by = 0;
while ((by = fis.read()) != -1) {
	System.out.print((char) by);
}
		
// 释放资源
fis.close();

复制文本文件

// 封装数据源
FileInputStream fis = new FileInputStream("a.txt");
// 封装目的地
FileOutputStream fos = new FileOutputStream("b.txt");

int by = 0;
while ((by = fis.read()) != -1) {
	fos.write(by);
}

// 释放资源(先关谁都行)
fos.close();
fis.close();

一次读取一个字节数组

  • int read(byte[] b)
  • 举例
// 创建字节输入流对象
FileInputStream fis = new FileInputStream("fis2.txt");

byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
	System.out.print(new String(bys, 0, len));
}
// 释放资源
fis.close();


// 把c:\\a.txt内容复制到d:\\b.txt中
FileInputStream fis = new FileInputStream("C:\\a.txt");
FileOutputStream fos = new FileOutputStream("D:\\b.txt");

byte[] bys = new byte[1024];
int len = 0;
while((len = fis.read(bys))!= -1) {
	fos.write(bys,0,len);
}

// 释放资源
fos.close();
fis.close();

带缓冲的字节类

通过定义数组的方式确实比以前一次读取一个字节的方式快很多,java提供了带缓冲区的字节类 * 这种类被称为:缓冲区类(高效类)

写数据: BufferedOutputStream

BufferedOutputStream bos = new BufferedOutputStream(
				new FileOutputStream("bos.txt"));
// 写数据
bos.write("hello".getBytes());

// 释放资源
bos.close();

读数据: BufferedInputStream

  • 方式一
BufferedInputStream bis = new BufferedInputStream(
				new FileInputStream("bos.txt"));
		
// 读取数据
int by = 0;
while((by=bis.read())!= -1) {
	System.out.print((char)by);
}
// 释放资源
bis.close();
  • 方式二
BufferedInputStream bis = new BufferedInputStream(
				new FileInputStream("bos.txt"));
byte[] bys = new byte[1024];
int len = 0;
while((len=bis.read(bys))!= -1) {
	System.out.println(new String(bys,0,len)); 
}

// 释放资源
bis.close();
  • 注意:虽然我们有两种方式可以读取,但是请注意这两种方式针对同一个对象在一个代码中只能使用一个。

注意

  1. 构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了
  2. 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
    原因很简单,字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本的流对象实现

IO流分类

  • 字节流
    • InputStream
      • FileInputStream
      • BufferedInputStream
    • OutputStream
      • FileOutputStream
      • BufferedOutputStream
  • 字符流
    • Reader
      • FileReader
      • BufferedReader
    • Writer
      • FileWriter
      • BufferedWriter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值