题目:
某产品需要实现一个内存文件系统,现在请你来实现目录与文件管理部分。
Ø系统支持目录与文件。
Ø目录可以包含其它目录与文件。
Ø删除目录时,要求同时删除此目录包含的子目录和文件。
Ø移动目录时,要求同时移动此目录包含的子目录和文件,并保证此目录下的子目录和文件层次结构不发生变化。
Ø根目录为“root”,要求缺省存在,由考生程序自行实现。
Ø除根目录(root),目录与文件有且仅有一个父目录。
头文件:FileManager.h
#ifndef _FILE_MANAGER_H_
#define _FILE_MANAGER_H_
#include <afx.h>
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include <string.h>
#include <direct.h>
#include <atlstr.h>
#include <shellapi.h>
#define BAD -1
#define OK 0
#define MAX_DIRPATH_LEN 512
#define FILENAME 1024
int CreateDir(const char * ParentDirName, const char * DirName);
void DeleteDir(const char * DirName);
int MoveDir(const char * SrcDirName, const char * DestDirName);
int CreateNewFile(const char * DirName, const char * FileName);
void DeleteNewFile(const char * FileName);
bool IsRoot(const char * lpszPath);
unsigned int GetFileNum(const char * DirName);
void Clear(void);
#endif
源文件:FileManager.cpp
/******************************************************************
File Name :
Version :
Author :
Created : 2014/4
Last Modified :
Description :
Function List :
History :
1.Date : 2014/4
Author :
Modification: Created file
*******************************************************************/
#include "FileManager.h"
/*用于保存root根目录的全局变量*/
char g_RootPath[MAX_DIRPATH_LEN] = {0};
/*******************************************************************
功能:在指定的目录(ParentDirName)下创建目录
输入:
ParentDirName 父目录名
DirName 待创建的目录名
返回:执行结果
成功返回0。
失败返回-1。如父目录( ParentDirName)不存在,
待创建的目录名( DirName)已经存在,等等。
********************************************************************/
int CreateDir(const char * ParentDirName, const char * DirName)
{
char str[MAX_DIRPATH_LEN] = {0};
char szNewFile[MAX_DIRPATH_LEN] = {0};
int iLoop = 0;
CString ParentPath;
CString TempPath;
BOOL iHook = FALSE;
if (NULL == ParentDirName)
{
return BAD;
}
TempPath = ParentDirName;
GetCurrentDirectory(MAX_DIRPATH_LEN, (LPWSTR)str);
ParentPath.Format(_T("%s"),str);
ParentPath = ParentPath + '\\' + TempPath;
memcpy(str,ParentPath.GetBuffer(ParentPath.GetLength()), ParentPath.GetLength() * 2);
for (iLoop; iLoop < ParentPath.GetLength() * 2, 2*iLoop < FILENAME; iLoop++)
{
g_RootPath[iLoop] = str[2*iLoop];
}
g_RootPath[iLoop] = '\0';
if(CreateDirectory(ParentPath,NULL))
printf("创建成功");
TempPath = DirName;
ParentPath = ParentPath + '\\' + TempPath;
if(CreateDirectory(ParentPath,NULL))
printf("创建成功");
::SetFileAttributes((LPCTSTR)DirName, FILE_ATTRIBUTE_NORMAL);
return OK;
}
/*******************************************************************
功能:删除指定目录
输入:
DirName 待删除的目录名
********************************************************************/
void DeleteDir(const char * DirName)
{
char szFind[MAX_PATH] = {0};
char szFile[MAX_PATH] = {0};
char szFileName[MAXLOGICALLOGNAMESIZE] = {0};
int iLoop = 0;
CString FullPath;
WIN32_FIND_DATA wfd;
if (NULL == DirName)
{
return ;
}
sprintf(szFind, "%s\\%s", g_RootPath, DirName);
if (!IsRoot(szFind))
{
sprintf(szFind, "%s\\*.*", szFind);
}
FullPath = szFind;
HANDLE hFind = FindFirstFile(FullPath, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 没有找或查找失败
{
return ;
}
do
{
memset(szFile, 0, sizeof(szFile));
memset(szFileName, 0, sizeof(szFileName));
if ( strcmp((char *)wfd.cFileName, ".") == 0
|| strcmp((char *)wfd.cFileName, "..") == 0 )
continue; // 过滤两目录
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (IsRoot(DirName))
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s%s", DirName, szFile);
}
else
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s\\%s", DirName, szFile);
}
DeleteDir(szFileName); // 找目录则进入此目录进行递归
}
else
{
if (IsRoot(DirName))
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s%s", DirName, szFile);
}
else
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s\\%s", DirName, szFile);
}
sprintf(szFind, "%s\\%s", g_RootPath, szFileName);
FullPath = szFind;
DeleteFile(FullPath);
printf("%s\n",szFind);
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
/*删除最外层文件夹*/
sprintf(szFind, "rd %s\\%s \/s \/q", g_RootPath, DirName);
system(szFind);
return;
}
/*******************************************************************
功能:把指定的目录( SrcDirName )移动到目标目录( DestDirName)下
输入:
SrcDirName 待移动的目录名
DestDirName 目标目录名
返回:执行结果
成功返回0。
失败返回-1。如目录( SrcDirName或DestDirName)不存在,
目标目录是待移动目录本身,或其子目录、直接父目录,等等。
********************************************************************/
int MoveDir(const char * SrcDirName, const char * DestDirName)
{
SHFILEOPSTRUCT sfo;
char szSrcPath[FILENAME] = {0};
char szDestPath[FILENAME] = {0};
sprintf(szSrcPath, "%s\\%s\0", g_RootPath, SrcDirName);
sprintf(szDestPath, "%s\\%s\0", g_RootPath, DestDirName);
CString SrcPath = szSrcPath;
CString DestPath = szDestPath;
sfo.hwnd = NULL;
sfo.wFunc = FO_MOVE;
sfo.pFrom = SrcPath;
sfo.pTo = DestPath;
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
SHFileOperation(&sfo);
return 0;
}
/*******************************************************************
功能:在指定目录( DirName)下创建文件
输入:
DirName 待创建文件所属的目录名
FileName 待创建的文件名
返回:执行结果
成功返回0。
失败返回-1。如已有同名的文件存在,目录名( DirName)不存在,等等。
********************************************************************/
int CreateNewFile(const char * DirName, const char * FileName)
{
FILE *fp = NULL;
char strFileName[FILENAME] = {0};
if (NULL == DirName)
{
return BAD;
}
sprintf(strFileName, "%s\\%s\\%s", g_RootPath, DirName, FileName);
if((fp=fopen(strFileName, "wb")) == NULL)
{
return BAD;
}
fclose(fp);
::SetFileAttributes((LPCTSTR)strFileName, FILE_ATTRIBUTE_NORMAL);
return OK;
}
/*******************************************************************
功能:删除文件
输入:
FileName 待删除的文件名
********************************************************************/
void DeleteNewFile(const char * FileName)
{
char szFilePath[MAX_DIRPATH_LEN] = {0};
CString FullPath;
if (NULL == FileName)
{
return ;
}
sprintf(szFilePath, "%s\\%s", g_RootPath, FileName);
FullPath = szFilePath;
DeleteFile(FullPath);
return ;
}
/*******************************************************************
功能:查询路径是否在最外层磁盘上
输入:
lpszPath 待查询的文件名
********************************************************************/
bool IsRoot(const char * lpszPath)
{
CHAR szRoot[4];
sprintf(szRoot, "%c:\\", lpszPath[0]);
return (strcmp(szRoot, lpszPath) == 0);
}
/*******************************************************************
功能: 统计目录( DirName)下的文件个数
输入:
DirName 待统计的目录名
返回:目录( DirName)下的文件个数,包括子目录下的文件。
说明:
目录( DirName)不存在,返回0。
********************************************************************/
unsigned int GetFileNum(const char * DirName)
{
char szFind[MAX_PATH] = {0};
char szFile[MAX_PATH] = {0};
char szFileName[MAXLOGICALLOGNAMESIZE] = {0};
int FileNum = 0;
int iLoop = 0;
CString FullPath;
WIN32_FIND_DATA wfd;
if (NULL == DirName)
{
return 0;
}
sprintf(szFind, "%s\\%s", g_RootPath, DirName);
if (!IsRoot(szFind))
{
sprintf(szFind, "%s\\*.*", szFind);
}
FullPath = szFind;
HANDLE hFind = FindFirstFile(FullPath, &wfd);
if (hFind == INVALID_HANDLE_VALUE) // 没有找或查找失败
return 0;
do
{
memset(szFile, 0, sizeof(szFile));
memset(szFileName, 0, sizeof(szFileName));
if ( strcmp((char *)wfd.cFileName, ".") == 0
|| strcmp((char *)wfd.cFileName, "..") == 0 )
continue; // 过滤两目录
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (IsRoot(DirName))
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s%s", DirName, szFile);
}
else
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s\\%s", DirName, szFile);
}
FileNum += GetFileNum(szFileName); // 找目录则进入此目录进行递归
}
else
{
if (IsRoot(DirName))
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s%s", DirName, szFile);
}
else
{
memcpy(szFileName, wfd.cFileName, sizeof(szFileName));
for (iLoop = 0; iLoop < sizeof(wfd.cFileName) * 2, 2*iLoop < sizeof(szFileName); iLoop++)
{
szFile[iLoop] = szFileName[2*iLoop];
}
szFile[iLoop] = '\0';
sprintf(szFileName, "%s\\%s", DirName, szFile);
}
//printf("%s\n",szFileName);
FileNum++;
// 对文件进行操作
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind); // 关闭查找句柄
//printf("\n%d\n", FileNum);
return FileNum;
}
/*******************************************************************
功能:清空所有数据,将系统恢复至初始化完成状态。
说明:
将根目录也需要删除。
********************************************************************/
void Clear(void)
{
/*删除root根文件夹*/
char gFilePath[MAX_DIRPATH_LEN] = {0};
sprintf(gFilePath, "rd %s \/s \/q", g_RootPath);
system(gFilePath);
return;
}