IO學習(十七)檔案的分割與合併

2021-07-11 23:15:23 字數 3360 閱讀 3401

目的:將檔案分割成數個部分,然後再將它們合併起來

首先檔案的分割,有下面幾個要點

1.先要確定的兩個因素就是,分成多少塊,每塊多大,那麼最後一塊的大小不一定剛好能是你規定的每小塊的大小,那麼最後一塊的大小就比較特殊,它等於檔案總大小(塊數-1)乘以每塊大小

2.在操作原始檔到目的檔案,即被分割檔案到分割檔案時,實際上就是檔案的拷貝過程

3.最關鍵的問題是如何控制檔案輸入流,它必須按照指定的位置讀取每乙個分塊

比如,我有142k大小的檔案,要將他們分割成3塊,規定每塊大小為50,那麼我將第一塊內容讀取的時候,是從0-50k

當讀第二快內容時就變成了50-100k,那麼如何控制讀取範圍?

這裡就需要用到randomaccessfile類,它提供了乙個seek方法,可以指定讀取的開始位置

檔案的合併就是將那些分塊重新組合在一起,比檔案分割考慮的因素少,這裡提供了兩種不同的方式進行檔案合併,其實也就是關於輸入流做出的改變,詳細見下文,合併

從小塊檔案到大檔案,其實也就是檔案追加輸出

本著oop的設計思想,將對檔案的資訊和操作方法封裝成乙個類 splitfile

這個類包含了關於檔案的一些基本資訊,檔案的路徑,大小,名稱等,以及為了分割需要的一些資訊,分割塊數,每塊的大小,分割檔案所在的目錄檔案,各自的名稱等,下面開始一步一步實現**

1.類屬性+構造方法

在構造方法執行結束後,初始化也結束,關於每塊大小可以在建立物件的時候設定,也可以使用預設的1024

public class splitfile 

public splitfile(string filepath,string destpath)

public splitfile(string filepath, long blocksize,string destpath)

}

2.初始化分割資訊

確定分割塊數,先得到檔案長度length

size=(int)(math.ceil(length*1.0/this.blocksize));

確定部分檔案的名稱

由於將所有小檔案的名稱存放在list中,所以這裡用乙個for迴圈,往list中新增元素

其中destpath是存放部分檔案的目錄

for(int i=0;ithis.blockpath.add(destpath+"/"+this.filename+".part"+i);}

3.檔案的分割

這裡需要兩個很關鍵的值,beginpos和actualblocksize,每個部分檔案開始的位置,以及它的大小

由於每乙個分塊這些資訊都不完全相同,所以需要分別處理

使用for迴圈遍歷所有的塊,需要注意的是,我們的size是向下取整,也就是說當計算的值為3.6時,size的值為3,但是這裡的i從0開始,所以一切正常

long beginpos=0;

long actualblocksize=blocksize;

for(int i=0;i//計算最後一塊大小

if(i==size-1)

spiltdetail(i,beginpos,actualblocksize);

beginpos+=actualblocksize;}

spiltdetail方法其實就是真正檔案分割的過程,其實也就是檔案拷貝,4個步驟

選擇目標檔案和原始檔;

選擇輸入輸出流;

進行拷貝;

關閉流

在拷貝過程中,需要注意不能一直都以固定的緩衝長度來寫出資料,需要進行判斷

while (-1 != (len = raf.read(flush))) else}

檔案的合併就比較簡單了,第二種方法中用到了sequenceinputstream類,將很多個輸入流集中在一起,只所有有很多個輸入流是由於每乙個部分檔案對應乙個輸入流

要使用這個類就要先有乙個集合,這裡用vector建立乙個帶泛型的vector物件

使用for迴圈將檔案輸入流新增到容器中,然後構建sequenceinputstream物件

sequenceinputstream sis = new sequenceinputstream(vi.elements());

為了增強**的健壯性,還新增了一些判斷,下面是全部**

public class splitfile

public splitfile(string filepath,string destpath)

public splitfile(string filepath, long blocksize,string destpath)

/*** 初始化操作,確定塊數

*/public void init()

//如果是乙個資料夾,直接return

if(src.isdirectory())

//得到檔案實際大小與名稱

this.length=src.length();

this.filename=src.getname();

//如果每塊大小大於檔案大小,則修改每塊大小

if(this.blocksize>length)

//計算塊數,向下取整

size=(int)(math.ceil(length*1.0/this.blocksize));

}/**

* 初始化部分檔名稱

*/private void initpathname(string destpath)else

}} catch (filenotfoundexception e) catch (ioexception e1) finally catch (ioexception e)

} }

/*** 檔案合併

* @param args

*/public void mergefile1(string destpath)

bos.flush();

bis.close();

}} catch (filenotfoundexception e) catch (ioexception e) finally catch (ioexception e)

} }

/*** 檔案合併2

* 使用sequenceinputstream

* @param args

*/public void mergefile2(string destpath){

file dest=new file(destpath);

sequenceinputstream sis=null;

bufferedoutputstream bos = null;

//建立乙個容器

vectorvi=new vector();

try{

for(int i=0;i

Qt學習之十七 檔案I O

qt 通過 qiodevice 提供了對 i o 裝置的抽象,這些裝置具有讀寫位元組塊的能力。下面是 i o裝置的類圖 qiodevice 所有 i o 裝置類的父類,提供了位元組塊讀寫的通用操作以及基本介面 qflie 訪問本地檔案或者嵌入資源 qtemporaryfile 建立和訪問本地檔案系統...

Linux 大檔案的分割與合併

分割 split命令 可以指定按行數分割和按位元組大小分割兩種模式。1 按行數分割 split l 300 large file.txt new file prefix加上 d,使用數字字尾 加上 verbose,顯示分割進度 split l 50000 d large file.txt part ...

linux大檔案分割與合併

09 原 linux相關 linux大檔案分割與合併 823 0 前言 split 命令 功能說明 切割檔案。語 法 split help version 行數 b 位元組 c 位元組 l 行數 要切割的檔案 輸出檔名 補充說明 split可將檔案切成較小的檔案,預設每1000行會切成乙個小檔案。參...