添加功能:通过MoveFileEx接口尝试计算机重启后移动文件
/*=================================================
1.创建目录 ***
2.创建文件
3.查询目录和文件属性
4.遍历文件夹,并输出所有文件的属性//http://blog.jobbole.com/109303/
5.拷贝目录和文件
6.剪切目录和文件
7.删除目录和文件
===================================================*/
#include<stdio.h>
#include<io.h>
#include <stdlib.h>
#include <direct.h> //用 _mkdir()创建一个文件夹(目录)
#include<windows.h>
#include<string>
#include<iostream>
#include<tchar.h>
using namespace std;
LPCTSTR lp;
wchar_t* cTOw(char* pchar)
{
DWORD dcNum = MultiByteToWideChar(CP_ACP, 0, pchar, -1, NULL, 0);//计算这个GB2312实际有几个字节组成
wchar_t* pwname;
pwname = new wchar_t[dcNum];
if (!pwname)
{
delete[] pwname;
}
MultiByteToWideChar(CP_ACP, 0, pchar, -1, pwname, dcNum);//把GB2312变成UNICODE:sText -> pwText
wchar_t* p = pwname;
return p;
delete[] pwname;
}
//创建文件
void FileCreat()
{
char sname[20]; //定义一个窄字串
cout << "创建文件名:";
cin >> sname;
DWORD dcNum = MultiByteToWideChar(CP_ACP, 0, sname, -1, NULL, 0);//计算这个GB2312实际有几个字节组成
wchar_t* pwname;
pwname = new wchar_t[dcNum];
if (!pwname)
{
delete[] pwname;
}
MultiByteToWideChar(CP_ACP, 0, sname, -1, pwname, dcNum);//把GB2312变成UNICODE:sText -> pwText
HANDLE hFile;//文件句柄
hFile = CreateFile(
pwname,//创建或打开的文件或设备的名称(这里是txt文件)。
GENERIC_WRITE / GENERIC_READ,// 文件访问权限,写
0,//共享模式,这里设置0防止其他进程打开文件或设备
NULL,//SECURITY_ATTRIBUTES结构,安全描述,这里NULL代表默认安全级
CREATE_ALWAYS,//对于存在或不存在的设置执行的操作,这里是始终创建
FILE_ATTRIBUTE_NORMAL,//设置文件的属性,里面有高速缓存的选项
NULL);
//这里失败不会返回NULL,而是INVALID_HANDLE_VALUE
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "hFile ERROR" << endl;
return;
}
CloseHandle(hFile);
delete[]pwname;//释放宽字符内存
cout << "creat sucess" << endl;
system("PAUSE");
}
//创建目录
void DocumentCreat()
{
char sname[20]; //定义一个窄字串
cout << "创建目录名:";
cin >> sname;
/*DWORD dcNum = MultiByteToWideChar(CP_ACP, 0, sname, -1, NULL, 0);//计算这个GB2312实际有几个字节组成
wchar_t* pwname;
pwname = new wchar_t[dcNum];
if (!pwname)
{
delete[] pwname;
}
MultiByteToWideChar(CP_ACP, 0, sname, -1, pwname, dcNum);//把GB2312变成UNICODE:sText -> pwText
*/
if (_access(sname, 0))//判断目录是否存在
{
if (!CreateDirectory(cTOw(sname), NULL))
cout << endl << "目录创建失败";
else
cout << endl << "目录创建成功";
}
else
{
cout << endl << "目录已经存在";
}
//delete[] pwname;
system("PAUSE");
}
//深度遍历目录文件
void BrowseDocFile(string path, int layer)
{
_finddata_t file_info;
//=======_finddata_t结构体说明==========http://blog.youkuaiyun.com/wzhwho/article/details/6372353
/*struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};*/
string current_path = path + "\\*.*";// 也可以用/*来匹配所有
int handle = _findfirst(current_path.c_str(), &file_info);
//返回值为-1则查找失败
if (-1 == handle)
{
cout << "无法遍历该目录" << endl;
return;
}
while ((0==_findnext(handle, &file_info)))
{
//判断是否子目录
if (file_info.attrib == _A_SUBDIR)
{
//递归遍历子目录
int layer_tmp = layer;
if (strcmp(file_info.name, "..") != 0 && strcmp(file_info.name, ".") != 0) //[.是当前目录],[..是上层目录],必须排除掉这两种情况
{
for (int i = 0; i < layer; i++)
{
cout << "=>";//打印记号反映出深度层次
}
cout << " [目录] " << file_info.name << endl;
BrowseDocFile(path + '\\' + file_info.name, layer_tmp + 1); //再windows下可以用\\转义分隔符,不推荐
}
}
else//判断是文件
{
//打印记号反映出深度层次
for (int i = 0; i<layer; i++)
cout << "=>";
cout << " [文件] " << file_info.name << endl;
}
}
_findclose(handle);//关闭文件句柄
getchar();
}
void Traverse()
{
string namepath;
int layernume = 0;
cout << "输入遍历的目录:";// 此处路径连接符只能用 / ,根盘符大小写都行
cin >> namepath;
BrowseDocFile(namepath, layernume);
}
//粘贴文件
void CopyFile(string infile, string outfile)
{
FILE *in, *out;
char ch;
char pin[30], pout[30];
strcpy(pin, infile.c_str());//这是为了string和char*型的获取 https://zhidao.baidu.com/question/1382412488844707980.html?fr=iks&word=string%BA%CDchar%2A&ie=gbk
strcpy(pout, outfile.c_str());//
if ((in = fopen(pin, "r")) == NULL)
{
printf("cannot open infile!\n");
exit(0);
}
if ((out = fopen(pout, "w")) == NULL)
{
printf("cannot open outfile!\n");
exit(0);
}
while (!feof(in))
{
ch = fgetc(in);
if (ch == EOF)
break;
fputc(ch, out);
}
fclose(in);
fclose(out);
}
//粘贴目录
void CopyDoc(string frompath, string topath)
{
_finddata_t file_info;
string current_path = frompath + "\\*";// 也可以用/*来匹配所有
int handle = _findfirst(current_path.c_str(), &file_info);
//返回值为-1则查找失败
if (-1 == handle)
{
cout << "无法找到该目录" << endl;
return;
}
do
{
//判断是子目录
if (file_info.attrib == _A_SUBDIR)
{
//建立对应位置的目录
char filename1[50], filename2[60];
char buff[50];
strcpy(buff, topath.c_str());//得到目标路径
sprintf(filename1, "%s\\%s", buff, file_info.name);
CreateDirectory(cTOw(filename1), NULL);
//递归遍历子目录
if (strcmp(file_info.name, "..") != 0 && strcmp(file_info.name, ".") != 0) //[.是当前目录],[..是上层目录],必须排除掉这两种情况
CopyDoc(frompath + '\\' + file_info.name, topath + '\\' + file_info.name); //再windows下可以用\\转义分隔符,不推荐
}
//是文件
else
{
//复制文件
string s1 = frompath + '\\' + file_info.name;
string s2 = topath + '\\' + file_info.name;
CopyFile(s1, s2);
}
} while (!_findnext(handle, &file_info)); //返回0则遍历完
_findclose(handle); //关闭文件句柄
}
//拷贝
void Copy()
{
string infile, outfile, outfile1;
char buff[50];
char outpath[40];
cout << "复制的原目录: ";
cin >> infile;
cout << endl;
cout << "复制的目标地址: ";
cin >> outfile;
const char *ptr;
ptr = strrchr(infile.c_str(), '\\'); ;//p是path里最后一个'\\'的地址。然后
string s(ptr + 1); //s就是当前路径的目录名 "===== "。
outfile1 = outfile + '\\' + s;
strcpy(outpath, outfile1.c_str());//得到目标路径
//在目标路径下创建拷贝的目录
CreateDirectory(cTOw(outpath), NULL);
CopyDoc(infile, outfile1);
}
//删除文件
void FileDelete()
{
char sname[20]; //定义一个窄字串
cout << "创建文件名:";
cin >> sname;
DWORD dcNum = MultiByteToWideChar(CP_ACP, 0, sname, -1, NULL, 0);//计算这个GB2312实际有几个字节组成
wchar_t* pwname;
pwname = new wchar_t[dcNum];
if (!pwname)
{
delete[] pwname;
}
MultiByteToWideChar(CP_ACP, 0, sname, -1, pwname, dcNum);//把GB2312变成UNICODE:sText -> pwText
if (_access(sname, 0))//判断目录是否存在
{
cout << endl << "文件不存在";
}
else
{
DeleteFile(pwname);
cout << endl << "文件删除成功";
}
delete[] pwname;
system("PAUSE");
}
//通用的删除目录或文件
wchar_t* ConvertUtf8ToUnicode(char* utf8)
{
if (!utf8)
{
wchar_t* buf = (wchar_t*)malloc(2);
memset(buf, 0, 2);
return buf;
}
int nLen = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (LPCSTR)utf8, -1, NULL, 0);
//返回需要的unicode长度
WCHAR * wszUNICODE = new WCHAR[nLen + 1];
memset(wszUNICODE, 0, nLen * 2 + 2);
nLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8, -1, wszUNICODE, nLen); //把utf8转成unicode
return wszUNICODE;
}
int WXDeleteDir(wchar_t* path)
{
SHFILEOPSTRUCT FileOp;
FileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = path;
FileOp.pTo = NULL;
FileOp.wFunc = FO_DELETE;
return SHFileOperation(&FileOp);
}
void DocumentFileDelete()
{
char sname[50];
cout << "删除的目录或文件:";
cin >> sname;
wchar_t* unicode = ConvertUtf8ToUnicode(sname);
int res = WXDeleteDir(unicode);
if (res)
cout << endl << "There is an error:";
else
cout << endl << "SHFileOperation finished successfully";
free(unicode);
}
//剪切目录
void share()
{
string infile, outfile, outfile1;
char buff[50];
char outpath[40];
cout << "剪切的原目录: ";
cin >> infile;
cout << endl;
cout << "粘贴的目标地址: ";
cin >> outfile;
const char *ptr;
ptr = strrchr(infile.c_str(), '\\'); ;//p是path里最后一个'\\'的地址。然后
string s(ptr + 1); //s就是当前路径的目录名 "===== "。
outfile1 = outfile + '\\' + s;
strcpy(outpath, outfile1.c_str());//得到目标路径
//在目标路径下创建拷贝的目录
CreateDirectory(cTOw(outpath), NULL);
CopyDoc(infile, outfile1);
//删掉原目录
char infiledle[50];
strcpy(infiledle, infile.c_str());
wchar_t* unicode = ConvertUtf8ToUnicode(infiledle);
WXDeleteDir(unicode);
free(unicode);
}
//移动目录(SHFILEOPSTRUCT)
int WXMoveDirFile(wchar_t* path, wchar_t* tag)
{
SHFILEOPSTRUCT FileOp;
FileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = path;
FileOp.pTo = tag;
FileOp.wFunc = FO_MOVE;
return SHFileOperation(&FileOp);
}
void MoveDirFile()
{
char name[50], tag[50];
cout << "要移动的目录或文件:";
cin >> name;
cout << "\n移动的目标地址:";
cin >> tag;
int res = WXMoveDirFile(cTOw(name), cTOw(tag));
if (res)
cout << endl << "There is an error:";
else
cout << endl << "SHFileOperation finished successfully";
}
//移动目录(MoveFileEx)本质:不同路径下是移动并重命名,同一路径下只能重命名,这一点在帮助文件中,已经说的很清楚。
void Move()
{
char name[30], tag[30];
cout << "要移动的目录或文件:";
cin >> name;
cout << "\n移动的目标地址:";
cin >> tag;
if (
MoveFileEx(
cTOw(name), // 源文件名,指向一个以零结尾的字符串的指针。
cTOw(tag), // 把原文件(目录)更改成的文件(目录)名,必须写全更改后的路径和目录名字。指向一个以零结尾的字符串的指针。
MOVEFILE_COPY_ALLOWED // 移动标记,见定义 (同卷移动目录或文件,但跨卷只能移动文件)
)
)
MessageBox(NULL, L"移动文件成功", L"test", MB_OK);
else
MessageBox(NULL, L"移动文件失败", L"test", MB_OK);
return;
}
void RestartMove()
{
char name[30], tag[30];
cout << "要重启移动的目录或文件:";
cin >> name;
cout << "\n移动的目标地址:";
cin >> tag;
if (
MoveFileEx(
cTOw(name), // 源文件名,指向一个以零结尾的字符串的指针。
cTOw(tag), // 把原文件(目录)更改成的文件(目录)名,必须写移动后的全路径。
MOVEFILE_DELAY_UNTIL_REBOOT // 移动标记,见定义
)
)
MessageBox(NULL, L"移动文件成功", L"test", MB_OK);
else
MessageBox(NULL, L"移动文件失败", L"test", MB_OK);
return;
}
void main()
{
//FileCreat();
//DocumentCreat();
//FileDelete();
//DocumentFileDelete();
//Traverse();
//Copy();
//share();
//=======================================
//MoveDirFile();
//Move();//MoveFileEx移动
RestartMove();
return;
}