ZZLFileWriter.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:19k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2. *  Openmysee
  3. *
  4. *  This program is free software; you can redistribute it and/or modify
  5. *  it under the terms of the GNU General Public License as published by
  6. *  the Free Software Foundation; either version 2 of the License, or
  7. *  (at your option) any later version.
  8. *
  9. *  This program is distributed in the hope that it will be useful,
  10. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. *  GNU General Public License for more details.
  13. *
  14. *  You should have received a copy of the GNU General Public License
  15. *  along with this program; if not, write to the Free Software
  16. *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. *
  18. */
  19. #include "stdafx.h"
  20. #include "zzlfilewriter.h"
  21. #include "md5.h"
  22. ZZLFileWriter::ZZLFileWriter(void) : FILE_VERSION(1.0f),mbIsSingleAudio(FALSE)
  23. {
  24. zzlHandle = INVALID_HANDLE_VALUE;
  25. blockCount = 0;
  26. dataOffset = 0;
  27. startTime = endTime = 0;
  28. dataHandle = keySampleHandle = configHandle = INVALID_HANDLE_VALUE;
  29. firstSampleTime = firstKeySampleTime = 0;
  30. newBlockSize = 0;
  31. sampleBuffer = NULL;
  32. sampleBufferSize = 0;
  33. dataFileCount = 0;
  34. audioDataSize = videoDataSize = 0;
  35. audioStartTime = audioEndTime = videoStartTime = videoEndTime = 0;
  36. mLLMaxAudioTime = 0;
  37. mLLMaxVideoTime = 0;
  38. InitializeCriticalSection(&zzlfile_cs);
  39. }
  40. ZZLFileWriter::~ZZLFileWriter(void)
  41. {
  42. CloseHandle(zzlHandle);
  43. CloseHandle(dataHandle);
  44. CloseHandle(keySampleHandle);
  45. CloseHandle(configHandle);
  46. zzlHandle= dataHandle = keySampleHandle = configHandle = INVALID_HANDLE_VALUE;
  47. SAFE_ARRAYDELETE(sampleBuffer);
  48. DeleteCriticalSection(&zzlfile_cs);
  49. }
  50. bool ZZLFileWriter::Init(string path, string name) {
  51. if(path.empty() || name.empty())
  52. return false;
  53. if(!chnlName.empty())
  54. return true;
  55. //补路径后的斜杠
  56. string::const_iterator litSavePath = path.end();
  57. --litSavePath;
  58. if ('\' != static_cast<BYTE>(*litSavePath))
  59. {
  60. path += "\"; 
  61. }
  62. savePath = path+name; // 再加一层目录,名字就是节目名
  63. chnlName = name;
  64. // calculate md5 hashcode of channel name
  65. char* md5Str = NULL;
  66. MD5 md5(reinterpret_cast<const unsigned char*>(chnlName.data()), chnlName.size());
  67. md5Str = md5.hex_digest();
  68. assert(md5Str);
  69. // 删除旧的临时文件
  70. if(!RemoveOldTmpFile(savePath)) {
  71. return false; // 不能删除旧的节目数据,此次压缩取消
  72. }
  73. for(;;) {
  74. string bufferFileName = savePath+"\"+name+".zzl";
  75. // 创建zzl文件
  76. if((zzlHandle = CreateFile(bufferFileName.data(), 
  77. GENERIC_WRITE | GENERIC_READ, 
  78. FILE_SHARE_READ, 
  79. NULL, 
  80. CREATE_ALWAYS, 
  81. FILE_ATTRIBUTE_NORMAL, 
  82. NULL)) == INVALID_HANDLE_VALUE)
  83. {
  84. int err = GetLastError();
  85. if(err == ERROR_PATH_NOT_FOUND) { 
  86. // 创建文件失败,因为有不存在的中间目录,需要首先创建中间目录
  87. int index = 0;
  88. string temp;
  89. do {
  90. int offset = bufferFileName.find_first_of('\', index);
  91. if(offset == -1)
  92. break;
  93. temp = bufferFileName.substr(0, offset);
  94. index = offset+1;
  95. if(!CreateDirectory(temp.data(), NULL)) {
  96. int ret = GetLastError();
  97. if(ret == ERROR_ALREADY_EXISTS || ret == ERROR_ACCESS_DENIED)
  98. continue;
  99. break;
  100. }
  101. }
  102. while(1);
  103. // Create Again
  104. continue;
  105. }
  106. else
  107. return false;
  108. }
  109. break; // succeeded
  110. }
  111. DWORD writenBytes = 0;
  112. // 1. write ZZLD
  113. char fcc[5];
  114. strcpy(fcc, "ZZLD");
  115. if(INVALID_SET_FILE_POINTER == SetFilePointer(zzlHandle, 0, 0, FILE_BEGIN))
  116. return false;
  117. if(!WriteFile(zzlHandle, fcc, 4, &writenBytes, NULL))
  118. return false;
  119. if(writenBytes != 4)
  120. return false;
  121. // 2. write file version
  122. float version = FILE_VERSION;
  123. if(!WriteFile(zzlHandle, &version, sizeof(version), &writenBytes, NULL))
  124. return false;
  125. if(writenBytes != sizeof(version))
  126. return false;
  127. savePath = savePath + "\" + md5Str;
  128. if(!CreateDirectory(savePath.data(), NULL)) {
  129. int ret = GetLastError();
  130. if(ret != ERROR_ALREADY_EXISTS && ret != ERROR_ACCESS_DENIED)
  131. {
  132. return false;
  133. }
  134. }
  135. keySampleHandle = CreateFile((savePath+"\keysample").data(), 
  136. GENERIC_WRITE | GENERIC_READ, 
  137. FILE_SHARE_READ, 
  138. NULL, 
  139. CREATE_ALWAYS, 
  140. FILE_ATTRIBUTE_NORMAL, 
  141. NULL);
  142. if(keySampleHandle == INVALID_HANDLE_VALUE)
  143. return false;
  144. configHandle = CreateFile((savePath+"\config").data(), 
  145. GENERIC_WRITE | GENERIC_READ, 
  146. FILE_SHARE_READ, 
  147. NULL, 
  148. CREATE_ALWAYS, 
  149. FILE_ATTRIBUTE_NORMAL, 
  150. NULL);
  151. if(configHandle == INVALID_HANDLE_VALUE)
  152. return false;
  153. char temp[16];
  154. itoa(dataFileCount, temp, 10);
  155. dataHandle = CreateFile((savePath+"\"+temp).data(), 
  156. GENERIC_WRITE | GENERIC_READ, 
  157. FILE_SHARE_READ, 
  158. NULL, 
  159. CREATE_ALWAYS, 
  160. FILE_ATTRIBUTE_NORMAL, 
  161. NULL);
  162. if(dataHandle == INVALID_HANDLE_VALUE)
  163. return false;
  164. mLLMaxAudioTime = 0;
  165. mLLMaxVideoTime = 0;
  166. // 写入节目开始的标志Sample
  167. SampleHeader header;
  168. memset(&header, 0, sizeof(SampleHeader));
  169. header.size = sizeof(SampleHeader);
  170. header.length = 0xffffffff;
  171. header.start = 0xffffffffffffffff;
  172. header.bSyncPoint = 1;
  173. if(!PutSample(header, NULL))
  174. return false;
  175. return true;
  176. }
  177. bool ZZLFileWriter::SetMediaType(const TVMEDIATYPESECTION& audioType, BYTE* audioData, const TVMEDIATYPESECTION& videoType, BYTE* videoData) {
  178. if(zzlHandle == INVALID_HANDLE_VALUE)
  179. return false;
  180. assert(audioData || videoData);
  181. DWORD writenBytes = 0;
  182. char temp[1024];
  183. memset(temp, 0, sizeof(temp));
  184. char* pTemp = temp;
  185. // write media type
  186. memcpy(pTemp, &videoType, sizeof(videoType));
  187. pTemp += sizeof(videoType);
  188. if(videoData)
  189. memcpy(pTemp, videoData, videoType.cbFormat);
  190. pTemp += videoType.cbFormat;
  191. memcpy(pTemp, &audioType, sizeof(audioType));
  192. pTemp += sizeof(audioType);
  193. if(audioData)
  194. memcpy(pTemp, audioData, audioType.cbFormat);
  195. pTemp += audioType.cbFormat;
  196. // write start & end Time
  197. memcpy(pTemp, &startTime, sizeof(startTime));
  198. pTemp += sizeof(startTime);
  199. memcpy(pTemp, &endTime, sizeof(endTime));
  200. pTemp += sizeof(endTime);
  201. if(INVALID_SET_FILE_POINTER == SetFilePointer(zzlHandle, 4+sizeof(float), 0, FILE_BEGIN))
  202. return false;
  203. if(!WriteFile(zzlHandle, temp, pTemp-temp, &writenBytes, NULL))
  204. return false;
  205. if(writenBytes != pTemp-temp)
  206. return false;
  207. dataOffset = 4 + sizeof(float) + pTemp-temp;
  208. // calculate md5 hashcode of channel name
  209. char* md5Str = NULL;
  210. MD5 md5(reinterpret_cast<const unsigned char*>(chnlName.data()), chnlName.size());
  211. md5Str = md5.hex_digest();
  212. assert(md5Str);
  213. char cfgStr[1024];
  214. memset(cfgStr, 0, sizeof(cfgStr));
  215. // write config data
  216. // 注意:此处给BitRate所留的空间是“BitRate=000000000”
  217. sprintf(cfgStr, "BitRate=000000000nBlockSize=%dnChannelName=%snResourceHash=%snDataLength=%dnData=", 
  218. BLOCK_SIZE, chnlName.data(), md5Str, 
  219. sizeof(audioType) + audioType.cbFormat + sizeof(videoType) + videoType.cbFormat);
  220. delete [] md5Str;
  221. int totalLen = strlen(cfgStr);
  222. // write media type
  223. memcpy(cfgStr+totalLen, temp, sizeof(videoType)+videoType.cbFormat+sizeof(audioType)+audioType.cbFormat);
  224. totalLen += sizeof(videoType)+videoType.cbFormat+sizeof(audioType)+audioType.cbFormat;
  225. if(INVALID_SET_FILE_POINTER == SetFilePointer(configHandle, 0, 0, FILE_BEGIN))
  226. return false;
  227. if(!WriteFile(configHandle, cfgStr, totalLen, &writenBytes, NULL))
  228. return false;
  229. if(writenBytes != totalLen)
  230. return false;
  231. return true;
  232. }
  233. /*
  234.  * block content
  235.  *  |offset of first keysample(int32)|offset of first sample(int32)|list of samples|last uncomplete sample|
  236.  *  |sample data| = |header(SampleHeader)|data(...)|
  237.  */
  238. bool ZZLFileWriter::SaveSample(UINT dataOff, const UINT allSize) {
  239. // at the start of new block, write the offset of next sample
  240. if(newBlockSize == 0) {
  241. // 在开头的4个字节写入first keysample offset
  242. *(UINT*)newBlock = 0; // 默认值是0
  243. // 在此后的4个字节写入first sample offset
  244. *((UINT*)newBlock+1) = sizeof(int)*2; // 如果开始保存新的Sample,则first sample offset = 8
  245. if(dataOff > 0)
  246. *((UINT*)newBlock+1) += allSize-dataOff;// 如果保存前一个sample剩下的部分,则要加上其剩下的长度
  247. if(*((UINT*)newBlock+1) >= BLOCK_SIZE) // 如果此sample剩下的部分长度超过当前Block,则用UINT_MAX表示
  248. *((UINT*)newBlock+1) = UINT_MAX;
  249. newBlockSize += sizeof(int)*2;
  250. }
  251. if( *(UINT*)(newBlock) == 0 && // 当前Block尚未记录FirstKeySampleOffset
  252. dataOff == 0 && // 一个新的Sample
  253. firstKeySampleTime && // KeySample的时间
  254. newBlockSize+sizeof(SampleHeader) < BLOCK_SIZE) // SampleHeader刚好保存在当前Block中
  255. {
  256. // 在开头的4个字节记录FirstKeySampleOffset, sizeof(UINT)*2是start在SampleHeader中的位置
  257. *(UINT*)(newBlock) = newBlockSize+sizeof(UINT)*2;
  258. }
  259. // 比较剩余数据与剩余空间
  260. if(allSize-dataOff >= BLOCK_SIZE-newBlockSize) {
  261. // 剩余数据超过剩余空间,则填满并保存当前Block,并继续存储剩下的数据
  262. memcpy(newBlock+newBlockSize, sampleBuffer+dataOff, BLOCK_SIZE-newBlockSize);
  263. dataOff += BLOCK_SIZE-newBlockSize;
  264. newBlockSize = 0; // 开始新的Block
  265. // 保存旧的Block
  266. if(!SaveBlock(newBlock, BLOCK_SIZE))
  267. return false;
  268. // 继续保存剩余的数据
  269. if(allSize-dataOff > 0)
  270. return SaveSample(dataOff, allSize);
  271. }
  272. else {
  273. // 剩余数据小于剩余空间,复制并等待下一个Sample
  274. memcpy(newBlock+newBlockSize, sampleBuffer+dataOff, allSize-dataOff);
  275. newBlockSize += allSize-dataOff;
  276. }
  277. return true;
  278. }
  279. bool ZZLFileWriter::PutSample(const SampleHeader& header, BYTE* pData) {
  280. if(header.size > 1024*1024)
  281. return false;
  282. bool ret = true;
  283. EnterCriticalSection(&zzlfile_cs);
  284. char tmpStr[96];
  285. _i64toa(header.start, tmpStr, 10);
  286. _i64toa(header.length+header.start, tmpStr+32, 10);
  287. DbgLog((LOG_TRACE, 5, TEXT("start: %s end: %s"), tmpStr, tmpStr+32));
  288. // record first sample time
  289. if(firstSampleTime == 0)
  290. firstSampleTime = (time_t)(header.start/10000000);
  291. // record first keysample time
  292. //区分单音频和视频的情况
  293. if (firstKeySampleTime == 0 && TRUE == mbIsSingleAudio && header.start != 0xffffffffffffffff/*非节目起始标志Sample*/)
  294. {
  295. firstKeySampleTime = (time_t)(header.start/10000000);
  296. }
  297. else if(firstKeySampleTime == 0 && header.bSyncPoint && header.start != 0xffffffffffffffff/*非节目起始标志Sample*/) 
  298. {
  299. firstKeySampleTime = (time_t)(header.start/10000000);
  300. }
  301. if(header.size > sampleBufferSize) {
  302. SAFE_ARRAYDELETE(sampleBuffer);
  303. sampleBuffer = new BYTE[header.size];
  304. sampleBufferSize = header.size;
  305. }
  306. // copy sample header into sample buffer
  307. memcpy(sampleBuffer, &header, sizeof(SampleHeader));
  308. // copy sample data into sample buffer;
  309. if(header.size-sizeof(SampleHeader)) {
  310. assert(pData);
  311. memcpy(sampleBuffer+sizeof(SampleHeader), pData, header.size-sizeof(SampleHeader));
  312. }
  313. #ifndef GENERATE_SMALL_ZZL
  314. if(header.start > 0 && header.start != 0xffffffffffffffff/*非节目起始标志Sample*/) {
  315. if(header.bAudioSample) {
  316. //检查音频时间是否回滚
  317. if (header.start > mLLMaxAudioTime)
  318. {
  319. mLLMaxAudioTime = header.start;
  320. }
  321. else
  322. {
  323. //char lstr[1024];
  324. //sprintf(lstr, "这段音频的数据应该已经播放过了,不能进行直播%I64D",header.start);
  325. MessageBox(NULL,"这段音频的数据应该已经播放过了,不能进行直播", "错误", MB_OK|MB_ICONSTOP);
  326. return FALSE;
  327. }
  328. // calculate total size of audio samples
  329. audioDataSize += header.size;
  330. // set start&end time of audio samples
  331. if(header.start > audioEndTime || header.start < audioStartTime) {
  332. if(audioStartTime == 0 || header.start < audioStartTime) {
  333. audioStartTime = header.start;
  334. }
  335. if(header.start+header.length > audioEndTime)
  336. audioEndTime = header.start+header.length;
  337. }
  338. assert(audioStartTime <= header.start);
  339. }
  340. else {
  341. //检查视频时间是否回滚
  342. if (header.start > mLLMaxVideoTime)
  343. {
  344. mLLMaxVideoTime = header.start;
  345. }
  346. else
  347. {
  348. MessageBox(NULL,"这段视频的数据应该已经播放过了,不能进行直播", "错误", MB_OK|MB_ICONSTOP);
  349. return FALSE;
  350. }
  351. // calculate total size of video samples
  352. videoDataSize += header.size;
  353. // set start&end time of video samples
  354. if(header.start > videoEndTime || header.start < videoStartTime) {
  355. if(videoStartTime == 0 || header.start < videoStartTime) {
  356. videoStartTime = header.start;
  357. }
  358. if(header.start+header.length > videoEndTime)
  359. videoEndTime = header.start+header.length;
  360. }
  361. assert(videoStartTime <= header.start);
  362. // 检查video sample和audio sample是否时间相差过多,相差过多的节目不适合进行直播!
  363. if(videoEndTime > 0 && audioEndTime > 0)
  364. {
  365. if(videoEndTime > audioEndTime+10*10000000
  366. || audioEndTime > videoEndTime+10*10000000)
  367. {
  368. ::MessageBox(NULL,
  369. "现在视频和音频已经不同步,相差超过10s,这样压缩出来的节目是不能进行直播的!",
  370. "错误", MB_OK|MB_ICONSTOP);
  371. ret = false;
  372. }
  373. }
  374. }
  375. }
  376. #endif
  377. if(ret)
  378. ret = SaveSample(0, header.size);
  379. LeaveCriticalSection(&zzlfile_cs);
  380. return ret;
  381. }
  382. bool ZZLFileWriter::SaveBlock(const PBYTE data, const UINT size) {
  383. if(zzlHandle == INVALID_HANDLE_VALUE)
  384. return false;
  385. DWORD writenBytes = 0;
  386. if(INVALID_SET_FILE_POINTER == SetFilePointer(zzlHandle, dataOffset + blockCount*BLOCK_SIZE, 0, FILE_BEGIN))
  387. return false;
  388. if(!WriteFile(zzlHandle, data, size, &writenBytes, NULL))
  389. return false;
  390. if(writenBytes != size)
  391. return false;
  392. // write min&max keySample to zzl file
  393. if(firstSampleTime > 0) {
  394. if(firstSampleTime > endTime || firstSampleTime < startTime) {
  395. if(startTime == 0 || firstSampleTime < startTime) {
  396. startTime = firstSampleTime;
  397. }
  398. if(firstSampleTime > endTime)
  399. endTime = firstSampleTime;
  400. if(INVALID_SET_FILE_POINTER == SetFilePointer(zzlHandle, dataOffset-sizeof(startTime)-sizeof(endTime), 0, FILE_BEGIN))
  401. return false;
  402. // write start & end Time
  403. if(!WriteFile(zzlHandle, &startTime, sizeof(startTime), &writenBytes, NULL))
  404. return false;
  405. if(writenBytes != sizeof(startTime))
  406. return false;
  407. if(!WriteFile(zzlHandle, &endTime, sizeof(endTime), &writenBytes, NULL))
  408. return false;
  409. if(writenBytes != sizeof(endTime))
  410. return false;
  411. }
  412. assert(startTime <= firstSampleTime);
  413. }
  414. if(firstKeySampleTime > 0) {
  415. // write keysample to keysample file
  416. if(INVALID_SET_FILE_POINTER == SetFilePointer(keySampleHandle, 0, 0, FILE_END)) // seek to end of file
  417. return false;
  418. // write blockID
  419. if(!WriteFile(keySampleHandle, &blockCount, sizeof(blockCount), &writenBytes, NULL))
  420. return false;
  421. if(writenBytes != sizeof(blockCount))
  422. return false;
  423. // write keysample
  424. if(!WriteFile(keySampleHandle, &firstKeySampleTime, sizeof(firstKeySampleTime), &writenBytes, NULL))
  425. return false;
  426. if(writenBytes != sizeof(firstKeySampleTime))
  427. return false;
  428. }
  429. // write block data to data file
  430. if(blockCount/BLOCK_OF_DATA_FILE > dataFileCount) {
  431. dataFileCount = blockCount/BLOCK_OF_DATA_FILE;
  432. CloseHandle(dataHandle);
  433. char temp[16];
  434. itoa(dataFileCount, temp, 10);
  435. dataHandle = CreateFile((savePath+"\"+temp).data(), 
  436. GENERIC_WRITE | GENERIC_READ, 
  437. FILE_SHARE_READ, 
  438. NULL, 
  439. CREATE_ALWAYS, 
  440. FILE_ATTRIBUTE_NORMAL, 
  441. NULL);
  442. if(dataHandle == INVALID_HANDLE_VALUE)
  443. return false;
  444. }
  445. if(INVALID_SET_FILE_POINTER == SetFilePointer(dataHandle, (blockCount%BLOCK_OF_DATA_FILE)*BLOCK_SIZE, 0, FILE_BEGIN))
  446. return false;
  447. if(!WriteFile(dataHandle, data, size, &writenBytes, NULL))
  448. return false;
  449. if(writenBytes != size)
  450. return false;
  451. firstKeySampleTime = 0;
  452. firstSampleTime = 0;
  453. blockCount++;
  454. // 将最新的码率统计写入配置文件
  455. if(!SaveBitRate())
  456. return false;
  457. return true;
  458. }
  459. double ZZLFileWriter::GetBitRate() {
  460. // 根据起始Sample和最近一个Sample的时间戳以及数据的大小,分别计算视频音频的码率,然后加起来就是总的码率
  461. double bitRate = 0.0f;
  462. if(videoEndTime-videoStartTime > 0)
  463. bitRate += ((double)videoDataSize)/1024/((videoEndTime-videoStartTime)/10000000);
  464. if(audioEndTime-audioStartTime > 0)
  465. bitRate += ((double)audioDataSize)/1024/((audioEndTime-audioStartTime)/10000000);
  466. return bitRate;
  467. }
  468. //设置是否是单音频
  469. void ZZLFileWriter::SetIsSingleAudio(BOOL abAudio)
  470. {
  471. mbIsSingleAudio = abAudio;
  472. }
  473. bool ZZLFileWriter::SaveBitRate() {
  474. if(configHandle == INVALID_HANDLE_VALUE)
  475. return false;
  476. DWORD writenBytes = 0;
  477. char temp[64];
  478. if(INVALID_SET_FILE_POINTER == SetFilePointer(configHandle, 0, 0, FILE_BEGIN))
  479. return false;
  480. sprintf(temp, "BitRate=%.4f", GetBitRate());
  481. // 注意:配置文件中所留的空间是“BitRate=000000000”,所以要防止超过这个长度
  482. temp[strlen("BitRate=000000000")-1] = 0;
  483. // 检查一下,某些情况下,最后码率是0,很奇怪
  484. if(blockCount > 20) {
  485. assert(strcmp(temp, "BitRate=000000000") != 0);
  486. }
  487. if(!WriteFile(configHandle, temp, strlen(temp), &writenBytes, NULL))
  488. return false;
  489. if(writenBytes != strlen(temp))
  490. return false;
  491. return true;
  492. }
  493. bool ZZLFileWriter::RemoveOldTmpFile(string path) {
  494. WIN32_FIND_DATA fileData;
  495. string match = path;
  496. match.append("\*");
  497. HANDLE hFind = FindFirstFile(match.data(), &fileData);
  498. if(hFind == INVALID_HANDLE_VALUE)
  499. return true;
  500. bool firstDeleteFile = true;
  501. while(1) {
  502. bool shouldDelete = false;
  503. if(stricmp(fileData.cFileName, "config") == 0) // 配置文件
  504. shouldDelete = true;
  505. else if(stricmp(fileData.cFileName, "keysample") == 0) // 关键帧文件
  506. shouldDelete = true;
  507. else if(stricmp(fileData.cFileName, (chnlName+".zzl").data()) == 0) // zzl文件
  508. shouldDelete = true;
  509. else {
  510. // 如果是纯数字,说明是数据文件
  511.  int itemp  = atoi(fileData.cFileName);
  512.  char stemp[64];
  513.  itoa(itemp, stemp, 10);
  514.  if(itemp >= 0 && stricmp(fileData.cFileName, stemp) == 0)
  515.  shouldDelete = true;
  516. }
  517. if(shouldDelete) {
  518. if(firstDeleteFile) {
  519. firstDeleteFile = false;
  520. TCHAR temp[1024];
  521. //sprintf(temp, "名字是 %s 的节目已经存在于目录 %s ,请问要删除旧的节目数据吗?(可能是被遗忘的有用数据)", chnlName.data(), path.data());
  522. //int answer = MessageBox(NULL, temp, "警告", MB_YESNO|MB_ICONQUESTION);
  523. int answer = IDYES;
  524. if(answer != IDNO) {
  525. //MessageBox(NULL, "你选择删除旧的节目数据,新的节目开始压缩!", "通知", MB_OK|MB_ICONINFORMATION);
  526. TraceLog1("现在覆盖旧的节目数据,新的节目开始压缩!n");
  527. }
  528. else {
  529. sprintf(temp, "你选择保存旧的节目数据,此次压缩将被取消,请在转移目录 %s 下的数据之后,重新开始压缩。", path.data());
  530. MessageBox(NULL, temp, "通知", MB_OK|MB_ICONINFORMATION);
  531. return false;
  532. }
  533. }
  534. string temp = path+"\";
  535. temp.append(fileData.cFileName);
  536. DeleteFile(temp.data());
  537. }
  538. if(!FindNextFile(hFind, &fileData)) {
  539. if(GetLastError() == ERROR_NO_MORE_FILES)
  540. break;
  541. else {
  542. assert(0);
  543. return true; 
  544. }
  545. }
  546. }
  547. FindClose(hFind);
  548. return true;
  549. }