#ifndef _OIFILEC_FILECMDER_H #define _OIFILEC_FILECMDER_H #include "stdafx.h" #include "OIFileC_global.h" #include #include "FileResumeInfo.h" using namespace OISocketClient; namespace OIFileC { // Cmder Name #define CMD_FILE_UPLOAD L"ULF" // 上传文件 #define CMD_FILE_DOWNLOAD L"DLF" // 下载文件 #define CMD_FILE_COPY L"CPF" // 复制文件 #define CMD_FILE_DELETE L"DTF" // 删除文件 #define CMD_FILE_GETFILEINFO L"GFI" // 得到文件信息 // 数据大小定义 #define SIZE_PACK_BASE64 ( 1024 ) // 数据包大小 #define SIZE_PACK ( 768 ) // 读取相当于 BASE64 1K 的数据块大小,(1024 + 3) / 4 * 3 #define SIZE_BLOCK_BASE64 ( 512000 ) // 分块的 Base64 大小,500KB = 1024 * 500 = 512000B #define SIZE_BLOCK ( 384000 ) // 分块的大小,512000 / 4 * 3 = 384000B ///////////////////////////////////////////////////////////////////////////// // CFileCmder window class OIFILEC_API CFileCmder : public COICommander { public: CFileCmder(void); ~CFileCmder(void); // Attributers public: wstring m_strFileID; wstring m_strFolderName; // 文件目录,上传保存目录;下载时的保存目录 wstring m_strFileName; // 要上传的文件或是下载时FileID 对应的原文件名 wstring m_strSavedFile; // 下载后保存的文件名 wstring m_strFileMD5; // 文件的 MD5 数据串 wstring m_strSourceFileID; // 上传时的源文件,如果不为空,表示复制此 FileID 对应的文件至目的目录 DWORD m_dwOption; // 文件传输选项 bool m_bIsBase64; // 是否采用 Base64 编码传输 protected: // ULF, DLF FILE *m_pFile; ULONGLONG m_nReaded; // 文件读取大小 ULONGLONG m_nFileSize; // 文件大小 wstring m_strPathName; // Full Path Name wstring m_strCopyedPathName; // 文件独占不能打开的文件,需要被拷贝到TEMP目录中 // CUploadDlg *m_pdlgUpload; // 上传进度对话框 // CDownloadDlg *m_pdlgDownload; // 下载进度对话框 bool m_bIsFirst; // 接收大文件的第一批数据 // 用于发送 wstring m_strTrSessonID; // 传输事务的 ID UINT m_nBlockCount; // 分块总数 UINT m_nCurBlock; // 当前块,从 0 开始计数 char *m_pszCurBlock; // 当前数据块内容,Base64 编码,50KB wstring m_strBlockMD5; // 当前数据块的 MD5 UINT m_nCurBlockSize; // 当前块大小,可能不够一块的大小 UINT m_nSendedOfBlock; // 当前块已经发送 UINT m_nCurBlockRelSize; // 当前数据块的实际内容大小 int m_nResendCount; // 重发次数 char *m_pszFileData; // 用于存储读取文件的内容数据,临时用,开始上传时申请,结束后释放,以免每次读取数据时再申请空间 wstring m_strResumeInfoPath; // 断点续传信息的保存目录 CFileResumeInfo m_infoFileResume; // 续传信息 // Operations public: static bool CanPrsCmd( const wstring &strCmdName ); // 判断当前命令对象是否可以处理该命令 // void SetAppType( const wstring &strAppType ); // 上传时设置应用程序类型 void SetUploadFile( const wstring &strFileName ); void SetDownloadFile( const wstring &strFolderName, const wstring &strSaveFile ); void SetResumeInfoPath( const wstring &strPath ); // 设置保存断点续传信息的目录 protected: void UploadFile( COIClientSocket *pSocket ); void DownloadFile( COIClientSocket *pSocket ); void CopyFile( COIClientSocket *pSocket ); void DeleteFile( COIClientSocket *pSocket ); void GetFileInfo( COIClientSocket *pSocket ); bool ResponseUploadFile( COIResponse *pResponse, COIClientSocket *pSocket ); bool ResponseDownloadFile( COIResponse *pResponse, COIClientSocket *pSocket ); bool ResponseCopyFile( COIResponse *pResponse, COIClientSocket *pSocket ); bool ResponseDeleteFile( COIResponse *pResponse, COIClientSocket *pSocket ); bool ResponseGetFileInfo( COIResponse *pResponse, COIClientSocket *pSocket ); void ShowDownloadDlg( const wstring &strFileName, __int64 nDownloaded, __int64 nFileSize ); void ShowUploadDlg( const wstring &strFileName, __int64 nUploaded, __int64 nFileSize ); bool UploadFileErr( COIRequest *pRequest, COIClientSocket *pSocket, DWORD dwErrorCode ); bool DownloadFileErr( COIResponse *pResponse, COIClientSocket *pSocket, DWORD dwErrorCode ); bool DeleteFileErr( COIRequest *pRequest, COIClientSocket *pSocket, DWORD dwErrorCode ); void ReadBlockData(); void UploadBlockData( COIClientSocket *pSocket ); // 上传数据块 void WriteFileData( char *pszData, int nDataLen ); // 将接收的数据写入本地 void WriteToFile(); // 将缓存内存写入文件 void CloseFile(); // Overrides public: virtual void OnDisconnect( COIClientSocket *pSocket, short nInfo, int nCode ); // 连接断开, nInfo: 1 - TCP_DISCONNECT_WRITE, 2 - TCP_DISCONNECT_ERROR virtual void OnConnectFailed( COIClientSocket *pSocket, int nErrorCode ); // 连接出错 virtual void OnConnected( COIClientSocket *pSocket ); virtual int ExportBuff( COIBuffer *pBuff, size_t nNeedLen ); // virtual void OnRequestAbort( COIRequest *pRequest, int nErrCode ); // 请求失败 virtual bool OnResponse( COIResponse *pResponse, COIClientSocket *pSocket ); }; } // End of namespace OIFileC #endif // _OIFILEC_FILECMDER_H