package com.lingshang.io.other;
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.RandomAccessFile;
import java.io.SequenceInputStream;
import java.nio.BufferOverflowException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import com.lingshang.io.util.FileCloseUtils;
public class SplitFile {
private String filePaht;
private int size;
private long blockSize;
private String despblockPaht;
private List<String> blockPaht;
private String fileName;
private long length;
public SplitFile() {
blockPaht = new ArrayList<String>();
}
public SplitFile(String filePaht, String despblockPaht) {
this(filePaht, 1024, despblockPaht);
}
public SplitFile(String filePaht, long blockSize, String despblockPaht) {
this();
this.filePaht = filePaht;
this.blockSize = blockSize;
this.despblockPaht = despblockPaht;
init();
}
private void init() {
// TODO Auto-generated method stub
File src = null;
// 健壮性
if (null == filePaht || !((src = new File(filePaht)).exists())) {
return;
}
if (src.isDirectory()) {
return;
}
// 计算块数与实际大小
// 修正每一块的大小
this.fileName = src.getName();
this.length = src.length();
if (this.blockSize > length) {
this.blockSize = length;
}
// 确定块数
size = (int) (Math.ceil(length * 1.0 / blockSize));
initPathName();
}
private void initPathName() {
for (int i = 0; i < size; i++) {
this.blockPaht.add(despblockPaht + "/" + this.fileName + ".part"
+ i);
}
}
// 分割文件 存放目录
public void split(String destPath) {
long beginPos = 0;
long actualBlockSize = blockSize;
for (int i = 0; i < size; i++) {
if (i == size - 1) {
actualBlockSize = this.length - beginPos;
}
splitDetal(i, beginPos, actualBlockSize);
beginPos += actualBlockSize;// 这一次的终点就是下一次的起点
}
}
public void splitDetal(int idx, long beginPos, long actualBlockSize) {
// 原文件
File src = new File(this.filePaht);
// 目标文件
File dest = new File(this.blockPaht.get(idx));
// 选择流
RandomAccessFile raf = null;
BufferedOutputStream bos = null;
try {
raf = new RandomAccessFile(src, "r");
bos = new BufferedOutputStream(new FileOutputStream(dest));
raf.seek(beginPos);
byte[] fulsh = new byte[1024];
int len = 0;
while (-1 != (len = raf.read(fulsh))) {
if (actualBlockSize - len >= 0) {
bos.write(fulsh, 0, len);
actualBlockSize -= len;// 查看剩余量
} else {
bos.write(fulsh, 0, (int) actualBlockSize);
break;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
FileCloseUtils.close(bos, raf);
}
}
public void mergeFile(String destPath) {
File src = new File(destPath);
BufferedOutputStream bos = null;
SequenceInputStream sis = null;
// 创建一个容器
Vector<InputStream> vi = new Vector<InputStream>();
try {
for (int i = 0; i < this.blockPaht.size(); i++) {
vi.add(new BufferedInputStream(new FileInputStream(new File(
this.blockPaht.get(i)))));
}
sis = new SequenceInputStream(vi.elements());
bos = new BufferedOutputStream(new FileOutputStream(destPath, true));// 表示追加
byte[] fulsh = new byte[1024];
int len = 0;
while (-1 != (len = sis.read(fulsh))) {
bos.write(fulsh, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
FileCloseUtils.close(bos, sis);
}
}
public void mergeFile1(String destPath) {
File src = new File(destPath);
BufferedOutputStream bos = null;
for (int i = 0; i < this.blockPaht.size(); i++) {
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(new File(
this.blockPaht.get(i))));
bos = new BufferedOutputStream(new FileOutputStream(destPath,
true));// 表示追加
byte[] fulsh = new byte[1024];
int len = 0;
while (-1 != (len = bis.read(fulsh))) {
bos.write(fulsh, 0, len);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
FileCloseUtils.close(bos, bis);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SplitFile sf = new SplitFile("F:/XP/test/print.txt", 50, "F:/XP/");
// System.out.println(sf.size);
// sf.split("F:/XP/test");
sf.mergeFile("F:/XP/test/test1.java");
}
}