package com.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
public class QuickCopy {
private static final int threshold = 10*1024;
private static final int max_buf = 1024;
private static final int max_worker = 4;
private File targetFile;
private String targetFileName;
public String getTargetFileName() {
return targetFileName;
}
public void setTargetFileName(String targetFileName) {
this.targetFile = new File(targetFileName);
this.targetFileName = targetFileName;
}
private File sourceFile;
private String sourceFileName;
public String getSourceFileName() {
return sourceFileName;
}
public void setSourceFileName(String sourceFileName) throws FileNotFoundException {
this.sourceFile = new File(sourceFileName);
if(!this.sourceFile.exists() && !this.sourceFile.isFile()) {
throw new FileNotFoundException();
}
this.sourceFileName = sourceFileName;
}
public QuickCopy(String sourceFileName, String targetFileName) throws FileNotFoundException {
this.setSourceFileName(sourceFileName);
this.setTargetFileName(targetFileName);
}
public void copy() throws IOException{
createTargetFile();
if(this.sourceFile.length() > threshold) {
multiCopy();
} else {
singleCopy();
}
}
private void createTargetFile() throws IOException {
long length = this.sourceFile.length();
File parent = this.targetFile.getParentFile();
if(parent != null && !parent.exists()) {
parent.mkdirs();
}
RandomAccessFile raf =
new RandomAccessFile(
this.targetFile.getAbsolutePath(), "rw");
raf.setLength(length);
raf.close();
}
private void singleCopy() throws IOException {
FileInputStream in = new FileInputStream(this.sourceFile);
FileOutputStream out = new FileOutputStream(this.targetFile);
byte[] buf = new byte[max_buf];
int read = 0;
while((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
in.close();
out.close();
}
private void multiCopy() throws IOException {
long length = this.sourceFile.length();
long ave = length / max_worker;
for(int i=0; i<max_worker; i++) {
if(i == max_worker-1) {
multiCopy(i*ave, ave, false);
} else {
multiCopy(i*ave, ave, true);
}
}
}
private void multiCopy(long start, long total, boolean flag) {
Thread th = new Thread(new Runnable() {
@Override
public void run() {
try {
long ntotal = total;
FileInputStream in =
new FileInputStream(sourceFile);
RandomAccessFile out =
new RandomAccessFile(targetFile, "rw");
try {
in.skip(start);
out.seek(start);
byte[] buf = new byte[max_buf];
int read = 0;
while(ntotal > 0
&& (read = in.read(buf, 0,
!flag ? max_buf:
(int)(ntotal >= max_buf ? max_buf : max_buf-ntotal))) > 0)
{
out.write(buf, 0, read);
if(flag) {
ntotal -= read;
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
in.close();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
th.start();
}
}