基本思路:

文件分割:将一个文件分割成若干个独立的文件。

       设置分割后小文件文件的字节数,然后读取被分割文件,

     将对应的字节数写入分割后的小文件中。

        使用seek定位下一次读取位置。

     

文件合并:将分割后的若干的文件合并成一个完整的文件。

     按照原有分割顺序逐个读取分割后的小文件,

     然后以追加的方式写入合并的文件中。

读取被分割文件将指定字节数写入分割后小文件时,下一次读取时要确保当前读取位置是上一次的写入的终点。

例如文件有5000K,设置分割后的文件大小1000K,那么第一次从0开始读取1000K写入小文件1,第二次就要从1000开始读取1000K写入小文件2.

这时就需要用到seek()不断设置文件读取位置。

seek是RandomAccessFile类中的函数

构造方法,mode为设置读写方法,“”r“为只读”w”为只写。

设置文件指针偏移量,下一次读或写时,从当前设置的位置开始。

read,write方法与输入输出流函数相同。

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.OutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List; public class FileSplit {
private String filePath;//文件路径
private long blockSize;//每一块大小
private int blockNum;//块个个数
private List<String> blockName;//每一块名称
private String [] name;
public FileSplit(){
this.blockName = new ArrayList<String>();
} public FileSplit(String filePath){
this(filePath,1024);//未知的尺寸则默认1024
}
public FileSplit(String filePath, long blockSize){
this();
this.filePath = filePath;
this.blockSize = blockSize;
init();
} public String getFilePath() {
return filePath;
} public void setFilePath(String filePath) {
this.filePath = filePath;
} public long getBlockSize() {
return blockSize;
} public void setBlockSize(long blockSize) {
this.blockSize = blockSize;
} public int getBlockNum() {
return blockNum;
} public void setBlockNum(int blockNum) {
this.blockNum = blockNum;
} public List<String> getBlockName() {
return blockName;
} public void setBlockName(List<String> blockName) {
this.blockName = blockName;
} private void initBlockName(String destPath){
name = new File(filePath).getName().split("\\.");
for(int i = 0; i < blockNum; i++){
blockName.add(i,destPath + "\\" + name[0] + "_" + i + "." +name[1]);
}
} public void init(){
File src = new File(filePath);
//路径名不存在,或该路径表示的文件不存,或是文件夹在则结束。
if(filePath == null || !src.exists()||src.isDirectory()){
return;
}
if(blockSize >= src.length())
this.blockSize = src.length();
this.blockNum = (int)Math.ceil(src.length()*1.0/blockSize); }
//destPath分割文件存放目录
public void split(String destPath){//分割函数
initBlockName(destPath);//初始化分割后的文件名
long start = 0;
for(int i = 0; i < blockNum; i++){
if(i == blockNum - 1)//计算最后一块大小
blockSize = new File(filePath).length()%blockSize;
split_m(i,start,blockSize);//参数含义:第i块,读取位置,读取内容大小
start += blockSize;//更新起始位置
// System.out.println(start);
}
} //开始分割,每次分割一块
private void split_m(int blockNum,long start,long blockSize){
int len = 0;
byte[] flush = new byte[1024];
RandomAccessFile raf = null;//源文件
BufferedOutputStream bos = null;//分割后文件
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(blockName.get(blockNum))));
raf = new RandomAccessFile(new File(filePath),"r");
try {
raf.seek(start);//确定读取位置
while(-1 != (len = raf.read(flush))){//当前块分割完成或文件已读取完跳出循环。
//System.out.printf("%d %d %d %s\n",start,blockSize,len,blockName.get(blockNum));
if((blockSize - len) >=0){//当前块大小-写入字节数,判断剩余字节
bos.write(flush,0,len);//如果块剩余大小大于读取字节数,则写入读取字节数
blockSize -= len;
}else{//如果小于,则写入当前块剩余字节数
bos.write(flush, 0, (int)blockSize);
break;//分块文件已写满,跳出当前循环
}
}
bos.flush();
bos.close();
raf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void Merge(String mergePath){//合并文件夹路径
int len;
byte[] flush = new byte[1024];
InputStream is = null;
OutputStream bos = null;
for(int i = 0; i < blockNum; i++){
try {
//每次将一个分割后的文件写入合并文件中。
//写入方法为追加
bos = new BufferedOutputStream(new FileOutputStream(new File(mergePath,"merge." + name[1]),true));
is = new BufferedInputStream(new FileInputStream(new File(blockName.get(i))));
while(-1 != (len = is.read(flush))){//直到被分割的单个小文件读取完
is.read(flush);//将读取内容放入flush
bos.write(flush,0,len);//将读取内容写入文件。
}
bos.flush();
bos.close();
is.close();//释放当前资源,下次读取下一个小文件。
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
}
public class Main {
public static void main(String[] args){
FileSplit f = new FileSplit("F:\\依风\\Desktop\\temp.txt",500);//被分割文件,分割后的字节数
f.split("F:\\依风\\Desktop");//分割后小文件的存放位置
f.Merge("F:\\依风\\Desktop");//合并后大文件的存放位置
}
}

6.6(java学习笔记)文件分割(IO综合例子)的更多相关文章

  1. Java学习笔记31(IO:Properties类)

    Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...

  2. Java学习笔记--文件IO

    简介 对于任何程序设计语言,输入和输出(Input\Output)都是系统非常核心的功能,程序运行需要数据,而数据的获取往往需要跟外部系统进行通信,外部系统可能是文件.数据库.其他程序.网络.IO设备 ...

  3. Java学习笔记7(IO)

    IO(输入输出) IO流按照操作数据的不同,分为字节流和字符流,按照数据传输方向分为输入流和输出流. 字节流 计算机中,所有文件都是以二进制(字节)形式存在,IO流中针对字节的输入输出提供了一系列的流 ...

  4. Java学习笔记33(IO:打印流,IO流工具类)

    打印流: 有两个类:PrintStream     PrintWriter类,两个类的方法一样,构造方法不一样 PrintStream构造方法:接收File类型,接收字符串文件名,接收字节输出流(Ou ...

  5. Java学习笔记32(IO:序列化流)

    对象中的数据 ,以流的形式,写入到文件中保存,过程称为写出对象,对象的序列化 ObjectOutputStream将对象写到序列中,实现序列化 在文件中,以流 的形式,将对象读取出来,过程称为读取对象 ...

  6. java学习笔记30(IO :缓冲流)

    缓冲流: 读取数据大量的文件时,读取的速度慢,java提供了一套缓冲流,提高IO流的效率: 缓冲流分为字节缓冲流和字符缓冲流: 字节输入缓冲流和字节输出缓冲流如下: package com.zs.De ...

  7. Java学习笔记29(IO字符流,转换流)

    字符流:只能操作文本文件,与字节流的区别是,字节流是按照字节来读取文件,而字符流是按照字符来读取,因此字符流的局限性为文本文件 字符输出流:Write类,使用时通过子类   每一次写入都要刷新 pac ...

  8. Java学习笔记28(IO字节流)

    IO定义: 写:Output操作:将内存上的数据持久化 到设备上,这个动作称为输出: 读:Input操作:把硬盘上的东西读取到内存,这个动作称为输入:              这两种操作称为IO流 ...

  9. Java学习笔记-文件读写和Json数组

    Java文件读写 Java中I/O流对文件的读写有很多种方法,百度后主要看了以下三种 第一种方式:使用FileWriter和FileReader,对文件内容按字符读取,代码如下 String dir ...

随机推荐

  1. The base command for the Docker CLI.

    Description The base command for the Docker CLI. Child commands Command Description docker attach At ...

  2. vsftpd主动模式和被动模式的区别

    何为主动模式,何为被动模式 1.ftp采用两个端口控制: 20端口用于数据传输. 21端口用于控制,或指建立TCP连接. 2.主动方式连接过程: [注意]:C表示客户端 S表示服务器端 S端要开启20 ...

  3. auto login vpnclient bat

    @echo offstart "" /b "C:\Program Files (x86)\Cisco Systems\VPN Client\vpngui.exe" ...

  4. WebView使用--文章集锦

    对于android WebView加载不出Html5网页的解决方法 在android4.4中webview的使用相对于之前版本的一些区别 理解WebKit和Chromium: Android 4.4 ...

  5. HDU2066一个人的旅行---(多起点多终点最短路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=2066 一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memo ...

  6. 膨胀、腐蚀、开、闭(matlab实现)

    膨胀.腐蚀.开.闭运算是数学形态学最基本的变换. 本文主要针对二值图像的形态学 膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔): B=[0 1 0      1 1 1   ...

  7. noip2013 提高组

    T1 转圈游戏 题目传送门 果不其然 第一题还是模拟题 一波快速幂解决问题 #include<cstdio> #include<cstring> #include<alg ...

  8. noip车站分级 拓扑排序

    题目传送门 这道题呢 每次输入一段数就把1~n里面没有在这组数里面的数和他们连一波 表示这些数比他们等级低 然后就搞一搞就好了哇 #include<cstdio> #include< ...

  9. java List排序 顺序 倒序 随机

    List list = new LinkedList(); for ( int i = 0 ; i < 9 ; i ++ ) { list.add( " a " + i); ...

  10. Splunk笔记

    学习Splunk Fundamentals Part 2 (IOD) 和 Splunk Fundamentals Part 1课程的笔记. Chart Over By Tips: ….|chart c ...