📄 filetool.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 + -