最后稍微说一下文件的分割与合并,重在思路!!!重在思路!!!重在思路!!!
文件分割与合并:RandomAccessFile 关注seek方法。
思路:
第一步:初始操作
0)确定文件的块数
1)确定每块大小 注意处理边界,最后一块
2)每块的名称
第二步:1)分割
a)每一块的起始点、第几块、实际大小
b)文件分割
代码:
1、简单版
/**
*
* @param src
* @param blocksize
* @param dest
*/
public static void split(String src,int blocksize,String dest) throws IOException {
//源文件和目标文件
File srcFile = new File(src);
//确定分割块的数量
long filelen = srcFile.length();//文件长度
long destsize = blocksize*48;
long num = (int)filelen/destsize;
num = filelen%blocksize==0?num:num+1;//分割后的文件数目
InputStream in = null;
BufferedOutputStream bos = null;
in =new BufferedInputStream(new FileInputStream(srcFile));
byte[] bytes =new byte[12];
int len =0;
for (int i =0;i<num;i++){
String destName = dest +File.separator+srcFile.getName()+i+".txt";
bos=new BufferedOutputStream(new FileOutputStream(destName));
int count =0;
while (-1 !=(len=in.read(bytes))){
System.out.println(new java.lang.String(bytes,0,len));
bos.write(bytes,0,len);
count+=len;
if (count>=destsize){//最后一块处理
break;
}
}
bos.flush();
}
bos.close();
in.close();
}
2、封装版
package com.zr.IO.others;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class SplitFile1 implements Serializable{
//文件路径
private String filePath;
//分割后的存放目录
private String destBlockPath;
//文件大小
private long length;
//每一块的大小
private long size;
//文件名
private String fileName;
//文件每一块的大小
private long blocksize;
//文件每一块的名称
private List<String> blockPath;
public SplitFile1() {
blockPath = new ArrayList<String>();//初始化文件块的名称
}
public SplitFile1(String filePath,String destBlockPath) {
this(filePath,1024,destBlockPath);
}
public SplitFile1(String filePath,long blocksize,String destBlockPath) {
this();
this.filePath = filePath;
this.blocksize = blocksize;
this.destBlockPath = destBlockPath;
init();
}
//初始化操作,计算块数,确定文件名称
private void init() {
//分割文件数量
File file = null;
//判断文件是否可分割
if(null == filePath ||!(file = new File(filePath)).exists()){
return;
}
//文件名称
this.fileName = file.getName();
//计算块数 注意最后一块
length = file.length();//文件实际大小
//修正每一块的大小
if(this.blocksize>length){
this.blocksize = length;
}
size = (long) Math.ceil(length*1.0/this.blocksize);//计算文件的块数,取整
//确定每块文件名称
initPathName();
}
/**
* 分割文件,分割文件存放目录
* 起始位置
* 每块大小
* 第几块
* @param
*/
public void split() throws IOException {
long beginPos =0;
long actualblocksize = this.blocksize;//实际大小
for (int i =0;i<size;i++){
if(i==size-1){//考虑最后一块
actualblocksize = this.length - beginPos;
}
splitdetail(i,beginPos,actualblocksize);
beginPos+=actualblocksize;
}
}
/**
* 文件实际分割
*
* @param i 第几块
* @param beginPos 起始点
* @param actualblocksize 文件实际大小
*/
public void splitdetail(int i, long beginPos, long actualblocksize) throws IOException {
File file= new File(filePath);
File dest = new File(this.blockPath.get(i));
//选择流
RandomAccessFile raf = null;
BufferedOutputStream bos = null;
raf= new RandomAccessFile(file,"r");
bos = new BufferedOutputStream(new FileOutputStream(dest));
//读取文件
raf.seek(beginPos);
//缓冲区
byte[] bytes = new byte[1024];
//读取长度
int len =0;
while (-1!=(len=raf.read(bytes))){
int count =0;
if(actualblocksize-len>=0){
//写出文件
bos.write(bytes,0,len);
actualblocksize-=len;//剩余量
}else{
bos.write(bytes,0, (int) actualblocksize);
break;
}
bos.flush();
}
bos.close();
raf.close();
}
private void initPathName(){
for(int i =0 ;i<this.size;i++){
this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
}
}
/**
* 文件的合并
* @param destPath
*/
public void merge(String destPath) throws IOException {
File dest = new File(destPath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest,true));
BufferedInputStream bis =null;
for(int i =0;i<this.blockPath.size();i++){
bis = new BufferedInputStream(new FileInputStream(this.blockPath.get(i)));
System.out.println(this.blockPath.get(i));
//缓冲区
byte[] bytes = new byte[1024];
//读取长度
int len =0;
while (-1!=(len =bis.read(bytes))){
bos.write(bytes,0,len);
}
bos.flush();
}
bos.close();
bis.close();
}
}