文件的拷贝是把程序作为中转,读一段内容,然后写入到文件,循环往复。
package IO_Study;
import java.io.*;
/**
* 使用文件字节输入流和输出流进行文件的拷贝
* 1.确定源
* 2.选择流
* 3.操作
* 4.关闭系统资源
* @author 发达的范
* @date 2021/03/21 17:31
*/
public class FileCopy {
public static void main(String[] args) {
//1.确定源
File src = new File("E:/(A)PostgraduateFlies/JavaLearning/javaEE.jpg");//大小为180KB的一张图片
File dest = new File("E:/(A)PostgraduateFlies/CopyjavaEE.jpg");//必须指定位置和文件名
//2.选择流
InputStream is = null;
OutputStream os = null;
try {
//2.选择流
is = new FileInputStream(src);
os = new FileOutputStream(dest);
byte[] flush = new byte[1024];//每次读取1024字节byte,就是1KB的数据
int length = -1;
//3.操作(读取)
while ((length=is.read(flush)) != -1) {
os.write(flush,0,length);//读取过来的就是字节数组,可以直接使用文件字节写入流写入到文件中
os.flush();
}
// while ((is.read(flush)) != -1) {//这里是不指定获取读取的字节数,一次性写入
// os.write(flush);//读取过来的就是字节数组,可以直接使用文件字节写入流写入到文件中
// os.flush();
// }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//4.关闭流,有一个原则:先打开的后关闭
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
//先打开的字节输入流,所以后关闭
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
需要说明的是:
在代码层面拷贝文件时,除了必要的四步操作之外,还需要明确的是,被复制的文件需要在代码中指定绝对路径和文件名才能被拷贝成功;
操作二,选择流,实质上就是父类引用指向子类;
程序中这段代码:
while ((is.read(flush)) != -1) { os.write(flush);//读取过来的就是字节数组,可以直接使用文件字节写入流写入到文件中 os.flush(); } 这样写一样能够实现相同的功能,但是这样写有一些弊端:因为不能保证被读取的文件是每次读取 字节数的整数倍,也即是说有可能最后一次读取的字节数不足程序中设定的字节数组的长度,此时 还是字节数组仍是满的(后面都是初始化值0),所以一次性写入会写到目标文件中大量的无用数 据,这里需要注意!
打开多个输入输出流的时候,关闭时遵循:先打开的流后关闭原则,并且是分别关闭!为什么要这样? 暂时还不是很清楚,浅显的理解就是:只需要保证目的地正确,源头先关闭。
下面是使用递归拷贝文件夹的程序:
package IO_Study;
import java.io.*;
/**
* @author 发达的范
* @date 2021/03/21 17:31
*/
public class CopyFolds {
public static void main(String[] args) {
CopyFolds fileCopy = new CopyFolds();
//1.确定源
File src = new File("E:/(A)PostgraduateFlies/ceshiA");//
File dest = new File("E:/(A)PostgraduateFlies/ceshiB");
fileCopy.CopyFolds(src, dest);
}
//使用递归拷贝文件夹的方法
public void CopyFolds(File src, File dest) {
CopyFile copyFile = new CopyFile();
if (src == null && !src.exists()) {
//如果源文件不存在
return;
} else if (src.isDirectory()) {
//如果源文件是文件夹
File temp = new File(dest.getAbsolutePath() + File.separator + src.getName());
temp.mkdir();
File[] files = src.listFiles();//获取文件夹中所有文件(夹)
for (File f : files) {
CopyFolds(f, temp);
}
} else {
//如果是文件直接copy
File temp = new File(dest.getAbsolutePath() + File.separator + src.getName());
copyFile.Copy(src, temp);
}
}
}
package IO_Study;
import java.io.*;
/**
* @author 发达的范
* @date 2021/03/21 19:34
*/
public class CopyFile {
public void Copy(File src, File dest) {
//2.选择流
InputStream is = null;
OutputStream os = null;
try {
//2.选择流
is = new FileInputStream(src.getAbsoluteFile());
os = new FileOutputStream(dest.getAbsoluteFile());
byte[] flush = new byte[1024];//每次读取1024字节byte,就是1KB的数据
int length = -1;
//3.操作(读取)
while ((length = is.read(flush)) != -1) {
os.write(flush, 0, length);//读取过来的就是字节数组,可以直接使用文件字节写入流写入到文件中
os.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//4.关闭流,有一个原则:先打开的后关闭
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
成功拷贝,Nice!