// YANGJEE_CUsuallyFunction.h 文件内容:
#pragma once
#include <atomic>
#include <string>
namespace YANGJEE {
class YANGJEE_CUsuallyFunction {
static std::atomic<bool> cancelToken;
static std::atomic<bool> networkInit;
public:
// 检查文件是否存在
static bool fileExists(const std::string& filePath);
static void initializeNetwork(); // 新增初始化函数
private:
static bool isNetworkAvailable(const std::string& path);
static std::string normalizePath(const std::string& path);
};
}
// YANGJEE_CUsuallyFunction.cpp 文件内容:
#include "YANGJEE_CUsuallyFunction.h"
//#include "YANGJEE_UfunBasic.h"
using namespace std;
//using namespace YANGJEE;
using std::string;
//获取网卡物理地址
#include <winsock2.h>
#include <Iphlpapi.h>
#include <stdio.h>
#include <chrono>
#include <fstream>
#include <future>
#include <system_error> // for std::errc
#ifdef _WIN32
#include <windows.h>
#include <winnetwk.h>
#include <lm.h> // 包含网络资源类型定义
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "netapi32.lib") // Windows网络库
#pragma comment(lib, "mpr.lib") // 添加网络库链接
//#else
#include <sys/stat.h>
//#include <unistd.h>
#endif
std::atomic<bool> YANGJEE::YANGJEE_CUsuallyFunction::cancelToken(false);
std::atomic<bool> YANGJEE::YANGJEE_CUsuallyFunction::networkInit(false); // 新增初始化标志
// 新增网络初始化函数
void YANGJEE::YANGJEE_CUsuallyFunction::initializeNetwork() {
#ifdef _WIN32
if (!networkInit.exchange(true)) {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
throw std::runtime_error("WSAStartup failed");
}
}
#endif
}
// 检查文件是否存在 //超时关闭
bool YANGJEE::YANGJEE_CUsuallyFunction::fileExists(const std::string& filePath) {
try {
initializeNetwork(); // 确保网络初始化
const bool isNetworkPath =
(filePath.size() >= 2 && filePath[0] == '\\' && filePath[1] == '\\') ||
(filePath.find("/mnt/") == 0) ||
(filePath.find("/cifs/") == 0);
const auto timeout = isNetworkPath ?
std::chrono::seconds(3) :
std::chrono::milliseconds(500);
auto future = std::async(std::launch::async, [&]() -> bool {
try {
const auto sanitizedPath = normalizePath(filePath);
if (isNetworkPath && !isNetworkAvailable(sanitizedPath)) {
return false;
}
// 增强型取消检查(带内存屏障)
for (int i = 0; i < 30 && !cancelToken.load(std::memory_order_acquire); ++i) {
std::this_thread::sleep_for(100ms);
}
if (cancelToken.load(std::memory_order_relaxed)) return false;
#ifdef _WIN32
int wpath_len = MultiByteToWideChar(CP_UTF8, 0,
sanitizedPath.c_str(), -1, nullptr, 0);
if (wpath_len == 0) return false;
std::wstring wpath(wpath_len, 0);
MultiByteToWideChar(CP_UTF8, 0,
sanitizedPath.c_str(), -1, &wpath[0], wpath_len);
const DWORD attrs = GetFileAttributesW(wpath.c_str());
return (attrs != INVALID_FILE_ATTRIBUTES) &&
!(attrs & FILE_ATTRIBUTE_DIRECTORY);
#else
struct stat st;
return (stat(sanitizedPath.c_str(), &st) == 0) &&
S_ISREG(st.st_mode);
#endif
}
catch (const std::exception& ex) {
// 记录异常日志
return false;
}
catch (...) {
return false;
}
});
auto status = future.wait_for(timeout);
if (status == std::future_status::ready) {
return future.get();
}
// 安全取消流程
cancelToken.store(true, std::memory_order_release);
future.wait();
cancelToken.store(false, std::memory_order_relaxed);
}
catch (const std::exception& ex) {
// 记录初始化异常
return false;
}
catch (...) {
return false;
}
return false;
}
// 改进的网络可用性检查
bool YANGJEE::YANGJEE_CUsuallyFunction::isNetworkAvailable(const std::string& path) {
#ifdef _WIN32
try {
int wlen = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, NULL, 0);
if (wlen == 0) return false;
std::wstring wserverPath(wlen, 0);
MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, &wserverPath[0], wlen);
std::wstring serverName = wserverPath.substr(2, wserverPath.find(L'\\', 2) - 2);
wchar_t* nonConstServerName = _wcsdup(serverName.c_str());
if (!nonConstServerName) {
// LOG_ERROR("Memory allocation failed");
return false;
}
NETRESOURCEW nr = {
RESOURCE_GLOBALNET,
RESOURCETYPE_DISK,
RESOURCEDISPLAYTYPE_SERVER,
0,
NULL,
nonConstServerName,
NULL,
NULL
};
DWORD result = WNetAddConnection2W(&nr, NULL, NULL,
CONNECT_TEMPORARY | CONNECT_UPDATE_PROFILE);
free(nonConstServerName);
if (result == NO_ERROR) {
// 安全断开连接
DWORD cancelResult = WNetCancelConnection2W(serverName.c_str(), 0, TRUE);
if (cancelResult != NO_ERROR) {
// LOG_WARN("Failed to disconnect: {}", cancelResult);
}
return true;
}
if (result == ERROR_EXTENDED_ERROR) {
DWORD errCode = 0;
WCHAR errorBuf[256] = { 0 };
WCHAR providerBuf[256] = { 0 };
DWORD bufSize = sizeof(errorBuf) / sizeof(WCHAR);
DWORD provSize = sizeof(providerBuf) / sizeof(WCHAR);
DWORD errResult = WNetGetLastErrorW(
&errCode,
errorBuf,
bufSize,
providerBuf,
provSize
);
if (errResult == NO_ERROR) {
// LOG_ERROR("Network error [{}]: {}", errCode, errorBuf);
}
return false;
}
return (result == ERROR_SESSION_CREDENTIAL_CONFLICT) ||
(result == ERROR_NO_NETWORK);
}
catch (...) {
return false;
}
#else
return system("ping -c 1 8.8.8.8 > /dev/null 2>&1") == 0;
#endif
}
// 路径标准化
std::string YANGJEE::YANGJEE_CUsuallyFunction::normalizePath(const std::string& path) {
#ifdef _WIN32
std::string wPath = path;
std::replace(wPath.begin(), wPath.end(), '/', '\\');
// 处理超长路径(Windows)
if (wPath.length() >= 256) {
wPath = "\\\\?\\" + wPath;
}
size_t pos = 2;
while ((pos = wPath.find('\\', pos)) != std::string::npos) {
wPath.replace(pos, 1, 1, '/');
pos += 2;
}
return wPath;
#else
return path;
#endif
}
我在项目中的调用方式:
std::string YANGJEENXAnthorizefilePath = R"(\\\\192.168.70.165\\渝岚专用区\\重庆渝岚模具有限公司\\渝岚数据盘\\杨小林\\临时文件\\YANGJEE-SIEMENS_PLM_NX_Tools\\Anthorize\\YANGJEENXAnthorize.txt)";
YANGJEE::YANGJEE_CUsuallyFunction::initializeNetwork();
try {
if (YANGJEE::YANGJEE_CUsuallyFunction::fileExists(YANGJEENXAnthorizefilePath)) {
}
else {
// 处理文件不存在或网络错误
}
}
catch (const std::exception& ex) {
// 处理异常
}
帮我检查一下上述代码。现在的问题是及时网络连接良好,并且手动可以访问YANGJEENXAnthorizefilePath文件,但在项目中却抛出“处理文件不存在或网络错误”;而且还会造成开发的软件直接崩溃掉,运行系统windows10。
帮我把代码优化后完整的展现出来