⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filetool.cpp

📁 使用VC编写的文件操作类FileTool,主要有四个函数: //加密文件,输入参数为文件名,采用了BlowFish加密算法 BOOL EncryptFile(char * pFileName)
💻 CPP
字号:
/*
* Copyright (c) 2005,安胜联
* 
* 文件名称:FileTool.cpp
* 文件描述:主要实现文件的加密存储、打开、关闭、读取、写入
* 
* 当前版本:1.0
* 作    者:卫向军
* 完成日期:2006年1月11日
*
*/
#include "FileTool.h"
#include "blowfish.h"   //加密算法
#include "utility.h"
#include "lzari.h"      // 压缩算法
// Construction/Destruction
FileTool::FileTool()
{
	
}

FileTool::~FileTool()
{
	
}


BOOL FileTool::EncryptFile(char *pFileName)
{	
	BOOL	ret = FALSE;
	BYTE	buffer[MAX_BUF];
	int i;	
	HANDLE		fh;
	DWORD		nBytesToRead,nBytesRead;
	DWORD		nBytes;    //取整后的
	//加密函数
	CBlowFish bl;
	if ((fh = ::CreateFile(pFileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE)
	{		
		return FALSE;
	}
	
	//循环读取文件内容,每次读取512字节,然后加密.直到读到文件尾为止.	
	//文件内容必须为8的整数倍
	do{
		ret = ReadFile(fh, buffer, 512, &nBytesRead, NULL) ; 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}	
		BYTE skey[33] = "12345678901234567890123456789012";
//		bl.Initialize(skey, 32, CBlowFish::CBC);
//		bin2hexstr(buffer,nBytesRead,szBuffer);
//		p=(BYTE *)szBuffer;
//		bl.Encode(p, p, nBytesRead*2);
//		hexstr2bin((const char *)p,buffer,nBytesRead,&len);
		//文件内容必须为8的整数倍
		if(nBytesRead%8 != 0)
		{
			i=nBytesRead%8 + nBytesRead /8 * 8;
			nBytes = (nBytesRead/8 + 1) * 8;
			for(; i < nBytes; i++)
			{
				buffer[i] = 0x00;
			}
			bl.Encode(buffer, buffer, nBytesRead);
			//往后移动27个
			SetFilePointer(fh, - nBytesRead, NULL, FILE_CURRENT);
			//重新写32个
			nBytesRead = nBytes;
		}
		else
		{
			bl.Encode(buffer, buffer, nBytesRead);
			SetFilePointer(fh, - nBytesRead, NULL, FILE_CURRENT);
		}		
		ret = ::WriteFile(fh, buffer, nBytesRead, &nBytesToRead, NULL);					
		if(!ret)
		{
			return FALSE;
		}
	}while(TRUE);
	CloseHandle(fh);
	return	TRUE;
	
}

BOOL FileTool::DeCryptFile(char *pFileName)
{	
	BOOL	ret = FALSE;
	BYTE	buffer[MAX_BUF];
	HANDLE		fh;
	DWORD		nBytesToRead,nBytesRead;

	if (pFileName == NULL)
		return	FALSE;
	//加密函数
	CBlowFish bl;
	if ((fh = ::CreateFile(pFileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	
	//循环读取文件内容,每次读取512字节,然后加密.直到读到文件尾为止.	
	// Attempt a synchronous read operation. 
	do{
		ret = ReadFile(fh, buffer, 512, &nBytesRead, NULL) ; 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}	
		BYTE skey[33] = "12345678901234567890123456789012";
		bl.Decode(buffer,buffer,nBytesRead);
		SetFilePointer(fh,- nBytesRead,NULL,FILE_CURRENT);
		ret = ::WriteFile(fh,buffer,nBytesRead,&nBytesToRead,NULL);		
		if(!ret)
		{
			return FALSE;
		}
	}while(TRUE);
	CloseHandle(fh);
	return	TRUE;
	
}
//outbuf  应该置为全0
//返回值为0 说明已经到了文件末尾
//
int FileTool::ReadLine(char * szfilename, char * outBuf)
{
	char buf[20000];
	int i=0;
	DWORD nBytesRead;
	BOOL ret = FALSE;
	//printf("reading a line\n");
	while (i<20000) 
	{
		ReadFile(fHandle, buf+i, 1, &nBytesRead, NULL);
		if (nBytesRead!=1) 
		{
			return 0;
  		}
		if (buf[i]=='\n')
		{
			buf[i+1]=0;
			printf("line read=%s\n",buf);
			//读取到的数据中可能包含0x00,所以内存拷贝时长度不能用strlen
			memcpy(outBuf, buf, i+2);
			return strlen(buf);
		}
		i++;		
	}
	memcpy(outBuf, buf, i+2);
	return strlen(buf); 
}
BOOL FileTool::OpenFile(char *szFileName)
{
	HANDLE		fh;
	if ((fh = ::CreateFile(szFileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE)
	{		
		return FALSE;
	}
	fHandle = fh;
	return TRUE;
}


BOOL FileTool::CloseFile()
{
	CloseHandle(fHandle);
	return TRUE;
}

BOOL FileTool::WriteLine(char *inbuf, int len)
{
	
	DWORD nBytesWrited;
	BOOL ret = FALSE;

	ret = ::WriteFile(fHandle, inbuf, len, &nBytesWrited, NULL);
	if (ret = FALSE) 
	{
		return FALSE;
  	}
	ret = ::WriteFile(fHandle, "\r\n", 2, &nBytesWrited, NULL);
	if (ret = FALSE) 
	{
		return FALSE;
  	}
	return TRUE; 
}

BOOL FileTool::CopyDir(char *dst, char *src)
{
	SHFILEOPSTRUCT OpStruc;
	{
		OpStruc.hwnd = NULL;
		OpStruc.wFunc = FO_COPY;  //FO_COPY, FO_MOVE, FO_DELETE
		OpStruc.fFlags = NULL;
		OpStruc.pFrom = src;
		OpStruc.pTo = dst;
		OpStruc.lpszProgressTitle = NULL;
	}
	SHFileOperation(&OpStruc);
	return TRUE;
}

BOOL FileTool::CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists)
{
	return CopyFile(lpExistingFileName, lpNewFileName, bFailIfExists);
}

BOOL FileTool::WriteFile(char *inbuf, int len)
{
	DWORD  nBytesWrited;
	return ::WriteFile(fHandle, inbuf, len, &nBytesWrited, NULL);	
}

BOOL FileTool::WriteString(char *buf)
{
	DWORD  nBytesWrited;
	return ::WriteFile(fHandle, buf, strlen(buf)+1, &nBytesWrited, NULL);	
}

BOOL FileTool::WriteEnd()
{
	DWORD  nBytesWrited;
	return ::WriteFile(fHandle, "\r\n", 2, &nBytesWrited, NULL);
}
//打包某一目录下的所有文件
BOOL FileTool::Archieve(char *dir, char *arch)
{
	WIN32_FIND_DATA FindFileData;
	HANDLE	hFind;
	BOOL	bFinished = FALSE;
	BOOL	ret = FALSE;
	char	tempFileFind[200];
	DWORD	nBytesToRead,nBytesRead;
	FileTool ftSrc, ftDst;
	sprintf(tempFileFind,"%s\\*.*",dir); 
	hFind = FindFirstFile(tempFileFind, &FindFileData);
	if (hFind == INVALID_HANDLE_VALUE) 
	{
		printf ("Invalid File Handle. GetLastError reports %d\n", GetLastError ());
		return FALSE;
	} 	
	while (!bFinished)
	{		
		//如果不是.和..
		if(strcmp(FindFileData.cFileName, ".")!=0 && strcmp(FindFileData.cFileName,"..")!=0)
		{
			//如果是目录
			if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				char tempDir[MAX_PATH];
				char tempArch[MAX_PATH];
				sprintf(tempDir,"%s\\%s", dir, FindFileData.cFileName);
				sprintf(tempArch,"%s\\%s.archd", dir, FindFileData.cFileName);
				if(!Archieve(tempDir,tempArch))
					return FALSE;
			}
			//如果是文件则首先压缩文件,然后在写入到目标文件中
			else 
			{					
				if(strstr(FindFileData.cFileName, ".archd"))
				{
					BYTE	buffer[MAX_BUF];
					char	tempFile[MAX_PATH];
					DWORD	iFileSize;
					DWORD	iFileNameSize;
					sprintf(tempFile,"%s\\%s",dir,FindFileData.cFileName); 			
					//将文件写入打包文件arch中,首先为文件长度   4+文件名长度+文件长度+字节
					ftDst.OpenFile(arch);
					ftSrc.OpenFile(tempFile);
					::SetFilePointer(ftDst.fHandle, 0, NULL, FILE_END);
					iFileSize = ftSrc.GetFileSize();
					iFileNameSize = strlen(FindFileData.cFileName);
					//    4B			4B				文件名		文件内容
					//    文件名长度	文件内容长度    相对路径
					ftDst.WriteFile((char *)&iFileNameSize, 4);
					ftDst.WriteFile((char *)&iFileSize, 4);
					ftDst.WriteFile(FindFileData.cFileName, iFileNameSize);
					do
					{
						ret = ReadFile(ftSrc.fHandle, buffer, 512, &nBytesRead, NULL) ; 
						// Check for end of file. 
						if (ret &&  (nBytesRead == 0) ) 
						{ 
							break;
						}	
						ret = ::WriteFile(ftDst.fHandle,buffer,nBytesRead,&nBytesToRead,NULL);		
						if(!ret)
						{
							return FALSE;
						}
					}while(TRUE);	
					ftSrc.CloseFile();
					ftDst.CloseFile();
					//删除生成的临时文件*.archd
					DeleteFile(tempFile);
				}
				else
				{
					BYTE	buffer[MAX_BUF];
					char	tempFileCompressName[MAX_PATH];
					char	tempFile[MAX_PATH];
					DWORD	iFileSize;
					DWORD	iFileNameSize;						
					LZARI	LzariCom;
					sprintf(tempFile,"%s\\%s",dir,FindFileData.cFileName); 
					GetCompressFileName(tempFileCompressName, tempFile);
					//压缩文件 tempFileCompressName
					LzariCom.Compress(tempFile, tempFileCompressName);				
					//将文件写入打包文件arch中,首先为文件长度   4+文件名长度+文件长度+字节
					ftDst.OpenFile(arch);
					ftSrc.OpenFile(tempFileCompressName);
					::SetFilePointer(ftDst.fHandle, 0, NULL, FILE_END);
					iFileSize = ftSrc.GetFileSize();
					iFileNameSize = strlen(FindFileData.cFileName);
					//    4B			4B				文件名		文件内容
					//    文件名长度	文件内容长度    相对路径
					ftDst.WriteFile((char *)&iFileNameSize, 4);
					ftDst.WriteFile((char *)&iFileSize, 4);
					ftDst.WriteFile(FindFileData.cFileName, iFileNameSize);
					
					do
					{
						ret = ReadFile(ftSrc.fHandle, buffer, 512, &nBytesRead, NULL) ; 
						// Check for end of file. 
						if (ret &&  (nBytesRead == 0) ) 
						{ 
							break;
						}	
						ret = ::WriteFile(ftDst.fHandle,buffer,nBytesRead,&nBytesToRead,NULL);		
						if(!ret)
						{
							return FALSE;
						}
					}while(TRUE);	
					ftSrc.CloseFile();
					ftDst.CloseFile();
					//删除生成的临时文件*.liz
					DeleteFile(tempFileCompressName);	

				}				
			}
		}
		//查找下一个文件
		if (!FindNextFile (hFind, &FindFileData))
		{
			bFinished = TRUE;
			if (GetLastError () == ERROR_NO_MORE_FILES)
			{
				//printf(TEXT("Found all of the files."));
			}
			else
			{
				printf(TEXT("Unable to find next file."));
			}
		}
	}
	// Close the search handle.
	
	if (!FindClose (hFind))
	{
		printf(TEXT("Unable to close search handle."));
	}
	return TRUE;
}

DWORD FileTool::GetFileSize()
{
	return	::GetFileSize(fHandle, NULL);
}
//dir 为绝对路径
BOOL FileTool::UnArchieve(char *arch, char *dir)
{
	char szUnArchDir[MAX_PATH];	
	DWORD	nBytesRead;
	BOOL ret;
	if(dir == NULL)
	{
		strcpy(szUnArchDir, arch);
		char *p = szUnArchDir;
		p = strstr(szUnArchDir, ".");
		*p = 0;
	}
	CreateDirectory(dir, NULL);	
	FileTool ftSrc;
	FileTool ftDst;
	ftSrc.OpenFile(arch);
	unsigned long iFileDataSize;
	unsigned long iFileNameSize;
	
	
	do 
	{
		LZARI	Lzari;
		ret = ReadFile(ftSrc.fHandle, &iFileNameSize, 4, &nBytesRead, NULL); 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}	
		ret = ReadFile(ftSrc.fHandle, &iFileDataSize, 4, &nBytesRead, NULL); 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}	
		char *FileName = new char[iFileNameSize+1];
		char *FileData = new char[iFileDataSize+1];
		//文件名
		ret = ReadFile(ftSrc.fHandle, FileName, iFileNameSize, &nBytesRead, NULL); 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}
		FileName[iFileNameSize] = 0;
		//文件数据
		ret = ReadFile(ftSrc.fHandle, FileData, iFileDataSize, &nBytesRead, NULL); 
		// Check for end of file. 
		if (ret &&  (nBytesRead == 0) ) 
		{ 
			break;
		}
		FileData[iFileDataSize] = 0;
		if(strstr(FileName, ".archd"))
		{
			char TempFileName[MAX_PATH];
			char TempDirName[MAX_PATH];
			char *p;
			sprintf(TempFileName, "%s\\%s", dir, FileName);
			sprintf(TempDirName, "%s\\%s", dir, FileName);

			//去掉文件的后缀名
			p = strstr(TempDirName, ".");
			*p =0;
			ftDst.OpenFile(TempFileName);
			ftDst.WriteFile(FileData,iFileDataSize);			
			ftDst.CloseFile();
			CreateDirectory(TempDirName, NULL);
//			if(!CreateDirectory(TempDirName, NULL))
//			{	
//				printf("创建文件夹%s失败\n", dir);
//			}
			UnArchieve(TempFileName, TempDirName);
			DeleteFile(TempFileName);
		}
		else
		{
			char TempFileName[MAX_PATH];
			char TempFileComName[MAX_PATH];
			sprintf(TempFileName, "%s\\%s", dir, FileName);
			GetCompressFileName(TempFileComName, TempFileName);
			ftDst.OpenFile(TempFileComName);
			ftDst.WriteFile(FileData,iFileDataSize);
			ftDst.CloseFile();
			Lzari.UnCompress(TempFileComName, TempFileName);			
			DeleteFile(TempFileComName);
		}
		delete [] FileName;
		delete [] FileData;
	} while(TRUE);
	ftSrc.CloseFile();
	return TRUE;

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -