1.面向过程的分割文件编程(使用多线程时,再优化此功能)
/**
* Created by 18877 on 2019/8/21.
* 随机读取和写入流
* 文件分割
* 基础框架雏形
*/
public class ContentEncode {
public static void main(String[] args) throws IOException {
//分多少块
File src = new File("D:\\","测试目录\\test.txt");
//先获取文件的总长度
long len = src.length();
//指定每次读取的块大小
int blockSize = 3;
int size = (int) Math.ceil(len*1.0/blockSize);//向上取整
int beginPos = 0;//起始点
int actualSize = (int)(blockSize>len?len:blockSize);//如果读取的大小比文件大,则直接读取整个文件,否则为指定大小
for(int i=0;i<size;i++){
beginPos = i*blockSize;//读取点(读取的位置)
if (i==size-1){//如果是最后一块,直接读取文件剩余大小
actualSize = (int) len;
}else {
actualSize = blockSize;//每块大小
len -= actualSize;//总文件大小-读取过的大小=剩下的大小
}
System.out.println(i+"-->"+beginPos+"-->>"+actualSize);
split(i,beginPos,actualSize);//调用主要分割业务
}
}
public static void split(int i,int beginPos,int actualSize) throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("D:\\","测试目录\\test.txt"),"rw");
// int beginPos = 0;//起始读取位置
// int actualSize = 3;//实际大小(每次要读取的大小)
//随机读取
raf.seek(beginPos);//UTF-8的每个中文占3个字节
//分段读取
byte[] flush = new byte[1024];
int len = -1;
while ((len=raf.read(flush))!=-1){
if (actualSize>len){//如果要获取的大小比文件大,就直接获取文件大小
System.out.println(new String(flush,0,len));
actualSize -= len;//剩余需要实际大小多少,实际大小-读取过的
System.out.println(actualSize);
}else {
System.out.println(new String(flush,0,actualSize));//输出指定大小读取到的内容
break;
}
}
raf.close();
}
}
2.使用面向对象编程优化
/**
* Created by 18877 on 2019/8/21.
* 随机读取和写入流
* 文件分割
* 面向对象思想分割
*/
public class ContentEncode1 {
//源头
private File src;
//目的地(文件夹)
private String destDir;
//所有分割后的文件存储路径
private List<String> destPaths;
//每块大小
private int blockSize;
//多少块
private int size;
public ContentEncode1(String srcPath, String destDir, int blockSize) {
this.src = new File(srcPath);
this.destDir = destDir;
this.destPaths = new ArrayList<>();
this.blockSize = blockSize;
init();
}
private void init(){
//先获取文件的总长度
long len = this.src.length();
this.size = (int) Math.ceil(len*1.0/blockSize);//向上取整
//路径
for (int i=0;i<size;i++){
this.destPaths.add(this.destDir+"\\"+i+"-"+this.src.getName());
}
}
public void split() throws IOException {
//先获取文件的总长度
long len = src.length();
int beginPos = 0;//起始点
int actualSize = (int)(blockSize>len?len:blockSize);//如果读取的大小比文件大,则直接读取整个文件,否则为指定大小
for(int i=0;i<size;i++){
beginPos = i*blockSize;//读取点(读取的位置)
if (i==size-1){//如果是最后一块,直接读取文件剩余大小
actualSize = (int) len;
}else {
actualSize = blockSize;//每块大小
len -= actualSize;//总文件大小-读取过的大小=剩下的大小
}
splitDetail(i,beginPos,actualSize);//调用主要分割业务
}
}
public static void main(String[] args) throws IOException {
ContentEncode1 encode1 = new ContentEncode1("D:\\测试目录\\split.png","D:\\测试目录\\sp",1024);
encode1.split();
}
private void splitDetail(int i,int beginPos,int actualSize) throws IOException {
RandomAccessFile raf = new RandomAccessFile(this.src,"rw");
RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i),"rw");
//随机读取
raf.seek(beginPos);//UTF-8的每个中文占3个字节
//分段读取
byte[] flush = new byte[1024];
int len = -1;
while ((len=raf.read(flush))!=-1){
if (actualSize>len){//如果要获取的大小比文件大,就直接获取文件大小
raf2.write(flush,0,len);
actualSize -= len;//剩余需要实际大小多少,实际大小-读取过的
}else {
raf2.write(flush,0,actualSize);
break;
}
}
raf.close();
raf2.close();
}
}
3.合并文件
encode1.merge("D:\\测试目录\\split1.png");//main方法调用
//类中添加合并方法
public void merge(String destPath) throws IOException {
//输出流
OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(destPath),true));
//输入流
for (int i=0;i<destPaths.size();i++){
InputStream is = new BufferedInputStream(new FileInputStream(destPaths.get(i)));
byte[] flush = new byte[1024];
int len = -1;
while ((len=is.read(flush))!=-1){
os.write(flush,0,len);
}
os.flush();
is.close();
}
os.close();
}
public void merge(String destPath) throws IOException {
//输出流
OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(destPath),true));
Vector<InputStream> vi = new Vector<>();//容器
SequenceInputStream sis = null;
//输入流
for (int i=0;i<destPaths.size();i++){
vi.add(new BufferedInputStream(new FileInputStream(destPaths.get(i))));
}
sis = new SequenceInputStream(vi.elements());
byte[] flush = new byte[1024];
int len = -1;
while ((len=sis.read(flush))!=-1){
os.write(flush,0,len);
}
os.flush();
sis.close();
os.close();
}
评论