本文实例为大家分享了Java实现文件的分割与合并的具体代码,供大家参考,具体内容如下
一、文件分割实现思想
1、设置分割文件(块)的大小;
2、通过输入流获取源文件的大小;
3、根据1、2步的计算结果计算出分割后的文件个数(源文件的大小 / 设置分割文件的大小 ,如果设置的文件大小大于源文件的大小,接下来判断1、2步计算结果,如果余数为0,则文件个数为商值,如果余数大于0,则文件个数为商值加1。
如果设置分割文件的大小小于源文件的大小,那么文件个数为1。);
4、分割文件(边读边写)。
二、文件合并实现思想
1、文件合并与文件分割实现思想的第4步类似,就是边读边写。
方式一: 调用API中的RandomAccessFile,此类的实例支持对随机存取文件的读取和写入。按块分割与合并,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
package com.cn.filesplite1; 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.RandomAccessFile; import java.io.SequenceInputStream; import java.util.ArrayList; import java.util.List; import java.util.Vector;
public class SplitFile { //文件的路径 private String filePath; //文件名 private String fileName; //文件大小 private long length; //块数 private int size; //每块的大小 private long blockSize; //分割后的存放目录 private String destBlockPath; //每块的名称 private List<String> blockPath;
public SplitFile(){ blockPath = new ArrayList<String>(); } public SplitFile(String filePath,String destBlockPath){ this (filePath,destBlockPath, 1024 ); } public SplitFile(String filePath,String destBlockPath, long blockSize){ this (); this .filePath= filePath; this .destBlockPath =destBlockPath; this .blockSize=blockSize; init(); }
/** * 初始化操作 计算 块数、确定文件名 */ public void init(){ File src = null ; //健壮性 if ( null ==filePath ||!(((src= new File(filePath)).exists()))){ return ; } if (src.isDirectory()){ return ; } //文件名 this .fileName =src.getName();
//计算块数 实际大小 与每块大小 this .length = src.length(); //修正 每块大小 if ( this .blockSize>length){ this .blockSize =length; } //确定块数 size= ( int )(Math.ceil(length* 1.0 / this .blockSize)); //确定文件的路径 initPathName(); }
private void initPathName(){ for ( int i= 0 ;i<size;i++){ this .blockPath.add(destBlockPath+ "/" + this .fileName+ ".part" +i); } }
/** * 文件的分割 * 0)、第几块 * 1、起始位置 * 2、实际大小 * @param destPath 分割文件存放目录 */ public void split(){ long beginPos = 0 ; //起始点 long actualBlockSize =blockSize; //实际大小 //计算所有块的大小、位置、索引 for ( int i= 0 ;i<size;i++){ if (i==size- 1 ){ //最后一块 actualBlockSize = this .length-beginPos; } spiltDetail(i,beginPos,actualBlockSize); beginPos+=actualBlockSize; //本次的终点,下一次的起点 }
} /** * 文件的分割 输入 输出 * 文件拷贝 * @param idx 第几块 * @param beginPos 起始点 * @param actualBlockSize 实际大小 */ private void spiltDetail( int idx, long beginPos, long actualBlockSize){ //1、创建源 File src = new File( this .filePath); //源文件 File dest = new File( this .blockPath.get(idx)); //目标文件 //2、选择流 RandomAccessFile raf = null ; //输入流 BufferedOutputStream bos= null ; //输出流 try { raf= new RandomAccessFile(src, "r" ); bos = new BufferedOutputStream( new FileOutputStream(dest)); //读取文件 raf.seek(beginPos); //缓冲区 byte [] flush = new byte [ 1024 ]; //接收长度 int len = 0 ; while (- 1 !=(len=raf.read(flush))){ if (actualBlockSize-len>= 0 ){ //查看是否足够 //写出 bos.write(flush, 0 , len); actualBlockSize-=len; //剩余量 } else { //写出最后一次的剩余量 bos.write(flush, 0 , ( int )actualBlockSize); break ; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { FileUtil.close(bos,raf); } } /** * 文件的合并 */ public void merge(String destPath){ //创建源 File dest = new File(destPath); //选择流 BufferedOutputStream bos= null ; //输出流 SequenceInputStream sis = null ; //输入流 //创建一个容器 Vector<InputStream> vi = new Vector<InputStream>(); try { for ( int i = 0 ; i < this .blockPath.size(); i++) { vi.add( new BufferedInputStream( new FileInputStream( new File( this .blockPath.get(i))))); } bos = new BufferedOutputStream( new FileOutputStream(dest, true )); //追加 sis= new SequenceInputStream(vi.elements()); //缓冲区 byte [] flush = new byte [ 1024 ]; //接收长度 int len = 0 ; while (- 1 !=(len=sis.read(flush))){ bos.write(flush, 0 , len); } bos.flush(); FileUtil.close(sis); } catch (Exception e) { } finally { FileUtil.close(bos); } } /** * @param args */ public static void main(String[] args) { //1024 * 30 表示按照每块30Kb大小分割 SplitFile split = new SplitFile( "F:/123/1234/logFile.txt" , "F:/123/" , 1024 * 30 );
System.out.println(split.size);
// split.split();
split.merge( "F:/123/logFile.txt" );
}
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.cn.filesplite1; import java.io.Closeable; public class FileUtil { /** * 工具类关闭流 * 可变参数: ... 只能形参最后一个位置,处理方式与数组一致 */ public static void close(Closeable ... io){ for (Closeable temp:io){ try { if ( null != temp) { temp.close(); } } catch (Exception e) { } }
} /** * 使用泛型方法 */ public static <T extends Closeable> void closeAll(T ... io){ for (Closeable temp:io){ try { if ( null != temp) { temp.close(); } } catch (Exception e) { } } }
} |
方式二: 用读写的方式实现文件的分割与合并,具体实现如下代码所示:
定义一个抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package com.cn.filesplite2; import java.io.File; import java.io.IOException; /** * 文件分割 * @author Administrator * */ public abstract class SplitFile { /** * 设置单个文件的大小 * 根据自己需求设置大小,字节进率为1024,本例中设置的最大分割文件大小是2Gb。 */ public static long MAX_BYTE = 1024 * 1024 * 1024 * 2L; //2G
/** * 获取可以分割的文件数 * @param fileByte 文件大小 * @param fileParh 文件路径 * @return */ public abstract int getSplitFileNum( long fileByte,String fileParh); /** * 获取文件长度 * @param file * @return * @throws IOException */ public abstract long getFileLength(File file) ; /** * 分割文件 * @param srcFile * @param splitFileNum * @return * @throws IOException */ public abstract String[] splitFile (File srcFile, int splitFileNum) throws IOException; /** * 合并文件 * @param files * @param newFile * @throws IOException */ public abstract void mergeFile(String[] files,String newFile) throws IOException;
} |
实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
package com.cn.filesplite2;
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * 文本文件分割 * @author Administrator * */ public class SplitTextFile extends SplitFile{
@Override public long getFileLength(File file) { FileReader fr = null ; BufferedReader br = null ; //文件大小 long fileSize = 0 ; try { fr = new FileReader(file); br = new BufferedReader(fr); String line = br.readLine(); //按行读取文件 while (line != null ){ //计算文件大小 fileSize += line.length(); line = br.readLine(); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭输入流 try { if (br != null ){ br.close(); } if (fr != null ){ fr.close(); } } catch (IOException e) { e.printStackTrace(); } } //返回文件大小 return fileSize; }
@Override public int getSplitFileNum( long fileByte,String fileParh){ fileByte = getFileLength( new File(fileParh)); if (MAX_BYTE < fileByte){ if (fileByte % MAX_BYTE == 0 ){ return ( int ) (fileByte/MAX_BYTE); } else { return ( int ) (fileByte/MAX_BYTE) + 1 ; } } return 1 ; }
@Override public String[] splitFile(File srcFile, int splitFileNum) throws IOException { splitFileNum = getSplitFileNum(getFileLength(srcFile), srcFile.toString()); if (splitFileNum <= 0 ){ return null ; } FileReader fr = null ; BufferedReader br = null ; long readNum = 0 ; String[] splits = new String[splitFileNum]; try { fr = new FileReader(srcFile); br = new BufferedReader(fr); int i = 0 ; while (splitFileNum > i){ //分割后的文件名 String name = null ; //文件后缀 String nameLast = null ; if (srcFile.getName().indexOf( "." ) != - 1 ){ name = srcFile.getName().substring( 0 , srcFile.getName().indexOf( "." )); int last = srcFile.getName().lastIndexOf( "." ); // System.out.println(i); // String string = str.substring(i); nameLast = srcFile.getName().substring(last);
} else { name = srcFile.getName(); } splits[i] = srcFile.getParent() + "/" + name + "_" + i + nameLast; File wfile = new File(splits[i]); if (!wfile.exists()){ wfile.getParentFile().mkdirs(); wfile.createNewFile(); } FileWriter fw = new FileWriter(wfile, false ); BufferedWriter bw = new BufferedWriter(fw); String line = br.readLine(); int flush = 0 ; while (line != null ){ if (line.trim().length() == 0 ){ line = br.readLine(); continue ; } readNum += line.length(); if (i + 1 == splitFileNum){ bw.write(line); bw.newLine(); } else { if (readNum >= MAX_BYTE){ bw.write(line); bw.newLine(); break ; } else { bw.write(line); bw.newLine(); } } line = br.readLine(); if (flush % 100 == 0 ){ bw.flush(); } } bw.flush(); fw.flush(); bw.close(); fw.close(); readNum = 0 ; i++; } } catch (RuntimeException e) { e.printStackTrace(); } finally { try { if (br != null ) br.close(); if (fr != null ) fr.close(); } catch (Exception e) { e.printStackTrace(); } finally { br = null ; fr = null ; } } return splits; }
@Override public void mergeFile(String[] files, String newFile) throws IOException { File wfile = new File(newFile); FileWriter writer = null ; BufferedWriter bufferedWriter = null ; try { writer = new FileWriter(wfile, false ); bufferedWriter = new BufferedWriter(writer); for ( int i = 0 ; i < files.length; i++){ File rFile = new File(files[i]); FileReader reader = new FileReader(rFile); BufferedReader bufferedReader = new BufferedReader(reader); String line = bufferedReader.readLine(); while (line != null ){ if (line.trim().length() == 0 ){ line = bufferedReader.readLine(); continue ; } bufferedWriter.write(line); bufferedWriter.newLine(); line = bufferedReader.readLine(); } } bufferedWriter.flush(); writer.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (bufferedWriter != null ) bufferedWriter.close(); bufferedWriter = null ; if (writer != null ) writer.close(); writer = null ; } } } |
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.cn.filesplite2;
import java.io.File; import java.io.IOException; import org.junit.Test;
public class TestSplitFile { SplitTextFile splitTextFile = new SplitTextFile(); @Test public void funSplitFile() throws IOException{ String srcPath = "E:/splitfile/splitfile.txt" ; File file = new File(srcPath); long fileLength = splitTextFile.getFileLength(file); System.out.println( "文件大小:" + fileLength); int partitionFileNum = splitTextFile.getSplitFileNum(fileLength, srcPath); System.out.println( "个数" + partitionFileNum); //文件分割 splitTextFile.splitFile( new File(srcPath), partitionFileNum); }
@Test public void funMergeFile() throws IOException{
String[] files = { "E:/splitfile/splitfile0" , "E:/splitfile/splitfile1" , "E:/splitfile/splitfile2" // ...files/ }; String newFile = "E:/splitfile/newmergefile" ; splitTextFile.mergeFile(files, newFile);
} } |
以上内容如有任何问题或错误,恳请大家能给予意见,我会及时更正,谢谢大家。
本文的全部内容介绍完了,希望对大家的学习有所帮助,也希望大家多多支持。
原文链接:https://blog.csdn.net/manzongpeng/article/details/77937683