2.获得指定目录的文件
3.打开文件和下载文件功能
Directory.h
#pragma once
#include<string>
#include <direct.h>
#include<io.h>
#include<list>
#include"Strategist_FILE.h"
#include"ServerSocket.h"
typedef struct file_info
{
file_info() {
IsValid = true;
IsDirectory = -1;
HasNext = TRUE;
memset(szFileName, 0, sizeof(szFileName));
}
BOOL IsValid;//当前文件是否有效
BOOL IsDirectory;//1是目录,0不是
BOOL HasNext;//是否还有后续文件
char szFileName[256];//文件名
}FILEINFO, * PFILEINFO;
class CDirectory :public CStrategist_FILE//交由文件策略者处理
{
public:
CDirectory() {//构造时根据合理命令合理传入路径
if (CServerSocket::GetInstance()->GetFilePath(strFilePath) == false) {
OutputDebugString(_T("当前命令,不是文件列表相关操作,命令解析错误!"));
return;
}
}
std::string GetDirectoryInfo() { return strFilePath; }
~CDirectory(){}
public:
void RunFile();
void DownloadFile();
void _DeleteFile();
void DealCommand() override;
private:
void MakeDirectoryInfo();
private:
std::string strFilePath;
};
Directory.cpp
#include "pch.h"
#include "Directory.h"
//_CRT_SECURE_NO_WARNINGS
#pragma warning (disable:4996)
void CDirectory::RunFile()
{
ShellExecuteA(NULL, NULL, strFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL);//WINDOWS API调用执行
CPacket pack(8, NULL, 0);
CServerSocket::GetInstance()->Send(pack);
}
#define DOWNLOAD_SIZE 1024
void CDirectory::DownloadFile()
{
FILE* pFile = NULL;
errno_t err = fopen_s(&pFile, strFilePath.c_str(), "rb");//任何文件以二进制读取保证任何文件都可以下载
long long dataSize = 0;
if (err != 0 ) {
CPacket pack(4, (BYTE*)&dataSize, 8);
CServerSocket::GetInstance()->Send(pack);
return;
}
if(pFile!=NULL)
{
fseek(pFile, 0, SEEK_END);//设置文件指针在末尾开始偏移,偏移量为 0
dataSize = _ftelli64(pFile);//获取当前文件指针位置,这里则可以获取到整个文件大小
CPacket headpack(4, (BYTE*)&dataSize, 8);
fseek(pFile, 0, SEEK_SET);//记得恢复文件指针到初始位置
char buffer[DOWNLOAD_SIZE] = "";
size_t readLength = 0;
do {
readLength = fread(buffer, 1, DOWNLOAD_SIZE, pFile);
CPacket pack(9, (BYTE*)buffer, readLength);
CServerSocket::GetInstance()->Send(pack);
} while (readLength >= DOWNLOAD_SIZE);
fclose(pFile);
}
CPacket pack(9, NULL, 0);
CServerSocket::GetInstance()->Send(pack);
}
void CDirectory::_DeleteFile()
{
//TODO::
}
void CDirectory::DealCommand()
{
if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 7) {
MakeDirectoryInfo();
}
else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 8) {
RunFile();
}
else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 9) {
DownloadFile();
}
else if (CServerSocket::GetInstance()->GetPacket().PacketCommand == 10) {
_DeleteFile();
}
}
void CDirectory::MakeDirectoryInfo()
{
//strFilePath会从包中获取到数据,该数据必定是路径,即不会有文件
//因为后续实际点击事件时,假如点击文件夹目录,则会发送查看文件夹命令7
//点击到文件则会发送文件执行命令,也就是发送的包数据的控制命令是不同的
//if (CServerSocket::GetInstance()->GetFilePath(strFilePath) == false) {
// OutputDebugString(_T("当前命令,不是获取文件列表,命令解析错误!"));
// return;
//}
if (_chdir(strFilePath.c_str()) != 0) {//切换到strFilePath作为当前工作目录
//切换失败
FILEINFO finfo;
finfo.IsValid =false;//当前目录无效
finfo.IsDirectory = true;//因为前面说了发送过来的路径绝对是合理的所以肯定是目录,但是具体错误原因未知
finfo.HasNext = false;//无下一个
memcpy(finfo.szFileName, strFilePath.c_str(), strFilePath.size());//直接返回路径名表示无权限访问该目录
CPacket pack(7, (BYTE*) & finfo, sizeof(finfo));
CServerSocket::GetInstance()->Send(pack);
OutputDebugString(_T("无权限访问目录!"));
return;
}
//当前工作目录切换成功后
_finddata_t fdata;//文件的基本信息的结构体:文件名,文件大小等等基本属性
int hfind = 0;//用于表示找到后的文件句柄
if((hfind = _findfirst("*",&fdata)) == -1){//
OutputDebugString(_T("没有找到任何文件!"));
return;
}
//存在第一个文件,即有文件,且获得了该文件的句柄hfind
do {
FILEINFO finfo;
finfo.IsDirectory = (fdata.attrib & _A_SUBDIR) != 0;//true表示目录,false表示文件
memcpy(finfo.szFileName, fdata.name, strlen(fdata.name));
CPacket pack(7, (BYTE*)&finfo, sizeof(finfo));
CServerSocket::GetInstance()->Send(pack);
} while (!_findnext(hfind, &fdata));//尝试寻找hfind句柄的下一个文件,然后把信息传给fdata
FILEINFO finfo;
finfo.HasNext = false;
CPacket pack(7, (BYTE*)&finfo, sizeof(finfo));
CServerSocket::GetInstance()->Send(pack);
}