IO流之切割合并文件
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
66套java從入門到精通實(shí)戰(zhàn)課程分享
切割文件,思路就是 以每塊多大的分量去切割成多少塊,
比方說(shuō) 1024 的 文件以 500 切,就得切成 3塊,那么就是? 500,500 24 的三塊
也就是說(shuō)最后一塊可能裝不滿 500,那就得取實(shí)際數(shù)量了,也就是 24
所以就可以把文件分成 3 份,各份得起始點(diǎn)就是??
? ? ? ? ? ? 第一塊:0,500
? ? ? ? ? ? 第二塊:500,1000
? ? ? ? ? ? 第三塊:1000,1024
然后進(jìn)行讀寫(xiě),讀得時(shí)候可以使用 RandomAccessFile 的? seek 方法設(shè)置開(kāi)始讀取的地方,然后結(jié)束的地方再使用 輸入的 結(jié)束點(diǎn)進(jìn)行判斷,從而進(jìn)行分割
說(shuō)的可能有點(diǎn)不好懂,結(jié)合代碼來(lái)看吧
類的私有屬性放這幾個(gè):
// 文件路徑
??private?String?filePath;
??
??// 文件大小
??private?long fileLength;
??
??// 文件名稱
??private?String?fileName;
??
??// 以多大來(lái)切割文件
??private?long blockSize;
??
??// 文件塊數(shù)
??private?int size;
??
??// 切割后的文件的存放路徑
??private?String?destPath;
??
??// 切割后的每塊的文件名
??private?List<String> destFileName;初始化方法,初始化的時(shí)候,確定切幾塊,一塊多大,已經(jīng)切成塊后的文件名,等等:
public?SplitFileDemo()?{
????super();
????this.destFileName = new?ArrayList();
??}
??
??public?SplitFileDemo(String filePath,String destPath)?{
????this(filePath, 1024*1024, destPath);
??}
??
??public?SplitFileDemo(String filePath,long?blockSize,String destPath)?{
????this();
????this.filePath = filePath;
????this.blockSize = blockSize;
????this.destPath = destPath;
????init();
??}
??
??/**
???*
???* @Title: init
???* @Description: 初始化必須參數(shù),比如說(shuō)文件切割后的名字,分成幾塊,之類的
???* @param:
???* @return: void
???* @throws
???*/
??public?void?init()?{
????File src = null;
????// 如果 文件地址為空,或者文件不存在則終止程序
????if(this.filePath == null?|| !(src = new?File(this.filePath)).exists()) {
??????return?;
????}
????// 該地址為文件夾也終止
????if(src.isDirectory()) {
??????return?;
????}
????
????File dest = null;
????// 如果目標(biāo)文件不存在則終止程序
????if( this.destPath == null??) {
??????return?;
????}
????dest = new?File(this.destPath);
????// 如果目標(biāo)文件不存在則創(chuàng)建
????if(!dest.exists()) {
??????dest.mkdirs();
????}
????
????// 文件大小
????this.fileLength = src.length();
????
????// 文件名稱
????this.fileName = src.getName();
????
????if(this.blockSize > this.fileLength) {
??????this.blockSize = this.fileLength;
????}
????
????// 分塊
????this.size = (int)Math.ceil( (src.length()*1.0?/ this.blockSize) );
????
????initDestFileName();
??}
??
??/**
???*
???* @Title: initDestFileName
???* @Description: 初始化切割后的文件的名稱
???* @param:
???* @return: void
???* @throws
???*/
??public?void?initDestFileName()?{
????for?(int?i = 0; i < this.size; i++) {
??????this.destFileName.add( this.destPath + File.separator + this.fileName + ".temp"+i );
????}
??} 然后就是文件切割,確定文件的起始點(diǎn):
/**
???*
???* @Title: split
???* @Description: 切割文件 ,確定起始點(diǎn)
???* @param:
???* @return: void
???* @throws
???*/
??public?void?split()?{
????long?beginPos = 0;
????long?actualBlockSize = this.blockSize;
????
????for?(int?i = 0; i < this.size; i++) {
??????// 當(dāng)最后一塊的大小比分塊的大小小的時(shí)候,實(shí)際大小為 總長(zhǎng)度-起點(diǎn)
??????if(this.fileLength - beginPos <= this.blockSize ) {
????????actualBlockSize = this.fileLength - beginPos;
??????}
??????
??????splitDetil(i, beginPos, actualBlockSize);
??????// 起點(diǎn) = 上一次的結(jié)尾 + 實(shí)際讀取的長(zhǎng)度
??????beginPos += actualBlockSize;
????}
??}最后就是文件切割的詳細(xì)方法,如何切割:
/**
???*
???* @Title: splitDetil
???* @Description: 切割文件的具體實(shí)現(xiàn)方法
???* @param:
???* @return: void
???* @throws
???*/
??public?void?splitDetil(int?index,long?beginPos,long?actualBlockSize)?{
????// 創(chuàng)建源文件
????File src = new?File(this.filePath);
????File desc = new?File(this.destFileName.get(index));
????
????RandomAccessFile raf = null;
????BufferedOutputStream bos = null;
????try?{
??????// 設(shè)置只讀讀取
??????raf = new?RandomAccessFile(src, "r");
??????bos = new?BufferedOutputStream( new?FileOutputStream(desc) );
??????
??????// 讀取文件
??????raf.seek(beginPos);
??????
??????// 緩沖
??????byte?[] flush = new?byte[1024];
??????// 記錄每次讀取的長(zhǎng)度
??????int?len = 0;
??????while?(-1?!= (len = raf.read(flush))) {
????????if( (actualBlockSize - len )>0?) {
??????????bos.write(flush, 0, len);
??????????actualBlockSize -= len;
????????}else?{
??????????// 寫(xiě)出最后一塊后關(guān)閉循環(huán)
??????????bos.write(flush,0,(int)actualBlockSize);
??????????break;
????????}
??????}
??????
??????bos.flush();
??????
????} catch?(FileNotFoundException e) {
??????e.printStackTrace();
????} catch?(IOException e) {
??????e.printStackTrace();
????} finally?{
??????try?{
????????bos.close();
??????} catch?(IOException e) {
????????// TODO Auto-generated catch block
????????e.printStackTrace();
??????}
??????try?{
????????raf.close();
??????} catch?(IOException e) {
????????// TODO Auto-generated catch block
????????e.printStackTrace();
??????}
????}
????
??}最后就是文件合并了,文件合并就簡(jiǎn)單多了,因?yàn)?初始化文件的時(shí)候就確定了切塊后的每塊的文件名,只需要將其全部讀取出來(lái)然后寫(xiě)出就ok,記得這里的 new FileOutputStream( file, true ) 構(gòu)造方法應(yīng)該這樣寫(xiě),因?yàn)槭呛喜⑽募赃@里得 是追加
代碼如下:
/**
???* 文件合并
???* @Title: merge
???* @Description: TODO(這里用一句話描述這個(gè)方法的作用)
???* @param: @param?合并后的文件位置
???* @return: void
???* @throws
???*/
??public?void?merge(String destPath)?{
????File dest = new?File(destPath);
????if(destPath==null) {
??????return?;
????}
????// 目標(biāo)文件不存在則創(chuàng)建
????if(!new?File(dest.getParent()).exists()) {
??????new?File(dest.getParent()).mkdirs();
????}
????
????BufferedOutputStream bos = null;
????BufferedInputStream bis = null;
????try?{
??????// 此處是追加,因?yàn)槭俏募喜?/span>
??????bos = new?BufferedOutputStream( new?FileOutputStream( dest ,true) );
??????for?(int?i = 0; i < this.size; i++) {
????????
????????bis = new?BufferedInputStream( new?FileInputStream( new?File(this.destFileName.get(i)) ) );
????????
????????byte?[] flush = new?byte[1024];
????????int?len = 0;
????????while( -1!=(len = bis.read(flush)) ) {
??????????bos.write(flush,0,len);
????????}
????????
????????bos.flush();
????????bis.close();
??????}
????} catch?(Exception e) {
??????e.printStackTrace();
????} finally?{
??????try?{
????????bos.close();
??????} catch?(IOException e) {
????????// TODO Auto-generated catch block
????????e.printStackTrace();
??????}
????}
????
??}運(yùn)行示例:
public?static?void?main(String[] args)?{
????SplitFileDemo splitFileDemo = new?SplitFileDemo("F:\\msb\\劉明湘 - 漂洋過(guò)海來(lái)看你.mp3", 1024*1024, "F:/lmx");
????
????//splitFileDemo.split();
????splitFileDemo.merge("F:/msb/lxm.mp3");
??}自己動(dòng)手試試吧,多想想
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循?CC 4.0 BY-SA?版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/yali_aini/article/details/81942036


??? ?
感謝點(diǎn)贊支持下哈?
