1. 首先https://help.aliyun.com/document_detail/106216.html?spm=a2c4g.11186623.6.921.45171717JSWP5D 下载阿里云sdk源码,按照步骤编译出alibabacloud-oss-cpp-sdk.lib
2. 在UE工程文件夹下创建ThirdParty/Aliyun/include文件夹,然后把阿里云源码下的sdk/include 拷贝到ThirdParty/Aliyun/include下,创建ThirdParty/Aliyun/lib文件夹,把alibabacloud-oss-cpp-sdk.lib以及阿里云源码下的三方库文件
都拷贝到ThirdParty/Aliyun/lib文件夹下。
3. 在ue4 工程的 build.cs文件下添加
private string ModulePath
{
get { return ModuleDirectory; }
}
private string ThirdPartyPath
{
get { return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/")); }
}
public void LoadAliyun(ReadOnlyTargetRules Target)
{
// Start OpenCV linking here!
// Create OpenCV Path
string AliyunPath = Path.Combine(ThirdPartyPath, "Aliyun");
if (Target.Platform == UnrealTargetPlatform.Win64)
{
//Add Include path
PublicIncludePaths.AddRange(new string[] { Path.Combine(AliyunPath, "include") });
//PublicIncludePaths.AddRange(new string[] { Path.Combine(AliyunPath, "sdk/src") });
//PublicIncludePaths.AddRange(new string[] { Path.Combine(AliyunPath, "third_party/include") });
//该文章为CSDN博主执手画眉弯原创
string LibPath = Path.Combine(AliyunPath, "lib");
PublicLibraryPaths.Add(LibPath);
PublicAdditionalLibraries.Add(LibPath + "/alibabacloud-oss-cpp-sdk.lib");
//Add Static Libraries
PublicAdditionalLibraries.Add(LibPath + "/libcurl.lib");
PublicAdditionalLibraries.Add(LibPath + "/libeay32.lib");
PublicAdditionalLibraries.Add(LibPath + "/ssleay32.lib");
//Add Dynamic Libraries
PublicDelayLoadDLLs.Add(LibPath + "/libcurl.dll");
PublicDelayLoadDLLs.Add(LibPath + "/libeay32.dll");
PublicDelayLoadDLLs.Add(LibPath + "/ssleay32.dll");
PublicDelayLoadDLLs.Add(LibPath + "/zlibwapi.dll");
//RuntimeDependencies.Add("$(PluginDir)/Binaries/Win64/zlibwapi.dll");
}
}
记得在工程的主构造中调用LoadAliyun(target);
运行时候需要手动把alibabacloud-oss-cpp-sdk.lib和4个相关dll文件拷贝到工程的/Binaries/Win64文件夹下。
4. 上传文件的实例
.h 文件
#pragma once
#include "CoreMinimal.h"
#if PLATFORM_WINDOWS
#include <string>
#endif
/* 阿里云信息 管理文件
*
*/
class MYUE4PROJECT_API AliyunManager
{
private:
AliyunManager();
~AliyunManager();
//访问key id
std::string AccessKeyId;
//访问key 密钥
std::string AccessKeySecret;
//访问节点
std::string Endpoint;
//访问包名
std::string BucketName;
//是否已经读取了配置
uint8 bReadConfig : 1;
//是否在传输中
uint8 bInCross : 1;
private:
void ReadConfig();
public:
//单例
static AliyunManager&GetInstance()
{
static AliyunManager Inst;
return Inst;
}
//图片是否存在
bool IsPictureExists(const FString& PictureName);
//删除图片
void DeletePicture(const FString& PictureName);
//发送图片到oss
bool SendPictureToOss(const FString &PictureName);
//是否在传输过程中
const bool IsInCross() { return bInCross; }
};
#define gAliyunManager AliyunManager::GetInstance()
.cpp 文件
#include "AliyunManager.h"
#include "Config/GameConfig.h"
#if PLATFORM_WINDOWS
#include "alibabacloud/oss/OssClient.h"
#include <iostream>
#include <fstream>
#include "Windows/AllowWindowsPlatformTypes.h"
THIRD_PARTY_INCLUDES_START //lyh
#include <stringapiset.h>
THIRD_PARTY_INCLUDES_END //lyh
#include "Windows/HideWindowsPlatformTypes.h"
#endif
DEFINE_LOG_CATEGORY_STATIC(FXKAliyunLog, Log, All);
void UTF8ToGBK(char *&szOut)
{
unsigned short *wszGBK;
char *szGBK;
//长度
int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)szOut, -1, NULL, 0);
wszGBK = new unsigned short[len + 1];
memset(wszGBK, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)szOut, -1, (LPWSTR)wszGBK, len);
//长度
len = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
szGBK = new char[len + 1];
memset(szGBK, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, szGBK, len, NULL, NULL);
//szOut = szGBK; //这样得到的szOut不正确,因为此句意义是将szGBK的首地址赋给szOut,当delete []szGBK执行后szGBK的内
//存空间将被释放,此时将得不到szOut的内容
memset(szOut, '/0', strlen(szGBK) + 1); //改将szGBK的内容赋给szOut ,这样即使szGBK被释放也能得到正确的值
//memcpy(szOut, szGBK, strlen(szGBK));
strcpy_s(szOut, 512, szGBK);
delete[]szGBK;
delete[]wszGBK;
}
AliyunManager::AliyunManager()
{
bInCross = false;
ReadConfig();
}
AliyunManager::~AliyunManager()
{
}
void AliyunManager::ReadConfig()
{
/* 初始化OSS账号信息 */
//gGameConfig是自己写的配置管理文件,这里可以直接填阿里云对应的字符串
AccessKeyId = TCHAR_TO_UTF8(*gGameConfig.GetAliyunAccessKeyID());
AccessKeySecret = TCHAR_TO_UTF8(*gGameConfig.GetAliyunAccessKeySecret());
Endpoint = TCHAR_TO_UTF8(*gGameConfig.GetAliyunEndpoint());
BucketName = TCHAR_TO_UTF8(*gGameConfig.GetAliyunBucketName());
bReadConfig = true;
}
bool AliyunManager::IsPictureExists(const FString& PictureName)
{
if (PictureName.IsEmpty())
return false;
FString PictureUrl = gGameConfig.GetSaveAddr() + PictureName;
if (IFileManager::Get().FileExists(*PictureUrl) == false)
return false;
return true;
}
void AliyunManager::DeletePicture(const FString& PictureName)
{
FString FilePath = gGameConfig.GetSaveAddr();
FilePath /= PictureName;
IFileManager::Get().Delete(*FilePath, true, true);
}
bool AliyunManager::SendPictureToOss(const FString& PictureName)
{
if (PictureName.IsEmpty())
return false;
FString PictureUrl = gGameConfig.GetSaveAddr();
PictureUrl /= PictureName;
if (IFileManager::Get().FileExists(*PictureUrl) == false)
return false;
#if PLATFORM_WINDOWS
bInCross = true;
/* 初始化网络等资源 */
AlibabaCloud::OSS::InitializeSdk();
//该文章为CSDN博主执手画眉弯原创
AlibabaCloud::OSS::ClientConfiguration conf;
AlibabaCloud::OSS::OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);
//不设置存储类型的话,阿里云会自动根据文件类型存储,比如png图片会是image/png
//图片格式在打开连接时候是预览,如果想要打开连接直接下载就要把类型设置为application/octet-stream
auto meta = AlibabaCloud::OSS::ObjectMetaData();
meta.setContentType("application/octet-stream");
FString OssPictureName = gGameConfig.GetAliyunPath();
OssPictureName /= PictureName;
std::string ObjectName = TCHAR_TO_UTF8(*OssPictureName);
//包含中文字符的路径要转为GBK编码,不然std::make_shared<std::fstream>读取文件会失败
std::string strPictureUrl = TCHAR_TO_UTF8(*PictureUrl);
char charPictureUrl[512] = { 0 };
strcpy_s(charPictureUrl, strPictureUrl.c_str());
char* pCharPictureUrl = charPictureUrl;
UTF8ToGBK(pCharPictureUrl);
std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(pCharPictureUrl, std::ios::in | std::ios::binary);
AlibabaCloud::OSS::PutObjectRequest request(BucketName, ObjectName, content, meta);
/*(可选)请参见如下示例设置存储类型及访问权限ACL*/
//request.MetaData().addHeader("x-oss-object-acl", "private");
//request.MetaData().addHeader("x-oss-storage-class", "Standard");
//
#if WITH_EDITOR
UE_LOG(FXKAliyunLog, Warning, TEXT("Aliyun PutObject Start:%s"), *PictureName);
#endif
auto outcome = client.PutObject(request);
if(outcome.isSuccess())
{
#if WITH_EDITOR
UE_LOG(FXKAliyunLog, Warning, TEXT("Aliyun PutObject Success:%s"), *PictureName);
#endif
/* 释放网络等资源 */
AlibabaCloud::OSS::ShutdownSdk();
bInCross = false;
return true;
}
/* 异常处理 */
FString ErrorCode = outcome.error().Code().c_str();
FString ErrorMessage = outcome.error().Message().c_str();
FString ErrorRequestId = outcome.error().RequestId().c_str();
UE_LOG(FXKAliyunLog, Error, TEXT("Aliyun PutObject Fail:%s , Code:%s, Message:%s, RequestId:%s"), *PictureName, *ErrorCode, *ErrorMessage, *ErrorRequestId);
/* 释放网络等资源 */
AlibabaCloud::OSS::ShutdownSdk();
bInCross = false;
#endif
return false;
}