1. IO流分类
- 根据数据的流向分为输入流和输出流。
- 根据数据的单位分为字节流和字符流。
- 根据数据的角色分为节点流和处理流。
2. 使用字节流实现文件复制
字节流可以对文本文件和非文本文件进行处理,但使用字节流读取字符在控制台打印出来可能会造成乱码。
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
File file = new File("d:\\hi.txt");
File file1 = new File("d:\\hi1.txt");
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(file1);
byte[] buf = new byte[1024];
int len;
while ((len = fileInputStream.read(buf)) != -1){
fileOutputStream.write(buf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 使用缓冲流提升效率
缓冲流就是在内存开辟一片缓冲区,把读取的数据缓存起来,等缓存满了再把数据写到文件中,减少磁盘IO的次数,提高效率。
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
File file = new File("d:\\001.png");
File file1 = new File("d:\\002.png");
//节点流
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file1);
//处理流
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//读取并写入文件
byte[] buf = new byte[1024*1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
}
System.out.println("文件复制成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭流资源
if (bufferedInputStream != null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 封装文件复制类
把复制文件的操作封装成copy函数,复制文件夹的操作封装成copyDir函数,提高功能的复用性。
import java.io.*;
public class CopyFile {
private int dirCount = 0;
private int fileCount = 0;
public int getDirCount() {
return dirCount;
}
public int getFileCount() {
return fileCount;
}
//复制文件
public void copy(String srcPath, String desPath){
File srcFile = new File(srcPath);
File desFile = new File(desPath);
//输入输出流
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
FileInputStream fileInputStream = new FileInputStream(srcFile);
FileOutputStream fileOutputStream = new FileOutputStream(desFile);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//读取内容并写入新文件
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
}
System.out.println(srcFile.getName()+"成功复制到"+desFile.getParent());
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流资源
if (bufferedInputStream != null) {
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//复制文件夹
public void copyDir(String srcPath,String desPath){
File file = new File(srcPath);
File desFile = new File(desPath);
if (file.isDirectory()) {
desFile.mkdir();
File[] files = file.listFiles();
for (File f : files) {
if (f.isDirectory())
{
dirCount++;
copyDir(srcPath+File.separator+f.getName(),desPath+File.separator+f.getName());
}
else{
fileCount++;
copy(srcPath+File.separator+f.getName(),desPath+File.separator+f.getName());
}
}
}
}
}
4.1 测试CopyFile类
测试复制文件夹功能。
CopyFile copyFile = new CopyFile();
copyFile.copyDir("d:\\test1","d:\\test2");
System.out.println("总共:"+copyFile.getDirCount()+"个文件夹,"+copyFile.getFileCount()+"个文件");
5. 总结
字符流只能来处理文本文件,字节流可以处理非文本文件和文本文件,但是不能很好读取文本文件。