首页 > 代码库 > javaSE第二十天

javaSE第二十天

第二十天????254

1:递归(理解)????254

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

(2)递归的注意事项????255

(3)递归的案例:????255

A:递归求阶乘????255

B:兔子问题????256

C:递归输出指定目录下所有指定后缀名的文件绝对路径????258

D:递归删除带内容的目录(小心使用)????259

2:IO流(掌握)????260

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

(2)分类:????260

(3)代码体现????261

A:IO的分类????261

B:创建字节输出流的步骤及相关方法????263

C:如何实现数据的换行????264

D: 加入异常处理的字节输出流操作????264

(4)FileOutputStream写出数据????266

A:构造方法以及常用方法????266

B:操作步骤????266

C:代码体现:????266

D:要注意的问题?????267

a:创建字节输出流对象做了几件事情?????267

b:为什么要close()?????267

c:如何实现数据的换行?????267

d:如何实现数据的追加写入?????267

(5)FileInputStream读取数据????267

A:操作步骤????267

B:FileInputStream 读取数据的两种方式比较图解????267

C:代码体现:????267

(6)案例:2种实现????269

A:复制文本文件????269

B:复制图片????270

C:复制视频????270

(7)字节缓冲区流????271

A:BufferedOutputStream(OutputStream out)????271

B:BufferedInputStream(InputStream in)????272

(8)案例:4种实现????273

A:复制文本文件????273

B:复制图片????273

C:复制视频????273

3:自学字符流????275

?

?

第二十天

1:递归(理解)
????(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:构造方法不能递归使用

*

* 举例:

* ????????A:从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:

* ????????????从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:

* ????????????????从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:

* ????????????????????从前有座山,山里有座庙,庙里有个老和尚和小和尚,老和尚在给小和尚讲故事,故事是:

* ????????????????????????...

* ????????????????????庙挂了,或者山崩了

* ????????B:学编程 -- 高薪就业 -- 挣钱 -- 娶媳妇 -- 生娃娃 -- 放羊 -- 挣学费

* ???????????? 学编程 -- 高薪就业 -- 挣钱 -- 娶媳妇 -- 生娃娃 -- 放羊 -- 挣学费

* ????????????????学编程 -- 高薪就业 -- 挣钱 -- 娶媳妇 -- 生娃娃 -- 放羊 -- 挣学费

* ????????????????????学编程 -- 高薪就业 -- 挣钱 -- 娶媳妇 -- 生娃娃 -- 放羊 -- 挣学费

* ????????????????????????...

* ????????????????????娶不到媳妇或者生不了娃娃????

*/

?

????(2)递归的注意事项

????????A:要有出口,否则就是死递归

????????B:次数不能过多,否则内存溢出

????????C:构造方法不能递归使用

????(3)递归的案例:

????????A:递归求阶乘

/*

* 需求:请用代码实现求5的阶乘。

* 下面的知识要知道:

* ????????5! = 1*2*3*4*5

* ????????5! = 5*4!

*

* 有几种方案实现呢?

* ????????A:循环实现

* ????????B:递归实现

* ????????????a:做递归要写一个方法

* ????????????b:出口条件

* ????????????c:规律

*/

class DiGuiDemo {

????public?static?void main(String[] args) {

????????int?jc = 1;

????????for (int?x = 2; x <= 5; x++) {

????????????jc *= x;

????????}

????????System.out.println("5的阶乘是:" + jc);

????????

????????System.out.println("5的阶乘是:"+jieCheng(5));

????}

????

????/*

???? * 做递归要写一个方法:

???? * ????????返回值类型:int

???? * ????????参数列表:int n

???? * 出口条件:

???? * ????????if(n == 1) {return 1;}

???? * 规律:

???? * ????????if(n != 1) {return n*方法名(n-1);}

???? */

????public?static?int jieCheng(int?n){

????????if(n==1){

????????????return 1;

????????}else {

????????????return?n*jieCheng(n-1);

????????}

????}

}

?

????????B:兔子问题

/*

* 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?

* 分析:我们要想办法找规律

* ????????????兔子对数

* 第一个月: ????1

* 第二个月:????1

* 第三个月:????2

* 第四个月:????3????

* 第五个月:????5

* 第六个月:????8

* ...

*

* 由此可见兔子对象的数据是:

* ????????1,1,2,3,5,8...

* 规则:

* ????????A:从第三项开始,每一项是前两项之和

* ????????B:而且说明前两项是已知的

*

* 如何实现这个程序呢?

* ????????A:数组实现

* ????????B:变量的变化实现

* ????????C:递归实现

*

* 假如相邻的两个月的兔子对数是a,b

* 第一个相邻的数据:a=1,b=1

* 第二个相邻的数据:a=1,b=2

* 第三个相邻的数据:a=2,b=3

* 第四个相邻的数据:a=3,b=5

* 看到了:下一次的a是以前的b,下一次是以前的a+b????

*/

class DiGuiDemo2 {

????public?static?void main(String[] args) {

????????// 方法1:数组实现

????????diGui1();

????????//方法2:用变量的变化实现

????????diGui2();

?

????????//方法3:用递归实现

????????System.out.println(fib(20));

????}

????//方法2:用变量的变化实现

????public?static?void diGui2() {

????????int?a = 1;

????????int?b = 1;

????????for (int?x = 0; x < 18; x++) {

????????????// 临时变量存储上一次的a

????????????int?temp = a;

????????????a = b;

????????????b = temp + b;

????????}

????????System.out.println(b);

????????System.out.println("----------------");

????}

?

????//方法1:用数组实现

????public?static?void diGui1() {

????????// 定义一个数组

????????int[] arr = new?int[20];

????????arr[0] = 1;

????????arr[1] = 1;

????????// arr[2] = arr[0] + arr[1];

????????// arr[3] = arr[1] + arr[2];

????????// ...

????????for (int?x = 2; x < arr.length; x++) {

????????????arr[x] = arr[x - 2] + arr[x - 1];

????????}

????????System.out.println(arr[19]);// 6765

????????System.out.println("----------------");

????}

?

????/*

???? * 方法: 返回值类型:int?

???? * ???? 参数列表:int n

???? * ???? 出口条件: 第一个月是1,第二个月是1

???? * ???? 规律: 从第三个月开始,每一个月是前两个月之和

???? */

????//方法3:用递归实现

????public?static?int fib(int?n) {

????????if (n == 1 || n == 2) {

????????????return 1;

????????} else {

????????????return?fib(n - 1) + fib(n - 2);

????????}

????}

}

?

????????C:递归输出指定目录下所有指定后缀名的文件绝对路径

import java.io.File;

?

/*

* 需求:请大家把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。

*

* 分析:

* ????????A:封装目录

* ????????B:获取该目录下所有的文件或者文件夹的File数组

* ????????C:遍历该File数组,得到每一个File对象

* ????????D:判断该File对象是否是文件夹

* ????????????是:回到B

* ????????????否:继续判断是否以.java结尾

* ????????????????是:就输出该文件的绝对路径

* ????????????????否:不搭理它

*/

class FilePathDemo {

????public?static?void main(String[] args) {

????????// 封装目录

????????File srcFolder = new File("E:\\JavaSE");

?

????????// 递归功能实现

????????getAllJavaFilePaths(srcFolder);

????}

?

????private?static?void getAllJavaFilePaths(File srcFolder) {

????????// 获取该目录下所有的文件或者文件夹的File数组

????????File[] fileArray = srcFolder.listFiles();

?

????????// 遍历该File数组,得到每一个File对象

????????for (File file : fileArray) {

????????????// 判断该File对象是否是文件夹

????????????if (file.isDirectory()) {

????????????????getAllJavaFilePaths(file);

????????????} else {

????????????????// 继续判断是否以.java结尾

????????????????if (file.getName().endsWith(".java")) {

????????????????????// 就输出该文件的绝对路径

????????????????????System.out.println(file.getAbsolutePath());

????????????????}

????????????}

????????}

????}

}

?

????????D:递归删除带内容的目录(小心使用)

import java.io.File;

?

/*

* 需求:递归删除带内容的目录

* 说明:如果需要删除文件夹,那就需要在删除文件夹之前删除该文件夹里面的所有文件,才允许删除文件夹

* 目录我已经给定:demo

*

* 分析:

* ????????A:封装目录

* ????????B:获取该目录下的所有文件或者文件夹的File数组

* ????????C:遍历该File数组,得到每一个File对象

* ????????D:判断该File对象是否是文件夹

* ????????????是:回到B

* ????????????否:就删除

*/

class FileDeleteDemo {

????public?static?void main(String[] args) {

????????// 封装目录

????????File srcFolder = new File("demo");

????????// 递归实现

????????deleteFolder(srcFolder);

????}

?

????private?static?void deleteFolder(File srcFolder) {

????????// 获取该目录下的所有文件或者文件夹的File数组

????????File[] fileArray = srcFolder.listFiles();

?

????????if (fileArray != null) {

????????????// 遍历该File数组,得到每一个File对象

????????????for (File file : fileArray) {

????????????????// 判断该File对象是否是文件夹

????????????????if (file.isDirectory()) {

????????????????????deleteFolder(file);

????????????????} else {

????????????????????// 这一步,仅仅是删除所有文件夹下的所有文件,而不是文件夹

????????????????????System.out.println(file.getName() + "---" + file.delete());

????????????????}

????????????}

????????????//而这一步:是在删除了所有文件夹下的所有文件之后,再来删除所有的空文件夹的

????????????System.out.println(srcFolder.getName() + "---" + srcFolder.delete());

????????}

????}

}

?

2:IO流(掌握)
????(1)IO用于在设备间进行数据传输的操作????
????(2)分类:

????????A:流向

????????????输入流????读取数据

????????????输出流????写出数据

????????B:数据类型

????????????字节流????

????????????????????字节输入流 InputStream

????????????????????字节输出流 OutputStream

????????????字符流

????????????????????字符输入流 Reader

????????????????????字符输出流 Writer

????????注意:

????????????a:如果我们没有明确说明按照什么分,默认按照数据类型分。

????????????b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。

?

????(3)代码体现

????????A:IO的分类

????????

import?java.io.File;

import?java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* IO流的分类:

* ????????流向:

* ????????????输入流????读取数据

* ????????????输出流 写出数据

* ????????数据类型:

* ????????????字节流

* ????????????????字节输入流????读取数据????InputStream

* ????????????????字节输出流????写出数据????OutputStream

* ????????????字符流

* ????????????????字符输入流????读取数据????Reader

* ????????????????字符输出流????写出数据????Writer

*

* ????????注意:一般我们在探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。

*

* 需求:我要往一个文本文件中输入一句话:"hello,io"

*

* 分析:

* ????????A:这个操作最好是采用字符流来做,但是呢,字符流是在字节流之后才出现的,所以,今天我先讲解字节流如何操作。

* ????????B:由于我是要往文件中写一句话,所以我们要采用字节输出流。

*

* 通过上面的分析后我们知道要使用:OutputStream

* 但是通过查看API,我们发现该流对象是一个抽象类,不能实例化。

* 所以,我们要找一个具体的子类。

* 而我们要找的子类是什么名字的呢?这个时候,很简单,我们回想一下,我们是不是要往文件中写东西。

* 文件是哪个单词:File

* 然后用的是字节输出流,联起来就是:FileOutputStream

* 注意:每种基类的子类都是以父类名作为后缀名。

* ????????XxxOutputStream

* ????????XxxInputStream

* ????????XxxReader

* ????????XxxWriter

* 查看FileOutputStream的构造方法:

* ????????FileOutputStream(File file)

*????????FileOutputStream(String name)

*

* 字节输出流操作步骤:

* ????????A:创建字节输出流对象

* ????????B:写数据

* ????????C:释放资源

*/

class FileOutputStreamDemo {

????public?static?void main(String[] args) throws IOException {

????????// 创建字节输出流对象

????????// 方法一:FileOutputStream(File file)

????????//File file = new File("Filefile.txt");

????????//FileOutputStream fos = new FileOutputStream(file);

????????

????????//方法二: FileOutputStream(String name)????????

????????FileOutputStream fos = new FileOutputStream("Stringname.txt");

????????/*

???????? * 创建字节输出流对象了做了几件事情:

???????? * A:调用系统功能去创建文件

???????? * B:创建fos对象

???????? * C:fos对象指向这个文件

???????? */

????????

????????//写数据

????????fos.write("hello,IO".getBytes());

????????fos.write("java".getBytes());

????????

????????//释放资源

????????//关闭此文件输出流并释放与此流有关的所有系统资源。

????????fos.close();

????????/*

???????? * 为什么一定要close()?

???????? * A:让流对象变成垃圾,这样就可以被垃圾回收器回收了

???????? * B:通知系统去释放跟该文件相关的资源

???????? */

????????//java.io.IOException: Stream Closed

????????//fos.write("java".getBytes());

????}

}

????????B:创建字节输出流的步骤及相关方法

?

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 字节输出流操作步骤:

* A:创建字节输出流对象

* B:调用write()方法

* C:释放资源

*

* public void write(int b):写一个字节

* public void write(byte[] b):写一个字节数组

* public void write(byte[] b,int off,int?len):写一个字节数组的一部分

*/

class FileOutputStreamDemo2 {

????public?static?void main(String[] args) throws IOException {

????????// 创建字节输出流对象

????????// OutputStream os = new FileOutputStream("fos2.txt"); // 多态

????????FileOutputStream fos = new FileOutputStream("fos2.txt");

?

????????// 调用write()方法

????????//fos.write(97); //97 -- 底层二进制数据????-- 通过记事本打开 -- 97对应的字符值 -- a

????????// fos.write(57);

????????// fos.write(55);

????????

????????//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);

????????

????????//释放资源

????????fos.close();

????}

}

????????C:如何实现数据的换行

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 如何实现数据的换行?

* ????????为什么现在没有换行呢?因为你值写了字节数据,并没有写入换行符号。

* ????????如何实现呢?写入换行符号即可呗。

* ????????刚才我们看到了有写文本文件打开是可以的,通过windows自带的那个不行,为什么呢?

* ????????因为不同的系统针对不同的换行符号识别是不一样的?

* ????????windows:\r\n

* ????????linux:\n

* ????????Mac:\r

* ????????而一些常见的个高级记事本,是可以识别任意换行符号的。

*

* 如何实现数据的追加写入?

* ????????用构造方法带第二个参数是true的情况即可

*/

class FileOutputStreamDemo3 {

????public?static?void main(String[] args) throws IOException {

????????// 创建字节输出流对象

????????// FileOutputStream fos = new FileOutputStream("fos3.txt");

????????// 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。

????????FileOutputStream fos = new FileOutputStream("fos3.txt", true);

?

????????// 写数据

????????for (int?x = 0; x < 10; x++) {

????????????fos.write(("hello" + x).getBytes());

????????????fos.write("\r\n".getBytes());

????????}

?

????????// 释放资源

????????fos.close();

????}

}

?

????????D: 加入异常处理的字节输出流操作

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

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

*/

class FileOutputStreamDemo4 {

????public?static?void main(String[] args) {

????????// 分开做异常处理

????????// FileOutputStream fos = null;

????????// try {

????????// fos = new FileOutputStream("fos4.txt");

????????// } catch (FileNotFoundException e) {

????????// e.printStackTrace();

????????// }

????????//

????????// try {

????????// fos.write("java".getBytes());

????????// } catch (IOException e) {

????????// e.printStackTrace();

????????// }

????????//

????????// try {

????????// fos.close();

????????// } catch (IOException e) {

????????// 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("z:\\fos4.txt");

????????????fos = new FileOutputStream("fos4.txt");

????????????fos.write("java".getBytes());

????????} catch (FileNotFoundException e) {

????????????e.printStackTrace();

????????} catch (IOException e) {

????????????e.printStackTrace();

????????} finally {

????????????// 如果fos不是null,才需要close()

????????????if (fos != null) {

????????????????// 为了保证close()一定会执行,就放到这里了

????????????????try {

????????????????????fos.close();

????????????????} catch (IOException e) {

????????????????????e.printStackTrace();

????????????????}

????????????}

????????}

????}

}

?

????????

?

????(4)FileOutputStream写出数据

????????A:构造方法以及常用方法

????????????public FileOutputStream(File file)????????

????????????public FileOutputStream(String name)????

????????????

public void write(byte b[], int off, int len):一次写一个字节数组的一部分

public void write(byte b[])一次写一个字节数组

public void write(int b)一次写一个字节

????????B:操作步骤

????????????a:创建字节输出流对象

????????????b:调用write()方法

????????????c:释放资源

????????????

????????C:代码体现:

????????????FileOutputStream fos = new FileOutputStream("fos.txt");

????????????

????????????fos.write("hello".getBytes());

????????????

????????????fos.close();

????????????

????????D:要注意的问题?

????????????a:创建字节输出流对象做了几件事情?

????????????????1.调用系统功能去创建文件

????????????????2.创建FileOutputStream 流对象

????????????????3.FileOutputStream流对象指向该文件

????????????b:为什么要close()?

????????????????1.让流对象变成垃圾,这样就可以被垃圾回收器给回收啦

????????????????2.通知系统去释放与该文件相关的资源

????????????c:如何实现数据的换行?

????????????????答:说明:不同的系统针对不同的换行符的识别是不一样的

????????????????????Windows\r\n

????????????????????Linux : \n

????????????????????Mac : \r

????????????????????而一些常见的高级记事本,是可以识别任意换行符的。

????????????d:如何实现数据的追加写入?

????????????????答:用构造方法带第二个参数是true的情况即可

????????????????????即FileOutputStream fos = new FileOutputStream("a.txt", true);

????(5)FileInputStream读取数据

????????A:操作步骤

????????????a:创建字节输入流对象

????????????b:调用read()方法

????????????c:释放资源

????????????

????????常用方法

????????public int read():一次读取一个字节

????????public int read(byte b[]):一次读取一个字节数组

????????B:FileInputStream 读取数据的两种方式比较图解

技术分享

????????C:代码体现:

????????????

import java.io.FileInputStream;

import java.io.IOException;

?

/*

* 字节输入流操作步骤:

* A:创建字节输入流对象

* B:调用read()方法读取数据,并把数据显示在控制台

* C:释放资源

*

* 读取数据的方式:

* A:int read():一次读取一个字节

* B:int read(byte[] b):一次读取一个字节数组

* 返回值其实是实际读取的字节个数

*/

class FileInputStreamDemo {

????public?static?void main(String[] args) throws IOException {

????????// FileInputStream(String name)

????????// FileInputStream fis = new FileInputStream("fis.txt");

????????FileInputStream fis = new FileInputStream("FileOutputStreamDemo.java");

?

????????// 方式1:一次读取一个字节

????????int?by = 0;

????????// 读取,赋值,判断

????????while ((by = fis.read()) != -1) {

????????????System.out.print((char) by);

????????}

????????

????????//方式2:一次读取一个字节数组

????????byte[] b = new?byte[1024];

????????int?len = 0;

????????while((len = fis.read(b)) != -1) {

????????????System.out.print(new String(b, 0, len));

????????}

????????// 释放资源

????????fis.close();

????}

}

?

????(6)案例:2种实现

????????A:复制文本文件

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 需求:把c盘下的a.txt的内容复制到d盘下的b.txt

*

* 数据源:

* ????????c:\\a.txt????--????读取数据--????FileInputStream

* 目的地:

* ????????d:\\b.txt????--????写出数据????--????FileOutputStream

*/

public?class CopyFileDemo2 {

????public?static?void main(String[] args) throws IOException {

????????// 封装数据源

????????FileInputStream fis = new FileInputStream("a.txt");

????????// 封装目的地

????????FileOutputStream fos = new FileOutputStream("b.txt");

?

?????

????????//方式1:一次读取一个字节

????????// 复制数据

????????int?by = 0;

????????while ((by = fis.read()) != -1) {

????????????fos.write(by);

????????}

?

????????//方式2:一次读取一个字节数组

????????byte[] by1 = new?byte[1024];

????????int?len = 0;

????????while ((len = fis.read(by1)) != -1) {

????????????fos.write(by1, 0, len);

????????}

????????// 释放资源

????????fos.close();

????????fis.close();

????}

}

?

????????B:复制图片

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 需求:把e:\\林青霞.jpg内容复制到当前项目目录下的mn.jpg

*

* 数据源:

* ????????e:\\林青霞.jpg????--读取数据--FileInputStream

* 目的地:

* ????????mn.jpg--写出数据--FileOutputStream

*/

public?class CopyImageDemo {

????public?static?void main(String[] args) throws IOException {

????????// 封装数据源

????????FileInputStream fis = new FileInputStream("e:\\林青霞.jpg");

????????// 封装目的地

????????FileOutputStream fos = new FileOutputStream("mn.jpg");

?

????????// 方式1:一次读取一个字节

????????int?by = 0;

????????while ((by = fis.read()) != -1) {

????????????fos.write(by);

????????}

????????

????????//方式2:一次读取一个字节数组

????????byte[] by2 = new?byte[1024];

????????int?len = 0;

????????while((len = fis.read(by2)) != -1) {

????????????fos.write(by2, 0, len);

????????}

?

????????// 释放资源

????????fos.close();

????????fis.close();

????}

}

?

????????C:复制视频

????????

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 需求:把e:\\哥有老婆.mp4复制到当前项目目录下的copy.mp4

*

* 数据源:

* ????????e:\\哥有老婆.mp4--读取数据--FileInputStream

* 目的地:

* ????????copy.mp4--写出数据--FileOutputStream

*/

public?class CopyMp4Demo {

????public?static?void main(String[] args) throws IOException {

????????// 封装数据源

????????FileInputStream fis = new FileInputStream("e:\\哥有老婆.mp4");

????????// 封装目的地

????????FileOutputStream fos = new FileOutputStream("copy.mp4");

?

????????// 方式1:一次读取一个字节

????????int?by = 0;

????????while ((by = fis.read()) != -1) {

????????????fos.write(by);

????????}

????????

????????//方式2:一次读取一个字节数组

????????byte[] by2 = new?byte[1024];

????????int?len = 0;

????????while((len = fis.read(by2)) != -1) {

????????????fos.write(by2, 0, len);

????????}

????????// 释放资源

????????fos.close();

????????fis.close();

????}

}

?

????(7)字节缓冲区流

????????A:BufferedOutputStream(OutputStream out)

import java.io.BufferedOutputStream;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 通过定义数组的方式确实比以前一次读取一个字节的方式快很多,所以,看来有一个缓冲区还是非常好的。

* 既然是这样的话,那么,java开始在设计的时候,它也考虑到了这个问题,就专门提供了带缓冲区的字节类。

* 这种类被称为:缓冲区类(高效类)

* 写数据:BufferedOutputStream

* 读数据:BufferedInputStream

*

* 构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了。

*

* 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?

* 原因很简单,字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本的流对象实现。

*/

class BufferedOutputStreamDemo {

????public?static?void main(String[] args) throws IOException {

????????// BufferedOutputStream(OutputStream out)

????????// FileOutputStream fos = new FileOutputStream("bos.txt");

????????// BufferedOutputStream bos = new BufferedOutputStream(fos);

????????// 简单写法

????????BufferedOutputStream bos = new BufferedOutputStream(

????????????????new FileOutputStream("bos.txt"));

?

????????// 写数据

????????bos.write("hello".getBytes());

?

????????// 释放资源

????????bos.close();

????}

}

?

????????B:BufferedInputStream(InputStream in)

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.IOException;

?

/*

* 注意:虽然我们有两种方式可以读取,但是,请注意,这两种方式针对同一个对象在一个代码中只能使用一个。

*/

class BufferedInputStreamDemo {

????public?static?void main(String[] args) throws IOException {

????????// BufferedInputStream(InputStream in)

????????BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

????????????????"bos.txt"));

?

????????// 读取数据

????????// int by = 0;

????????// while ((by = bis.read()) != -1) {

????????// System.out.print((char) by);

????????// }

????????// System.out.println("---------");

?

????????byte[] bys = new?byte[1024];

????????int?len = 0;

????????while ((len = bis.read(bys)) != -1) {

????????????System.out.print(new String(bys, 0, len));

????????}

?

????????// 释放资源

????????bis.close();

????}

}

?

????(8)案例:4种实现

????????A:复制文本文件

????????B:复制图片

????????C:复制视频

????????????四种方式

????

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

?

/*

* 需求:把e:\\哥有老婆.mp4复制到当前项目目录下的copy.mp4

*

* 字节流四种方式复制文件:

* 基本字节流一次读写一个字节:????共耗时:117235毫秒

* 基本字节流一次读写一个字节数组: 共耗时:156毫秒

* 高效字节流一次读写一个字节: 共耗时:1141毫秒

* 高效字节流一次读写一个字节数组: 共耗时:47毫秒

*/

public?class CopyMp4Demo {

????public?static?void main(String[] args) throws IOException {

????????long?start = System.currentTimeMillis();

????????// method1("e:\\哥有老婆.mp4", "copy1.mp4");

????????// method2("e:\\哥有老婆.mp4", "copy2.mp4");

????????// method3("e:\\哥有老婆.mp4", "copy3.mp4");

????????method4("e:\\哥有老婆.mp4", "copy4.mp4");

????????long?end = System.currentTimeMillis();

????????System.out.println("共耗时:" + (end - start) + "毫秒");

????}

?

????// 高效字节流一次读写一个字节数组:

????public?static?void method4(String srcString, String destString)

????????????throws IOException {

????????BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

????????????????srcString));

????????BufferedOutputStream bos = new BufferedOutputStream(

????????????????new FileOutputStream(destString));

?

????????byte[] bys = new?byte[1024];

????????int?len = 0;

????????while ((len = bis.read(bys)) != -1) {

????????????bos.write(bys, 0, len);

????????}

?

????????bos.close();

????????bis.close();

????}

?

????// 高效字节流一次读写一个字节:

????public?static?void method3(String srcString, String destString)

????????????throws IOException {

????????BufferedInputStream bis = new BufferedInputStream(new FileInputStream(

????????????????srcString));

????????BufferedOutputStream bos = new BufferedOutputStream(

????????????????new FileOutputStream(destString));

?

????????int?by = 0;

????????while ((by = bis.read()) != -1) {

????????????bos.write(by);

?

????????}

?

????????bos.close();

????????bis.close();

????}

?

????// 基本字节流一次读写一个字节数组

????public?static?void method2(String srcString, String destString)

????????????throws IOException {

????????FileInputStream fis = new FileInputStream(srcString);

????????FileOutputStream fos = new FileOutputStream(destString);

?

????????byte[] bys = new?byte[1024];

????????int?len = 0;

????????while ((len = fis.read(bys)) != -1) {

????????????fos.write(bys, 0, len);

????????}

?

????????fos.close();

????????fis.close();

????}

?

????// 基本字节流一次读写一个字节

????public?static?void method1(String srcString, String destString)

????????????throws IOException {

????????FileInputStream fis = new FileInputStream(srcString);

????????FileOutputStream fos = new FileOutputStream(destString);

?

????????int?by = 0;

????????while ((by = fis.read()) != -1) {

????????????fos.write(by);

????????}

?

????????fos.close();

????????fis.close();

????}

}

?

?

?

????????

3:自学字符流

????IO流分类

????????字节流:

????????????InputStream

????????????????FileInputStream

????????????????BufferedInputStream

????????????OutputStream

????????????????FileOutputStream

????????????????BufferedOutputStream

????????

????????字符流:

????????????Reader

????????????????FileReader

????????????????BufferedReader

????????????Writer

????????????????FileWriter

????????????????BufferedWriter

?

?

javaSE第二十天