黑马程序员——IO流——递归,字节流,字符流

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一.递归

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

(2)递归的注意事项;

A:要有出口,否则就是死递归
B:次数不能过多,否则内存溢出
C:构造方法不能递归使用

(3)递归案例:

A:递归求阶乘

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

public class Demo {

	/**
	 * 递归求5的阶乘
	 * 分析:就是求1*2*3*4*5
	 * 可以看做	5*4的阶乘,4的阶乘就是4*3的阶乘依次类推
	 * 我们就可以定义求阶乘的方法了
	 */
	public static void main(String[] args) {
		//调用方法
		int num = method(5);
		System.out.println(num);
		
	}
	
	public static int method(int n){
		//确定阶乘出口如果n==1,就返回1
		if(n==1){
			return 1;
		}
		//返回n的阶乘的值
		return n*method(n-1);
		
	}

}</strong></span>


B:求斐波那契数列第15项的值.斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

/*
 * 求斐波那契数列第15项的值.斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55
 * 
 * 分析:1.根据斐波那契数列前10项的值可以得出规律
 * 		从第3项开始:  	当前项的值	=  当前项的前一项的值  +  当前项的前一项的前一项值
 * 
 * 	   2.我们使用递归方式求斐波那契数列第n项的值
 * 		使用递归我们必须要定义递归方法的出口:
 * 								当是第1项和第2项时,返回1
 * 		
 */
public class Demo2 {

	public static void main(String[] args) {
			// 调用方法获得第15项对应的值
			int value = method(15);
			// 输出结果
			System.out.println("第15项的值为:" + value);
	}

	// 使用递归方式定义方法,方法中参数为当前的项数
	public static int method(int n) {
		// 递归出口(当是第1项和第2项时,返回1)
		if (n == 1 || n == 2) {
			return 1;
		}
		// 递归调用(当前项的值=当前项的前一项的值 +当前项的前一项的前一项值)
		return method(n - 1) + method(n - 2);
	}

}
</strong></span>


C:递归删除带内容的目录


<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.File;

public class Demo3 {

	/**
	 * 递归删除带内容的目录
	 */
	public static void main(String[] args) {
		//创建文件对象
		File file = new File("F:\\a");
		//调用方法删除目录
		delete(file);
	}
	
	public static void delete(File file){
		//判断文件有无内容
		if (file.isDirectory()) {
			//将文件对象转成数组
			File[] listFiles = file.listFiles();
			//遍历文件数组
			for (File file2 : listFiles) {
				//使用递归操作文件对象
				delete(file2);
			}
		}else{
			//如果是文件,直接删除
			file.delete();
		}
		//空文件夹直接删除
		file.delete();
	}

}
</strong></span>


二.IO流
1.IO流概述

(1)IO用于在设备间进行数据传输的操作

(2)分类:

A:流向
输入流 读取数据
输出流 写出数据

B:数据类型
字节流
字节输入流
字节输出流
字符流
字符输入流
字符输出流

2.字节流

(1)FileOutputStream写出数据

A:使用步骤

a:创建字节输出流对象
b:调用write()方法进行写出数据
c:关闭字节输出流对象释放资源

(2)FileInputStream读取数据

A:使用步骤
a:创建字节输入流对象
b:调用read()方法进行读取数据
c:关闭字节输入流对象释放资源


(3)字节缓冲区流(高效字节流)

使用步骤与普通流一样,只需要在创建字节缓冲区流对象时将普通流传入即可.

A:BufferedOutputStream
B:BufferedInputStream

(4)字节流使用综合案例:

使用字节流四种复制方式分别复制文件

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo4 {

	/**
	 * 使用字节流四种复制方式分别复制文件
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//调用方法进行复制
		method1();
		method2();
		method3();
		method4();
	}

	// 方法一:使用普通字节流一次一个字节复制文件
	public static void method1() throws IOException {
		// 创建流对象
		FileInputStream fis = new FileInputStream("a.txt");
		FileOutputStream fos = new FileOutputStream("b.txt");
		// 读取数据
		int b;
		while ((b = fis.read()) != -1) {
			// 写出数据
			fos.write(b);
		}
		// 关闭流
		fos.close();
		fis.close();

	}

	// 方法二:使用普通字节流一次一个字节数组复制文件
	public static void method2() throws IOException {
		// 创建流对象
		FileInputStream fis = new FileInputStream("a.txt");
		FileOutputStream fos = new FileOutputStream("b.txt");
		// 读取数据
		int len;
		byte[] bytes = new byte[1024];
		while ((len = fis.read(bytes)) != -1) {
			// 写出数据
			fos.write(bytes, 0, len);
		}
		// 关闭流
		fos.close();
		fis.close();
	}

	// 方法三:使用缓冲区字节流一次一个字节复制文件
	public static void method3() throws IOException {
		// 创建流对象
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
		// 读取数据
		int b;
		while ((b = bis.read()) != -1) {
			// 写出数据
			bos.write(b);
		}
		// 关闭流
		bos.close();
		bis.close();
	}

	// 方法四:使用缓冲区字节流一次一个字节数组复制文件
	public static void method4() throws IOException {
		// 创建流对象
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));
		// 读取数据
		int len;
		byte[] bytes = new byte[1024];
		while ((len = bis.read(bytes)) != -1) {
			// 写出数据
			bos.write(bytes, 0, len);
		}
		// 关闭流
		bos.close();
		bis.close();
	}

}
</strong></span>


3.字符流

(1)主要针对文本文件这样的数据操作
Reader
a.InputStreamReader:子类FileReader

b.BufferedReader
Writer
a.OutputStreamWriter:子类FileWriter

b.BufferedWriter




(2)FileWriter写入数据
使用步骤:
A:创建字符输出流对象
B:调用对象的write()方法写入数据
C:字符输出流释放资源

(3)FileReader读取数据

使用步骤:
A:创建字符输入流对象
B:调用对象的read()方法读取数据
C:字符输入流释放资源

(4)字符缓冲区流(高效字符流)

使用步骤与普通流一样,只需要在创建字符缓冲区流对象时将普通流传入即可.

A:BufferedWriter
B:BufferedReader


(5)字符流使用综合案例:

使用字符流五种复制方式分别复制文本文件

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo5 {

	/**
	 * 使用字符流五种复制方式分别复制文本文件
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//调用方法对文本文件进行复制
		method1();
		method2();
		method3();
		method4();
		method5();
	}

	// 方法一:使用普通字符流一次一个字符复制文件
	public static void method1() throws IOException {
		// 创建流对象
		FileReader fr = new FileReader("a.txt");
		FileWriter fw = new FileWriter("b.txt");
		// 读取数据
		int c;
		while ((c = fr.read()) != -1) {
			// 写出数据
			fw.write(c);
		}
		// 关闭流
		fw.close();
		fr.close();

	}

	// 方法二:使用普通字符流一次一个字符数组复制文件
	public static void method2() throws IOException {
		// 创建流对象
		FileReader fr = new FileReader("a.txt");
		FileWriter fw = new FileWriter("b.txt");
		// 读取数据
		int len;
		char[] chars = new char[1024];
		while ((len = fr.read(chars)) != -1) {
			// 写出数据
			fw.write(chars, 0, len);
		}
		// 关闭流
		fw.close();
		fr.close();
	}

	// 方法三:使用缓冲区字符流一次一个字符复制文件
	public static void method3() throws IOException {
		// 创建流对象
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		// 读取数据
		int c;
		while ((c = br.read()) != -1) {
			// 写出数据
			bw.write(c);
		}
		// 关闭流
		bw.close();
		br.close();
	}

	// 方法四:使用缓冲区字符流一次一个字符数组复制文件
	public static void method4() throws IOException {
		// 创建流对象
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		// 读取数据
		int len;
		char[] chars = new char[1024];
		while ((len = br.read(chars)) != -1) {
			// 写出数据
			bw.write(chars, 0, len);
		}
		// 关闭流
		bw.close();
		br.close();
	}

	// 方法五:使用缓冲区字符流一次一行复制文件
	public static void method5() throws IOException {
		// 创建流对象
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		// 读取数据
		String line;
		while ((line = br.readLine()) != null) {
			// 写出数据
			bw.write(line);
			//换行
			bw.newLine();
		}
		// 关闭流
		bw.close();
		br.close();
	}

}
</strong></span>



4.IO流小结

A:字节流
a:字节输入流
InputStream
int read():一次读取一个字节
int read(byte[] bys):一次读取一个字节数组

子类:FileInputStream
子类:BufferedInputStream
b:字节输出流
OutputStream
void write(int by):一次写一个字节
void write(byte[] bys,int index,int len):一次写一个字节数组的

子类:FileOutputStream
子类:BufferedOutputStream
B:字符流
a:字符输入流
Reader
int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组

子类:InputStreamReader
|--FileReader
子类:BufferedReader
String readLine():一次读取一个字符串
b:字符输出流
Writer
void write(int ch):一次写一个字符
void write(char[] chs,int index,int len):一次写一个字符数组

子类:OutputStreamWriter
|--FileWriter
子类:BufferedWriter
void newLine():换行操作
void write(String line):一次写一个字符串(一行)


5.案例


A:把集合中的数据存储到文本文件

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Test {

	/**
	 * 把集合中的数据存储到文本文件
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//创建字符输出流
		BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
		//创建集合对象
		ArrayList<String> al = new ArrayList<String>();
		//向集合中添加元素
		al.add("奔跑吧兄弟");
		al.add("欢乐喜剧人");
		al.add("极限挑战");
		al.add("极速前进");
		
		//遍历集合
		for (String string : al) {
			//写入文件中
			bw.write(string);
			//换行
			bw.newLine();
		}
		
		//关闭流
		bw.close();
	}

}
</strong></span>


B:把文本文件中的数据读取到集合并遍历集合

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class Test2 {

	/**
	 * 把文本文件中的数据读取到集合并遍历集合
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		
		//创建字符输出流
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		//创建集合
		ArrayList<String> al = new ArrayList<String>();
		
		//读取数据
		String line;
		while ((line= br.readLine())!=null) {
			al.add(line);
		}
		
		//遍历集合
		for (String string : al) {
			System.out.println(string);
		}
		
		//关闭流
		br.close();
	}

}
</strong></span>


C:复制单级文件夹

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test3 {

	/**
	 * 复制单级文件夹
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		
		//创建两个文件夹对象
		File srcDir= new File("a");
		File destDir = new File("b");
		//调用方法复制单级文件
		copyFile(srcDir,destDir);
	}
	
	public static void copyFile(File srcDir,File destDir) throws IOException{
		//首先判断目标文件夹是否存在
		if(!destDir.exists()){
			destDir.mkdirs();
		}
		//将源文件对象转化为文件对象数组
		File[] listFiles = srcDir.listFiles();
		//遍历文件对象数组,进行复制
		for (File file : listFiles) {
			//获取源文件和目标文件
			File srcFile = file;
			File destFile = new File(destDir, srcFile.getName());
			
			//创建流对象
			FileInputStream fis = new FileInputStream(srcFile);
			FileOutputStream fos = new FileOutputStream(destFile);
			
			//读取文件数据
			int b;
			while ((b=fis.read())!=-1) {
				//写入文件数据
				fos.write(b);
			}
			//关闭流
			fos.close();
			fis.close();
		}
		
	}

}
</strong></span>


D:复制多级文件夹

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test4 {

	/**
	 * 复制多级文件夹
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		//创建文件对象
		File srcDirs = new File("a");
		File destDirs = new File("c");
		
		//调用方法复制多级文件夹
		copyDirs(srcDirs,destDirs);
	}
	//定义复制文件夹方法copyDirs
	public static void copyDirs(File srcDirs,File destDirs) throws IOException{
		
		if (srcDirs.isDirectory()) {
			//首先创建目标文件
			File newForld = new File(destDirs,srcDirs.getName());
			newForld.mkdirs();
			//将源文件文件对象转成文件对象数组
			File[] files = srcDirs.listFiles();
			//遍历files
			for (File file : files) {
			
				copyDirs(file,newForld);
			}
		}else{
			File srcFile = srcDirs;
			File destFile = new File(destDirs,srcFile.getName());
			copyFile(srcFile,destFile);
		}
		
		
	}
	
	//定义复制文件方法copyFile
	public static void copyFile(File srcFile,File destFile) throws IOException{
		//创建流对象
		BufferedReader  br = new BufferedReader(new FileReader(srcFile));
		BufferedWriter bw = new BufferedWriter(new FileWriter(destFile));
		//复制文件
		//读取数据
		int len;
		char[] chars = new char[1024];
		while ((len= br.read(chars))!=-1) {
			//写入数据
			bw.write(chars, 0, len);
		}
		
		//关闭流
		bw.close();
		br.close();
		
		
	}
	
	

}
</strong></span>


E:用Reader模拟BufferedReader的特有功能

<span style="font-family:FangSong_GB2312;font-size:18px;"><strong>package cn.bolg;

import java.io.IOException;
import java.io.Reader;

/**
 * 用Reader模拟BufferedReader的特有功能
 */
public class Test5 {
	//将Reader作为成员变量进行使用
	private Reader reader;
	//有参构造方法
	public Test5(Reader reader) {
		super();
		this.reader = reader;
	}
	//定义一次读取一行的方法
	public String myReadLine() throws IOException{
		//使用字符串缓冲区接收读到的数据
		StringBuilder sb = new StringBuilder();
		//使用一次读取一个字符的方式
		int c;
		while ((c=reader.read())!=-1) {
			//当字符读出来的是\r时,使用continue语句跳出不做添加
			if (c=='\r') {
				continue;
			}
			//当读到\n时,一行读取完毕,返回字符串缓冲区
			if(c=='\n'){
				return sb.toString();
			}
			//将读取到的内容存到缓冲区中
			sb.append(c);
		}
		//如果最后一行数据没有\r\n,但是有内容,使用缓冲区长度进行判断,不等于0就返回
		if (sb.length()!=0) {
			return sb.toString();
		}
		//最后没有内容就返回null
		return null;
		
	}
	//定义关闭流的方法
	public void close() throws IOException{
		reader.close();
	}
	
	
}
</strong></span>



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值