package fileSplitAndBination;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
/**
* 文件的分割
* @author 风潇潇
*
*/
public class FileSplit {
//文件路径
private String srcPath;
//文件对象
private File src;
//源文件大小
private long fileSize;
//源文件名
private String name;
//分割块数
private int blocks;
//每块大小
private long blockSize;
//分割后存储路径
public FileSplit(String srcPath){
this(srcPath,10);//默认分割为十块
}
/**
* 默认为读取源文件目录,和分割块数
* @param srcPath
* @param blocks
*/
public FileSplit(String srcPath,int blocks){
this.srcPath = srcPath;
this.blocks=blocks;
initial();
}
/**
* 读取文件名,文件大小,计算分割后每块大小
*/
public void initial(){
this.src=new File(srcPath);
if(!src.isFile()){
System.out.println("传入文件夹只能分割文件,或文件不存在");
return;
}
this.fileSize=src.length();//文件大小
this.name=src.getName();//文件名
this.blockSize = fileSize/blocks;//分割块大小
}
/**
* 指定输出目录
* @param destPath
* @throws IOException
*/
public void split(String destPath) throws IOException{
File dest = new File(destPath);
if(dest.isFile()||dest.isDirectory()){
System.out.println("无法存储到已有文件或文件夹中中,请指定未建立的文件夹路劲");//为方便合并,限定必须为未建立的文件夹路径
return;
}
if(!dest.exists()){
dest.mkdirs();
}
long head=0;
long size=this.blockSize;
for(int i=0;i<blocks;i++){
if(i==blocks-1){
size=this.fileSize-head;
}
splitDtails(i,dest,head,size);
head+=size;
}
/**
* 输出分割信息
* 由于分割信息名制定
* 所以限定未建立的文件夹
* 以便合并时读取
*/
File info = new File(dest,"splitInfo");
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(info)));
dos.writeUTF(this.name);
dos.writeInt(this.blocks);
dos.flush();
dos.close();
}
private void splitDtails(int idx,File dest,long head,long size) throws IOException{
File destSplit = new File(dest,this.name+"第"+idx+"部分");
if(destSplit.exists()){
destSplit.delete();
}//避免重复写入
RandomAccessFile is = new RandomAccessFile(src,"r");
OutputStream os = new BufferedOutputStream(new FileOutputStream(destSplit,true));
is.seek(head);
byte[] flush =new byte[1024];
int len=0;
long sum=0;
//此处要尤为注意,应按实际size写入,最后一次
//同文件复制不同,此处无法通过返回-1来推出循环
//因为文件分割所以在size边界外还是有字节存在
//若直接使用len,就无法正确读取!
while(-1!=(len=is.read(flush))){
if(size-len>=0){
os.write(flush, 0, len);
size-=len;
}else{
os.write(flush,0,(int)size);
break;
}
}
os.flush();
os.close();
is.close();
}
/**、
* 通过制定大小来分割文件
* @param destPath
* @param blockSize
* @throws IOException
*/
public void splitBySize(String destPath,long blockSize) throws IOException{
if(blockSize>fileSize){
blockSize = fileSize;
}
this.blockSize=blockSize;
this.blocks = (int)(Math.ceil((fileSize*1.0/blockSize)));
split(destPath);
}
public static void main(String[] args) {
FileSplit fs = new FileSplit("G:/《Java核心技术 卷1 基础知识(原书第9版)》(完整中文版).pdf");
try {
fs.split("G:/test");
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件的合并
package fileSplitAndBination;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileBination {
private String srcPath;
private String destPath;
private String fileName;
private int blocks;
public FileBination(String srcPath, String destPath) throws IOException {
this.srcPath = srcPath;
this.destPath = destPath;
binationIntial();
}
public void binationIntial() throws IOException{
File src = new File(srcPath);
File splitInfo = new File(src,"splitInfo");
if(!src.isDirectory()){
System.out.println("请提供分割文件绝对路径!");
return;
}else if(!splitInfo.exists()||!splitInfo.isFile()){
System.out.println("分割信息文件不存在或损坏");
return;
}else{
DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(splitInfo)));
this.fileName=dis.readUTF();
this.blocks = dis.readInt();
}
}
public void bination() throws IOException{
File bFile = new File(destPath, fileName);
for(int i=0 ;i<blocks;i++){
if(!binationDtail(bFile,i)){
bFile.delete();
break;
}
}
}
private boolean binationDtail(File bFile,int i) throws IOException{
File inFile = new File(srcPath,fileName+"第"+i+"部分");
OutputStream os = new BufferedOutputStream(new FileOutputStream(bFile,true));
InputStream is=null;
boolean ok=true;
if(!inFile.exists()){
System.out.println("第"+i+"个分割文件损坏");
ok=false;
}else{
is = new BufferedInputStream(new FileInputStream(inFile));
int len =0;
byte[] flush = new byte[1024];
while(-1!=(len=is.read(flush))){
os.write(flush, 0, len);
}
}
os.flush();
os.close();
is.close();
return ok;
}
public static void main(String[] args) {
try {
FileBination fb =new FileBination("G:/test","D:/");
fb.bination();
} catch (IOException e) {
e.printStackTrace();
}
}
}