文件分割机(FileSplitter)- 我的第一个C++程序

Posted on 2013-10-11 21:09  sunflover  阅读(628)  评论(0)    收藏  举报

由于最先学习的《C语言程序设计》,只会写控制台程序;后来学习了E语言,它的IDE很明了,还有很多网友发布的模块,开发程序很简单,后来觉得有时候别人的模块太坑,出问题了也不知道问题出在哪儿,只好自己写了一个模块,然后就发现E语言的鸡肋了,API要自己定义,很多数据类型也要定义,搞着搞着就烦了;所以下狠心学习C++,之前看过不少VC教程,也都是些基础的,对他们是膜拜有加,就差实践,最近刚好有空闲,就来实战学习了。

简要介绍:下载地址(含源码:http://pan.baidu.com/s/1kSim1)

实用层面:分割大文件为小文件,方便上传(论坛,网盘等等环境都有限制,均可解除),方便网络传输(太大的文件网络传输不方便,分割小就方便些)

技术层面:文件分割机采用多线程处理,所以分割/合并效率都很高

本次实践所得:全局变量的定义,类向导的使用,添加自定义消息以及响应函数的关联,加深了对MFC框架的理解;

主要实现代码:

 1 // FileSplitter1.h: interface for the CFileSplitter class.
 2 //
 3 //////////////////////////////////////////////////////////////////////
 4 
 5 #if !defined(AFX_FILESPLITTER1_H__413075E6_199B_4845_AC73_0AAF42D7665A__INCLUDED_)
 6 #define AFX_FILESPLITTER1_H__413075E6_199B_4845_AC73_0AAF42D7665A__INCLUDED_
 7 
 8 #if _MSC_VER > 1000
 9 #pragma once
10 #endif // _MSC_VER > 1000
11 
12 
13 #define UM_SPLITOK (WM_USER + 100)
14 #define UM_JOINOK (WM_USER + 101)
15 
16 class CFileSplitter  
17 {
18 public:
19     CFileSplitter(DWORD dwBlockSize,CString strFilePath,CWnd* pTargetWnd=NULL);
20 public:
21     DWORD m_dwBlockSize;
22     DWORD m_dwFileSize;
23     CString m_strFilePath;
24 public:
25     void Split();
26     void Join();
27     static DWORD WINAPI SplitThreadProc(LPVOID);
28     static DWORD WINAPI JoinThreadProc(LPVOID);
29     CWnd* m_pTargetWnd;
30 };
31 
32 #endif // !defined(AFX_FILESPLITTER1_H__413075E6_199B_4845_AC73_0AAF42D7665A__INCLUDED_)

 

  1 // FileSplitter1.cpp: implementation of the CFileSplitter class.
  2 //
  3 //////////////////////////////////////////////////////////////////////
  4 
  5 #include "stdafx.h"
  6 #include "FileSplilter.h"
  7 #include "FileSplitter1.h"
  8 
  9 #ifdef _DEBUG
 10 #undef THIS_FILE
 11 static char THIS_FILE[]=__FILE__;
 12 #define new DEBUG_NEW
 13 #endif
 14 
 15 //////////////////////////////////////////////////////////////////////
 16 // Construction/Destruction
 17 //////////////////////////////////////////////////////////////////////
 18 
 19 CFileSplitter::CFileSplitter(DWORD dwBlockSize,CString strFilePath,CWnd* pTargetWnd)
 20 {
 21 
 22     if (g_PerFileSize==2)
 23     {
 24         m_dwBlockSize=dwBlockSize*1024*1024;
 25     }
 26     else
 27     {
 28         m_dwBlockSize=dwBlockSize*1024;
 29     }    
 30     m_dwFileSize=0;
 31     m_strFilePath=strFilePath;
 32     m_pTargetWnd=pTargetWnd;
 33 
 34 }
 35 
 36 void CFileSplitter::Split()
 37 {
 38     HANDLE hThread=::CreateThread(NULL,0,SplitThreadProc,this,0,NULL);
 39     ::CloseHandle(hThread);
 40 }
 41 
 42 void CFileSplitter::Join()
 43 {
 44     HANDLE hThread=::CreateThread(NULL,0,JoinThreadProc,this,0,NULL);
 45     ::CloseHandle(hThread);
 46 }
 47 
 48 DWORD WINAPI CFileSplitter::SplitThreadProc(LPVOID lpParam)
 49 {
 50     CFileSplitter* pThis=(CFileSplitter*)lpParam;
 51     CFile file;
 52     file.Open(pThis->m_strFilePath,CFile::modeRead|CFile::typeBinary);
 53     pThis->m_dwFileSize=file.GetLength();
 54     if(pThis->m_dwBlockSize>pThis->m_dwFileSize)
 55     {
 56         ::MessageBox (NULL,"文件块大小大于文件大小!","错误",MB_OK);
 57         return 0;
 58     }
 59     int nFileIndex=0;
 60     DWORD offset=0;
 61     char buf[4096]={0};
 62     char *p=buf;
 63     CFile fileWriter;
 64     DWORD dwTempBlockSize=0;
 65     while(1)
 66     {
 67         if(offset==0)
 68         {
 69             char szFileName[255]={0};
 70             sprintf(szFileName,"%s.%d",pThis->m_strFilePath,nFileIndex++);
 71             fileWriter.Open (szFileName,CFile::modeWrite|CFile::modeCreate|CFile::typeBinary);
 72         }
 73         UINT nReadLen;
 74         if(pThis->m_dwBlockSize-offset>=4096)
 75         {
 76             nReadLen=file.Read(buf,4096);
 77         }
 78         else
 79         {
 80             nReadLen=file.Read(buf,pThis->m_dwBlockSize-offset);
 81         }
 82         if(nReadLen == 0)
 83         {
 84             fileWriter.Close();
 85             break;
 86         }
 87         fileWriter.Write(buf,nReadLen);
 88         offset+=nReadLen;
 89         if(offset==pThis->m_dwBlockSize)
 90         {
 91             offset=0;
 92             fileWriter.Close();
 93         }
 94     }
 95     file.Close();
 96     
 97     if (pThis->m_pTargetWnd)
 98     {
 99         //::SendMessage(pThis->m_pTargetWnd->m_hWnd,UM_SPLITOK,0,0);
100         ::PostMessage(pThis->m_pTargetWnd->m_hWnd,UM_SPLITOK,0,0);
101         
102     }
103     delete pThis;
104     return 0;
105 }
106 
107 DWORD WINAPI CFileSplitter::JoinThreadProc(LPVOID lpParam)
108 {
109     CFileSplitter* pThis =(CFileSplitter*)lpParam;
110     CString strSavePath=pThis->m_strFilePath.GetBufferSetLength(pThis->m_strFilePath.GetLength()-2);
111     CFile file;
112     file.Open (strSavePath,CFile::modeWrite|CFile::modeCreate|CFile::typeBinary);
113     int nFileIndex=0;
114     CFile fileReader;
115     char buf[4096]={0};
116     while(1)
117     {
118         char szFileName[255]={0};
119         sprintf(szFileName,"%s.%d",pThis->m_strFilePath,nFileIndex++);
120         BOOL bResult=fileReader.Open(szFileName,CFile::modeRead|CFile::typeBinary);
121         if(bResult==FALSE)
122         {
123             break;
124         }
125         else
126         {
127             while(1)
128             {
129                 UINT uReadLen=fileReader.Read(buf,4096);
130                 if(uReadLen==0)
131                     break;
132                 else
133                 {
134                     file.Write(buf,uReadLen);
135                 }
136             }
137             fileReader.Close();
138         }
139     }
140     file.Close();
141     if (pThis->m_pTargetWnd)
142     {
143         ::SendMessage(pThis->m_pTargetWnd->m_hWnd,UM_JOINOK,0 ,0);
144     }
145     delete pThis;
146     return 0;
147 }

注:本代码参考了《Visual C++入门与提高》一书。

下载地址(含源码:http://pan.baidu.com/s/1kSim1)