【发布时间】:2017-07-14 14:15:32
【问题描述】:
我正在尝试编写一个可以在 Linux 和 Windows 上使用的复制文件功能。它适用于 Linux,但在 Windows 上,尝试使用 WinApi 函数 CopyFile() 时出现错误代码 5。
在文件头文件.h中
这是我应该能够在 Linux 和 Windows 上使用的 File 命名空间中的自定义函数。
class File
{
public:
static bool copyFile(std::string source, std::string destination);
private:
}
在 File.cpp 中
对于 Linux,这很简单:
#ifdef __unix__
#include "File.h"
bool File::copyFile(std::string source, std::string destination)
{
std::string arg = source + " " + destination;
return launchProcess("cp", arg);
}
#endif
在 Windows 特定的代码块中,我使用 WinAPI (#include ) 函数 CopyFile()。这接受 LPCWSTR 数据类型而不是字符串。为了克服这个问题,我创建了一个将字符串转换为 LPCWSTR 类型的函数。
#ifdef _WIN32
#include "File.h"
#include <Windows.h>
std::wstring strtowstr(const std::string &str)
{
// Convert an ASCII string to a Unicode String
std::wstring wstrTo;
wchar_t *wszTo = new wchar_t[str.length() + 1];
wszTo[str.size()] = L'\0';
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wszTo,(int)str.length());
wstrTo = wszTo;
delete[] wszTo;
return wstrTo;
}
bool File::copyFile(std::string source, std::string destination)
{
std::wstring wsource = strtowstr(source);
std::wstring wdestination = strtowstr(destination);
int result = CopyFileW(wsource.c_str(), wdestination.c_str(), TRUE);
//for debugging...
std::wcout << "The error is " << GetLastError() <<std::endl;
std::wcout << wsource.c_str() << std::endl;
std::wcout << wdestination.c_str() << std::endl;
if (result == 0)
{
return false;
}
return true;
}
#endif
在我的测试程序中
TEST(all,main_copy_file)
{
std::cout << "Testing copyFile() function..." << std::endl;
std::string srcDir = File::currentWorkingDirectory() + "srcDir";
File::makeDirectory(srcDir);
std::string destDir = File::currentWorkingDirectory() + "destDir/";
File::makeDirectory(destDir);
File::makeFile(srcDir, "testFile", ".txt");
ASSERT_TRUE(File::fileExists(srcDir + "/testFile.txt")) << "Error: Test file has not been generated" << std::endl;
ASSERT_TRUE(File::directoryExists(destDir)) << "Error: Destination directory does not exist" <<std::endl;
ASSERT_TRUE(File::copyFile(srcDir + "/testFile.txt", destDir)) << "Error: Coppy unsucsessfull" << std::endl;
ASSERT_TRUE(File::fileExists(destDir + "/testFile.txt")) << "Error: CoppyFile() flagged as sucsessfull but file does not exist" << std::endl;
}
在应用程序中输出(在 Windows 上)
/*
Testing copyFile() function...
The error is 5
C:\GIT\CorteX\Externals\OSAL\build\Debug/srcDir/testFile.txt
C:\GIT\CorteX\Externals\OSAL\build\Debug/destDir/
error: Value of: File::copyFile(srcDir + "/testFile.txt", destDir)
Actual: false
Expected: true
Error: Coppy unsucsessfull
*/
错误代码 5 是拒绝访问错误。我认为当目录不存在、目录在其他地方打开或我没有权限时会出现此错误。
由于我已经测试过该目录确实存在,所以我认为它必须是后两者之一。我可能只有受限的管理员权限(我不知道),但我可以在没有管理员权限的情况下粘贴到“destDir”中。所以也许它认为目录是打开的?是否存在确保目录关闭的命令?
在Linux上运行时测试成功。
【问题讨论】:
-
请注意,C++ 已经提供了复制文件的功能。
-
你能指出其中一个/一些功能的方向吗?
-
您没有权限。如果其他人以独占访问权限打开文件夹 - 将是另一个错误 -
ERROR_SHARING_VIOLATION,如果文件/文件夹不存在 - 又将是另一个错误。如果文件已经存在并且是只读的,也会出现此错误 -
@RbMm 你猜我为什么没有权限?我只是想将文件从一个目录复制到另一个目录。这两个文件都在当前工作目录内的目录中,所以我应该没有问题,是吗?