这周学了io,下面贴一个拷贝文件的例子,这个例子结合了遍历文件,自动生成文件名,拷贝文件
package com.softeem.lesson33;
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;
import java.util.Objects;
public class FileTools {
/**
* 将目标File对象关联的本地文件(或目录)拷贝到目标目录中
* @param source 需要被拷贝file关联的文件(或目录)
* @param targetDir目标文件
*/
public static void copy(File source,File targetDir) {
//判断源文件是否为标准文件
if(source.isFile()) {
//如果源文件是标准文件,则直接进行文件拷贝
copyFiel(source,targetDir);
}else {
//在目标目录下创建一个和源目录同名的子目录
targetDir = new File(targetDir,source.getName());
if(targetDir.exists())targetDir.mkdirs();
//获取源文件目录下所有子文件
File[] subFiles = source.listFiles();
if(subFiles != null) {
//遍历所有子文件
for (int i = 0; i < subFiles.length; i++) {
copy(subFiles[i],targetDir);
}
}
}
}
private static void copyFiel(File sourceFile,File targeDir) {
//判断目标目录是否存在,不存在创建
if(!targeDir.exists()) {
targeDir.mkdirs();
}
//根据提供的源文件文件名,结合目录创建一个目录文件对象
File target = new File(targeDir,sourceFile.getName());
InputStream is = null;
OutputStream os = null;
try {
// 获取源文件的输入流
is = new FileInputStream(sourceFile);
// 获取目标文件输出流
os = new FileOutputStream(target);
// 声明字节缓冲区
byte[] b = new byte[1024];
// 声明临时变量标记当前读取的实际字节数
int len = 0;
System.out.println("开始拷贝...");
while ((len = is.read(b)) != -1) {
//使用输出流将数组从0开始写入len个字节到目标数组
os.write(b, 0, len);
}
System.out.println("拷贝完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(Objects.nonNull(os)) {
os.close();
}
if(Objects.nonNull(is)) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
FileTools f = new FileTools();
f.copy(new File("D:\\源文件"),new File("D:\\目标文件") );
}
}
线程的话,弄把一个视屏按多线程来进行拷贝的例子,这个最关键的在于如何进行多线程,也就是文件拷贝怎么分给多个线程,进行,最好进行画图思考。
package com.softeem.lesson36.exp03;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class FileSplitCopy extends Thread{
/**源文件*/
private File source;
/**目标文件*/
private File target;
/**开始拷贝位置*/
private long start;
/**结束拷贝位置*/
private long end;
public FileSplitCopy(File source, File target, long start, long end) {
super();
this.source = source;
this.target = target;
this.start = start;
this.end = end;
}
@Override
public void run() {
try (
RandomAccessFile read = new RandomAccessFile(source, "r");
RandomAccessFile write = new RandomAccessFile(target, "rw");
){
//跳过指定个字节发生下次读写
read.seek(start);
write.seek(start);
//用于统计一条线程读取的线程数
int count = 0;
byte[] b = new byte[1024];
int len =0;
System.out.println(getName()+"开始拷贝"+start);
while((len = read.read(b)) != -1) {
write.write(b, 0, len);
count += len;
//如果目前读取的总字节数超过了每一段长度了,则停止读取(当前线程结束)
//前提是:不是最后一条线程
if(count >= (end-start) && !"t3".equals(getName())) {
break;
}
}
System.out.println(getName()+"拷贝完成,拷贝长度"+count);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
File source = new File("D:\\源文件.mp4.fiq");
File target = new File("D:\\目标文件.mp4.fiq");
//平均获取每一段长度(如果除不尽剩余的字节数只可能是1-3)
long item = source.length()/4;
for (int i = 0; i < 4; i++) {
FileSplitCopy fsc = new FileSplitCopy(source, target, i*item,(i+1)*item);
fsc.setName("t"+i);
fsc.start();
}
}
}