一、使用字节流实现
复制文件中的地址可以是图片或视频。
1.基础版:
package com.uwo9.test01;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// 被复制的文件
File fromFile = new File("E:/Temp/1.jpg");
// 复制出来的文件
File toFile = new File("E:/Temp/2.jpg");
// 声明入流
InputStream is = null;
//
OutputStream os=null;
try {
is = new FileInputStream(fromFile);//创建输入流
os = new FileOutputStream(toFile);// 创建输出流
// 逐个字节读取
int content = is.read();
while (content != -1) {
// System.out.print((char)content); 控制台
// 使用输出流将读取到的content写入文件
os.write(content);
// 刷新流
// os.flush();
content = is.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
// 关闭流
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
System.out.println("复制文件完成,耗时:" + costTime + "毫秒");
}
}
}
发现问题:我们发现,上面的方法,可以实现复制功能,但复制的文件比较大时,复制比较慢
2.第一次优化:
我们可以用字节数组来做缓冲区,提升效率。
package com.uwo9.test01;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// 被复制的文件
File fromFile = new File("E:/Temp/1.avi");
// 复制出来的文件
File toFile = new File("E:/Temp/2.avi");
// 声明入流
InputStream is = null;
//
OutputStream os = null;
try {
is = new FileInputStream(fromFile);// 创建输入流
os = new FileOutputStream(toFile);// 创建输出流
// 创建用来做缓冲区的字节数组
byte[] array = new byte[512];
// 将数组读取到array中,count记录的为读取数组中字节数
int count = is.read(array);
while (count != -1) {
// 使用输出流将读取到的content写入文件
// os.write(array);
// 将读取到的有效数据写入文件
os.write(array, 0, count);
// 刷新流
// os.flush();
count = is.read(array);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭流
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
System.out.println("复制文件完成,耗时:" + costTime + "毫秒");
}
}
}
发现问题:效率提升了,但我们java里是否有更好的实现方法呢
3.第二次优化:
我们可以加入缓冲字符流
节点流与处理流(包装流):
1.节点流:可以直接从数据源或目的地读写数据。节点流处于IO操作的第一线,所有操作必须通过他们进行。
2.处理流:不能直接连接到数据源或目的地,是其他流进行封装。目的是主要是简化操作和提高性能。处理流可以对其他流进行处理(提高效率或操作灵活性)。
package com.uwo9.test01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
File fromFile = new File("E:/Temp/1.avi");
File toFile = new File("E:/Temp/2.avi");
InputStream is = null;
OutputStream os = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
is = new FileInputStream(fromFile);
os = new FileOutputStream(toFile);
// 创建缓冲流
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(os);
int content = bis.read();
while (content != -1) {
// 使用缓冲流写数据
bos.write(content);
// 刷新
bos.flush();
content = bis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("视频复制完成,耗时:" + (endTime - startTime) + "毫秒");
}
}
发现问题:我们还想继续提升效率
4.第三次优化:
我们可以在缓冲流的基础上再加字节数组来做缓冲区,提升效率
package com.uwo9.test01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
File fromFile = new File("E:/Temp/1.avi");
File toFile = new File("E:/Temp/2.avi");
InputStream is = null;
OutputStream os = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
is = new FileInputStream(fromFile);
os = new FileOutputStream(toFile);
// 创建缓冲流
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(os);
byte[]buffer = new byte[8192];
int count = bis.read(buffer);
while(count != -1){
//使用缓冲流写数据
bos.write(buffer,0,count);
//刷新
bos.flush();
count = bis.read(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("视频复制完成,耗时:" + (endTime - startTime) + "毫秒");
}
}
我们会发现,效率再次大大提升。
二、使用字符流
1.基础版
package com.uwo9.test01;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
//1.创建文件对象
File fromFile = new File("E:/Temp/Test1.java");
File toFile = new File("E:/Temp/Test2.java");
//2.创建字符输入流
Reader reader=null;
Writer writer=null;
try {
reader = new FileReader(fromFile);
writer = new FileWriter(toFile);
//3.循环读取(打印)
int content = reader.read();
while(content != -1){
//将字符写入文件
writer.write(content);
//继续读取
content = reader.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4.关闭流
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("复制完成,耗时:"+(endTime-startTime)+"毫秒");
}
}
发现问题:我们发现,字符流复制二进制普通文本类型的文件没问题,但读取图片、视频文件时,会出现丢帧、文件损坏现象。
2.优化普通二进制文本文件方法
我们可以使用包装流(处理流),及其特有的逐行读取方法提升效率
package com.uwo9.test01;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Test08 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
File fromFile = new File("E:/Temp/Test1.java");
File toFile = new File("E:/Temp/Test1.java");
Reader reader = null;
Writer writer = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
reader = new FileReader(fromFile);
writer = new FileWriter(toFile);
br = new BufferedReader(reader);
bw = new BufferedWriter(writer);
String content = br.readLine();//读取一行
while (content != null) {
bw.write(content);
// 换行操作
bw.newLine();
bw.flush();
content = br.readLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("文件复制完成,耗时:" + (endTime - startTime) + "毫秒");
}
}
FileWriter(File file, boolean append)
FileOutputStream(File file, boolean append)