场景:
1. 开发Windows产品时,很多东西都需要自己封装,因为它不像Cocoa那样有很好的对象模型,通过类就可以访问文件相关方法. 比如复制文件夹?
要知道Win32是否提供复制文件夹这个函数还真的通过baidu. MSDN真的很差.
2. 界面开发时打开选择文件夹窗口等.
3. 设置文件创建时间和修改时间等.
4. 也是可以在产品中移植.
bas_utility_file.h:
#ifndef __BAS_UTILITY_FILE_H
#define __BAS_UTILITY_FILE_H
#include "bas_exp.h"
#include <stdint.h>
#include <Windows.h>
#include "stdio.h"
typedef struct BASFileInfo1
{
wchar_t* dir;
wchar_t* filename;
wchar_t* ext;
}BASFileInfo;
class LIB_BASIC BASUtilityFile
{
public:
static BOOL CopyDir(LPCTSTR lpszSrcDir, LPCTSTR lpszDstDir);
static wchar_t* ZLGetFormatSizeFromBytes(uint64_t size);
static wchar_t* GetFilePathNewName(const wchar_t* path);
//utf8
static bool IsFileExist(const char* path);
static bool IsFileExist(const wchar_t* path);
static int64_t GetFileSize(const wchar_t* path);
//dateTaken: yyyy-MM-dd HH:mm:ss ; HH是1-24小时制.
static bool SetFileCreateAndModifyTime(const wchar_t* path,
const wchar_t* date_taken);
//0:目录
//1:文件名
//2:扩展名
static BASFileInfo GetFileInfo(const wchar_t* path,TCHAR c);
static wchar_t* SelectFolder();
};
#endif
#include <string.h>
#include <sstream>
#include <ShlObj.h>
#include "basic/bas_utility_file.h"
#include "basic/bas_utility_string.h"
bool BASUtilityFile::SetFileCreateAndModifyTime(const wchar_t* path,
const wchar_t* date_taken)
{
wchar_t* date = wcsdup(date_taken);
wchar_t* pos = wcschr(date,L'-');
WORD year = 0;
WORD month = 0;
WORD day = 0;
WORD hour = 0;
WORD minute = 0;
WORD seconds = 0;
*pos = 0x0;
year = _wtoi(date);
wchar_t* start = pos+1;
pos = wcschr(start,L'-');
*pos = 0x0;
month = _wtoi(start);
start = pos+1;
pos = wcschr(start,0x20);
*pos = 0x0;
day = _wtoi(start);
start = pos+1;
pos = wcschr(start,L':');
*pos = 0x0;
hour = _wtoi(start);
hour = (hour == 24)?0:hour;
start = pos+1;
pos = wcschr(start,L':');
*pos = 0x0;
minute = _wtoi(start);
start = pos+1;
seconds = _wtoi(start);
HANDLE file = CreateFile(path,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(file != INVALID_HANDLE_VALUE)
{
FILETIME ft;
SYSTEMTIME st,stUTC;
BOOL f;
//hour: 0-23
GetSystemTime(&st); // Gets the current system time
st.wYear = year;
st.wMonth = month;
st.wDay = day;
st.wHour = hour;
st.wMinute = minute;
st.wSecond = seconds;
st.wDayOfWeek = 0;
st.wMilliseconds = 0;
TzSpecificLocalTimeToSystemTime(NULL,&st,&stUTC);
SystemTimeToFileTime(&stUTC, &ft); // Converts the current system time to file time format
f = SetFileTime(file, // Sets last-write time of the file
&ft,NULL, // to the converted current system time
&ft);
CloseHandle(file);
free(date);
return true;
}
return false;
}
BOOL BASUtilityFile::CopyDir(LPCTSTR lpszSrcDir, LPCTSTR lpszDstDir)
{
SHFILEOPSTRUCT sfo;
ZeroMemory(&sfo, sizeof(sfo));
sfo.wFunc = FO_COPY;
sfo.pFrom = lpszSrcDir;
sfo.pTo = lpszDstDir;
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
int ret = SHFileOperation(&sfo);
if ( ret == 0 )
return TRUE;
else
return FALSE;
}
wchar_t* BASUtilityFile::ZLGetFormatSizeFromBytes(uint64_t size)
{
double kb = (double) size / 1024;
std::wstring result;
wchar_t buf[16];
if (kb < 1)
{
swprintf(buf,L"%.2f B",(double)size);
result.append(buf);
return wcsdup(result.c_str());
}
double mb = kb / 1024;
if (mb < 1)
{
swprintf(buf,L"%.2f KB",kb);
result.append(buf);
return wcsdup(result.c_str());
}
double gb = mb / 1024;
if (gb < 1)
{
swprintf(buf,L"%.2f MB",mb);
result.append(buf);
return wcsdup(result.c_str());
}
swprintf(buf,L"%.2f GB",gb);
result.append(buf);
return wcsdup(result.c_str());
}
wchar_t* BASUtilityFile::SelectFolder()
{
TCHAR szPath[MAX_PATH]={0};
TCHAR szDir[MAX_PATH]={0};
memset(szDir,0,sizeof(szDir));
GetCurrentDirectory(MAX_PATH,szPath);
BROWSEINFO bi;
bi.hwndOwner = NULL;
bi.pidlRoot=NULL;
bi.iImage=NULL;
bi.ulFlags = BIF_NEWDIALOGSTYLE;
bi.pszDisplayName=szDir;
bi.lpszTitle=szPath;
bi.lParam=NULL;
bi.lpfn=NULL;
if(!SHGetPathFromIDList(SHBrowseForFolder(&bi),szDir))
{
return NULL;
}
szDir[wcslen(szDir)] = L'\\';
return wcsdup(szDir);
}
BASFileInfo BASUtilityFile::GetFileInfo(const wchar_t* path1,TCHAR c)
{
std::wstring path(path1);
size_t pos = 0;
BASFileInfo info;
if((pos = path.find_last_of(c)) != std::wstring::npos)
{
info.dir = wcsdup(path.substr(0,pos+1).c_str());
pos++;
}else
{
info.dir = wcsdup(L"");
pos = 0;
}
size_t dot = path.find_last_of(L'.');
if(dot != std::wstring::npos)
{
info.filename = wcsdup(path.substr(pos,dot-pos).c_str());
info.ext = wcsdup(path.substr(dot).c_str());
}else
{
info.filename = wcsdup(path.substr(pos).c_str());
info.ext = wcsdup(L"");
}
return info;
}
int64_t BASUtilityFile::GetFileSize(const wchar_t* path)
{
FILE* file = _wfopen(path,L"rb");
if (file)
{
fseek(file, 0, SEEK_END);
int64_t size = ftell(file);
fclose(file);
return size;
}
return 0;
}
bool BASUtilityFile::IsFileExist(const char* path)
{
wchar_t* path1 = BASUtilityString::ConvertUtf8ToUnicode(path);
bool res = IsFileExist(path1);
free(path1);
return res;
}
bool BASUtilityFile::IsFileExist(const wchar_t* path)
{
if (_waccess(path,0)!= -1)
{
return true;
}
return false;
}
wchar_t* BASUtilityFile::GetFilePathNewName(const wchar_t* path1)
{
if(!IsFileExist(path1))
{
return wcsdup(path1);
}
std::wstring path(path1);
int count = 1;
std::wstring temp;
size_t dot = path.find_last_of(L".");
size_t slash = path.find_last_of(L"\\");
std::wstring dir_part = path.substr(0,slash+1);
std::wstring postfix_part = path.substr(dot);
std::wstring name_part = path.substr(slash+1,dot-slash-1);
int kMaxCount = 1000;
while(count < kMaxCount)
{
std::wstring new_path;
std::wstringstream wss;
wss << L"(" << count << L")";
new_path.append(dir_part).append(name_part).append(wss.str()).append(postfix_part);
if(!IsFileExist(new_path.c_str()))
{
return wcsdup(new_path.c_str());
}
++count;
}
return wcsdup(path.c_str());
}