基本思路:

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

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

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

        使用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. 修改centos的源

    最近都在使用国内的VPS.系统统一使用的都是Linux系统.但是,有一些服务商的系统给默认设置的是国外的.这样就会导致下载速度缓慢.于是,找到了国内几家比较热门的镜像点.奉献给大家.下面的镜像全部支持 ...

  2. Hbase写入量大导致region过大无法split问题

    最近在线上往hbase导数据,因为hbase写入能力比较强,没有太在意写的问题.让业务方进行历史数据的导入操作,中间发现一个问题,写入速度太快,并且业务数据集中到其中一个region,这个region ...

  3. Switf与OC混合开发流程

    看着身边越来越多的小伙伴转入Swift,本人也跟随潮流,转战Swift了~下面是初步写入的一个Swift项目框架. 1.创建项目,这个应该不用说了,语言swift 2.CocoaPods 导入第三方 ...

  4. svn备份

    公司的svn体量很大,要是一不小心误删了SVN版本库,就要哭了,所以有了下面的备份脚本 #每个版本库完全备份 #!/bin/bash SOUR_SVN="/var/www/svn" ...

  5. VR行业纷纷倒闭:有硬件没内容

    从去年年底开始,VR就成为了一个流行词汇,不仅是巨头公司砸钱布局,众多创业公司也纷纷投入其中.但是,一窝蜂拥入的企业基本都没有成熟的商业模式和赢利模式,只能靠融资供血.在资本寒冬中,大部分的VR企业开 ...

  6. 在liberty中通过LTPA设置单点登录

    不要忘了下面的设置,参考: https://www-01.ibm.com/support/knowledgecenter/was_beta_liberty/com.ibm.websphere.wlp. ...

  7. bzoj 5028: 小Z的加油店——带修改的区间gcd

    Description 小Z经营一家加油店.小Z加油的方式非常奇怪.他有一排瓶子,每个瓶子有一个容量vi.每次别人来加油,他会让 别人选连续一段的瓶子.他可以用这些瓶子装汽油,但他只有三种操作: 1. ...

  8. 【BZOJ】1799: [Ahoi2009]self 同类分布

    [题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模 ...

  9. [object-c 2.0 程序设计]object-c file handle (二)

    // // main.m // cmdTry // // Created by Calos Chen on 2017/8/21. // Copyright © 2017年 Calos Chen. Al ...

  10. [bzoj2763][JLOI2011]飞行路线——分层图最短路

    水题.不多说什么. #include <bits/stdc++.h> using namespace std; const int maxn = 10010; const int maxk ...