使用阿里云Oss官方提供的C开发包编译时会遇到一些小问题,比如“error LNK2019: 无法解析的外部符号”、缺少文件“libapr-1.dll”等,针对这些问题修改项目后,并且把函数封装成类函数方便使用。
首先说下增加的功能:
1.下载bucket下所有文件(不包括bucket中文件夹内的文件);
2.获取bucket下所有文件名称以及一级文件夹(最接近bucket的文件夹);
3.获取指定文件夹内的所有文件(不包括指定文件夹内的下一级文件夹内的文件,如果需要下载下一级文件夹内的文件可以指定下一级文件夹进行获取文件名称进行下载,更深层的文件夹也是这样);
4.上传文件时,如果创建类对象指定MD5认证,将会生成文件名加_verify.txt组成的校验文件并且上传。
5.下载文件时,如果创建类对象指定MD5认证,首先从Oss平台下载校验文件进行比较,如果本地存在相同的校验文件或者没有下载到校验文件,那么下载文件将会失败。
6.下载的文件只需要指定本地保存文件的一级文件夹或者指定盘的根目录,程序会自动判断指定下载的文件如果在文件夹内,将会在本地的一级文件夹内创建于下载文件相同的文件夹并将文件保存在内;
下面贴上部分封装类的实现方式:
.h文件:
#include "oss_.h"
class Coss : public Oss_Api
{
public:
//构造函数默认不启动校验,传true为启动校验:下载文件时将检查Oss服务器与本地文件校验匹配,匹配成功再下载文件
Coss(bool bverify = false);
virtual ~Coss();
public:
//初始化Oss连接信息(需要第一个调用)
bool InitOssConnectInfo(char * Endpoint,char *Access_Key_Id,char *Access_Key_Secret);
//获取获取bucket内所有文件夹以及文件名
bool GetOssbucketAllDirs(In char *bucket,Out std::vector<char *> & Dir_name,Out std::vector<char *> & File_name);
//获取bucket内指定文件夹的所有文件夹以及文件名 文件名以 文件夹/文件名的形式保存
bool GetbucketAllFiles(In char *bucket,In char *Dir,Out std::vector<char *> & Dir_name,Out std::vector<char *> & File_name);
//下载指定文件
//参数二 文件名,如果在文件夹内以文件夹/文件名的形式下载
//参数三 需要保存到本地的路径(如果指定到文件夹内,需要保证文件夹存在)
//参数四 如果本地有相同的文件是否覆盖 1覆盖 0不覆盖
bool DownLoadFile(In char *bucket,In char *Filename,In char *Local_Path,bool bcover);
//下载bucket内的所有文件(不包括文件夹内的文件)
//参数二 需要保存到本地的路径(如果指定到文件夹内,需要保证文件夹存在)
//参数三 如果本地有相同的文件是否覆盖 1覆盖 0不覆盖
bool DownLoadbucketAllFiles(In char *bucket,In char *Local_Path,bool bcover);
//获取bucket内指定文件夹的所有文件
bool DownLoadDirAllFiles(In char *bucket,In char *Dir,In char *Local_Path,bool bcover);
//上传指定文件以及校验文件,启动校验的情况下 如果没有校验文件 上传失败
bool UploadFile(In char *bucket_name,In char *object_name,In char *file_name,In char *file_type);
//在bucket内创建文件夹
bool Createdir(In char *bucket_name,In char *dir_name);
//删除指定文件
bool DeleteFile(In char *bucket_name,In char *object_name);
//删除指定文件夹内所有文件
bool DeleteFileFromDir(In char *bucket_name,In char *dir_name);
private:
//校验文件 -1没有找到本地校验文件,-2没有下载到Oss校验文件,0校验错误,1校验成功
int verifyFile(In char *bucket,In char *Filename,In char *Local_Path);
//创建文件夹
BOOL CreateFolder(CString szPath);
//如果启动校验 检查校验文件是否存在 并且上传校验文件,如果没有启动校验 返回true,并且不上传校验文件
bool UpLoadverifyFile(In char *bucket_name,In char *object_name,In char *file_name,In char *file_type);
private:
//1启动校验 0不启动校验
bool m_bverify;
};
.cpp文件:
#include "afxcmn.h"
#include
#include "Coss.h"
#include "MiniAppConfig.hpp"
#include "../../Md5File/Md5.hpp"
Coss::Coss(bool bverify):m_bverify(bverify)
{
}
Coss::~Coss()
{
}
//初始化Oss连接信息(需要第一个调用)
bool Coss::InitOssConnectInfo(char * Endpoint,char *Access_Key_Id,char *Access_Key_Secret)
{
return InitConnectInfo(Endpoint,Access_Key_Id,Access_Key_Secret);
}
//获取获取bucket内所有文件夹以及文件名
bool Coss::GetOssbucketAllDirs(In char *bucket,Out std::vector<char *> & Dir_name,Out std::vector<char *> & File_name)
{
Dir_name.clear();
File_name.clear();
return getbucketAllFile(bucket,"",Dir_name,File_name);
}
//获取bucket内指定文件夹的所有文件
bool Coss::GetbucketAllFiles(In char *bucket,In char *Dir,Out std::vector<char *> & Dir_name,Out std::vector<char *> & File_name)
{
return getbucketAllFile(bucket,Dir,Dir_name,File_name);
}
//下载指定文件
//参数二 文件名,如果在文件夹内以文件夹/文件名的形式下载
//参数三 需要保存到本地的路径(如果指定到文件夹内,需要保证文件夹存在)
//参数四 如果本地有相同的文件是否覆盖 1覆盖 0不覆盖
bool Coss::DownLoadFile(In char *bucket,In char *Filename,In char *Local_Path,bool bcover)
{
if (0 == bucket || 0 == Filename || 0 == Local_Path)
return false;
char LocalPath[512] = {0};
memcpy(LocalPath,Local_Path,strlen(Local_Path));
memcpy(LocalPath + strlen(LocalPath),Filename,strlen(Filename));
Replace(LocalPath,'/','\\');
//判断文件夹是否存在,不存在就创建
if (-1 == access(LocalPath,0))
CreateFolder(LocalPath);
//首先校验文件
int nVal = verifyFile(bucket,Filename,Local_Path);
if (-1 != nVal && 0 != nVal)
return false;
if (!bcover && 0 == nVal)
return false;
//下载
return get_object_to_local_file(bucket,Filename,LocalPath);
}
//下载bucket内的所有文件(不包括文件夹内的文件)
//参数二 需要保存到本地的路径
//参数三 如果本地有相同的文件是否覆盖 1覆盖 0不覆盖
bool Coss::DownLoadbucketAllFiles(In char *bucket,In char *Local_Path,bool bcover)
{
std::vector<char *> Dir_name;
std::vector<char *> File_name;
if (getbucketAllFile(bucket,"",Dir_name,File_name))
{
if (0 < File_name.size())
{
for (auto it = File_name.begin();it != File_name.end();it++)
{
DownLoadFile(bucket,*it,Local_Path,bcover);
}
}
}
return true;
}
//校验文件
int Coss::verifyFile(In char *bucket,In char *Filename,In char *Local_Path)
{
//不启动校验直接下载
if (0 == m_bverify)
return -1;
char LocalFile[512] = {0};
char File_name[256] = {0};
int nNum = FindData(Filename,".");
//如果没有找到.直接返回
if (-1 == nNum)
return -1;
memcpy(File_name,Filename,nNum);
memcpy(File_name + strlen(File_name),"_verify.txt",strlen("_verify.txt"));
memcpy(LocalFile,Local_Path,strlen(Local_Path));
memcpy(LocalFile + strlen(LocalFile),File_name,strlen(File_name));
Replace(LocalFile,'/','\\');
USES_CONVERSION;
//首先打开本地文件
if (-1 == access(LocalFile,0))
{
if (!get_object_to_local_file(bucket,File_name,LocalFile))
return -2;
else
return -1;
}
//配置路径
AppConfig::Initialize_Path(A2T(LocalFile));
CString Local_verify = AppConfig::GetString(_T("verify"),_T("info"),_T(""));
char OssFile[512] = {0};
memcpy(OssFile,Local_Path,strlen(Local_Path));
memcpy(OssFile + strlen(OssFile),Filename,nNum);
memcpy(OssFile + strlen(OssFile),"_verifytemp.txt",strlen("_verifytemp.txt"));
Replace(OssFile,'/','\\');
//下载Oss校验文件进行对比
if (!get_object_to_local_file(bucket,File_name,OssFile))
return -2;
AppConfig::Initialize_Path(A2T(OssFile));
CString Oss_verify = AppConfig::GetString(_T("verify"),_T("info"),_T(""));
//校验成功
if (Local_verify == Oss_verify)
{
//删除Oss校验文件
int nResult = remove(OssFile);
return 1;
}
else
{
//覆盖本地文件
int nResult = rename(OssFile,LocalFile);
return 0;
}
return 0;
}
//创建文件夹
BOOL Coss::CreateFolder(CString szPath)
{
CString strDir(szPath); //存放要创建的目录字符串
if (strDir.GetAt(strDir.GetLength() - 1) != _T('\\')) //确保以'\'结尾以创建最后一个目录
{
strDir.AppendChar(_T('\\'));
}
std::vector vPath; //存放每一层目录字符串
CString strTemp; //一个临时变量,存放目录字符串
bool bSuccess = false; //成功标志
//遍历要创建的字符串
for (int i = 0; i < strDir.GetLength(); ++i)
{
if (strDir.GetAt(i) != _T('\\'))
{ //如果当前字符不是'\\'
strTemp.AppendChar(strDir.GetAt(i));
}
else
{ //如果当前字符是'\\'
vPath.push_back(strTemp); //将当前层的字符串添加到数组中
strTemp.AppendChar(_T('\\'));
}
}
//遍历存放目录的数组,创建每层目录
std::vector ::iterator vIter;
for (vIter = vPath.begin(); vIter != vPath.end(); vIter++)
{
if (!PathIsDirectory(*vIter)) //判断当前目录时候存在,不存在就创建
{
if (0 <= (*vIter).Find(_T(".")))
{
continue;
}
//如果CreateDirectory执行成功,返回true,否则返回false
bSuccess = CreateDirectory(*vIter, NULL) ? true : false;
}
}
return bSuccess;
}
//获取bucket内指定文件夹的所有文件
bool Coss::DownLoadDirAllFiles(In char *bucket,In char *Dir,In char *Local_Path,bool bcover)
{
//判断文件夹是否存在,不存在就创建
if (-1 == access(Local_Path,0))
CreateFolder(Local_Path);
std::vector<char *> Dir_name;
std::vector<char *> File_name;
if (getbucketAllFile(bucket,Dir,Dir_name,File_name))
{
if (0 < File_name.size())
{
for (auto it = File_name.begin();it != File_name.end();it++)
{
DownLoadFile(bucket,*it,Local_Path,bcover);
}
}
}
return true;
}
//上传指定文件以及校验文件,启动校验的情况下 如果没有校验文件 上传失败
bool Coss::UploadFile(In char *bucket_name,In char *object_name,In char *file_name,In char *file_type)
{
if (0 == bucket_name || 0 == object_name || 0 == file_name || 0 == file_type)
return false;
//剪切掉/之前的路径
char * FileName = ReSetStr(object_name,"/");
char LocalFile[512] = {0};
memcpy(LocalFile,file_name,strlen(file_name));
memcpy(LocalFile + strlen(LocalFile),FileName,strlen(FileName));
delete FileName;
Replace(LocalFile,'/','\\');
if (-1 == access(LocalFile,0))
return false;
//启动校验的情况下,判断校验文件是否存在
if (!UpLoadverifyFile(bucket_name,object_name,file_name,file_type))
return false;
//上传文件
return put_object_from_file(bucket_name,object_name,LocalFile,file_type);
}
//如果启动校验 检查校验文件是否存在 并且上传校验文件,如果没有启动校验 返回true,并且不上传校验文件
bool Coss::UpLoadverifyFile(In char *bucket_name,In char *object_name,In char *file_name,In char *file_type)
{
if (0 == m_bverify)
return true;
int nNum = FindData(object_name,".");
//如果没有找到.直接返回
if (-1 == nNum)
return false;
USES_CONVERSION;
char Localverify[512] = {0};
char verifyFile[256] = {0};
memcpy(verifyFile,object_name,nNum);
memcpy(verifyFile + strlen(verifyFile),"_verify.txt",strlen("_verify.txt"));
memcpy(Localverify,file_name,strlen(file_name));
char * FileName = ReSetStr(object_name,"/");
nNum = FindData(FileName,".");
memcpy(Localverify + strlen(Localverify),FileName,nNum);
memcpy(Localverify + strlen(Localverify),"_verify.txt",strlen("_verify.txt"));
Replace(Localverify,'/','\\');
//如果没有找到校验文件,那么自动生成校验文件
if (-1 == access(Localverify,0))
{
char LocalFile[512] = {0};
memcpy(LocalFile,file_name,strlen(file_name));
memcpy(LocalFile + strlen(LocalFile),FileName,strlen(FileName));
//首先获取文件校验值
char * StrMd5 = MD5_file(LocalFile,16);
AppConfig::Initialize_Path(A2T(Localverify));
AppConfig::WriteString(_T("verify"),_T("info"),A2T(StrMd5));
}
delete FileName;
return put_object_from_file(bucket_name,verifyFile,Localverify,"txt");
}
//在bucket内创建文件夹
bool Coss::Createdir(In char *bucket_name,In char *dir_name)
{
return create_dir(bucket_name,dir_name);
}
//删除指定文件
bool Coss::DeleteFile(In char *bucket_name,In char *object_name)
{
bool bVal = delete_object(bucket_name,object_name);
if (!m_bverify && bVal)
return true;
else if (!m_bverify && !bVal)
return false;
else if (m_bverify && !bVal)
return false;
//删除校验文件
char verifyFile[512] = {0};
memcpy(verifyFile,object_name,FindData(object_name,"."));
memcpy(verifyFile + strlen(verifyFile),"_verify.txt",strlen("_verify.txt"));
return delete_object(bucket_name,verifyFile);
}
//删除指定文件夹内所有文件
bool Coss::DeleteFileFromDir(In char *bucket_name,In char *dir_name)
{
std::vector<char *> Dir_name;
std::vector<char *> File_name;
bool bIs = false;
if (getbucketAllFile(bucket_name,dir_name,Dir_name,File_name))
{
if (0 < File_name.size())
{
for (auto it = File_name.begin();it != File_name.end();it++)
{
bIs = DeleteFile(bucket_name,*it);
}
}
}
return bIs;
}
下面贴上完整文件下载地址:https://download.csdn.net/download/a29562268/10406997。