完整實現大檔案分割為多個小檔案、並可還原合併的核心演算法與 MFC 介面程式。
序號_原檔名 (如 1_test.zip、2_test.zip),便於合併時排序。int CFileSplitDlg::SplitMe() {
// ... 開啟來源檔案、計算分割數量 ...
long l = 1;
char buff[20];
do {
CString name = _ltoa(l, buff, 10); name += "_"; // 序號前綴
CString newPath = m_targetPath;
if (newPath.Right(1) != "\\") newPath += "\\";
CFile destFile;
if (!destFile.Open(newPath + name + m_SourceFile.GetFileName(),
CFile::modeWrite | CFile::shareExclusive | CFile::typeBinary | CFile::modeCreate)) {
// 錯誤處理...
}
DWORD dwRead;
do {
dwRead = m_SourceFile.Read(buffer, nCount);
destFile.Write(buffer, dwRead);
} while (dwRead > 0 && destFile.GetLength() < nSplitSize); // 關鍵:限制單檔大小
destFile.Close();
l++;
UpdateWindow();
} while (dwRead > 0); // 來源檔案讀完結束
m_SourceFile.Close();
return 0;
}
int CFileSplitDlg::MergeMe() {
// ... 開啟目標合併檔案 ...
long l = 1;
char buff[20];
do {
CString pref = _ltoa(l, buff, 10); pref += "_";
CFile srcFile;
if (!srcFile.Open(newPath + pref + m_fileName,
CFile::modeRead | CFile::shareExclusive | CFile::typeBinary)) {
// 找不到下一個分割檔,合併完成
break;
}
DWORD dwRead;
do {
dwRead = srcFile.Read(buffer, nCount);
destFile.Write(buffer, dwRead);
} while (dwRead > 0);
srcFile.Close();
l++;
UpdateWindow();
} while (l < 500); // 簡易上限,實際應動態判斷
return 0;
}
| 項目 | 實作細節 |
|---|---|
| 緩衝區 | 固定大小 (如 4KB/64KB) 平衡記憶體與 I/O 效率 |
| 二進制模式 | CFile::typeBinary 確保位元組精確對應,支援任意檔案類型 |
| 獨佔共享 | CFile::shareExclusive 防止分割/合併過程中被其他程式修改 |
| 錯誤處理 | CFileException 捕獲開啟/讀寫失敗,彈出訊息並清理資源 |
| 進度回饋 | UpdateWindow() 強制重繪進度條/狀態文字 |
