wking's blog

  • 文章分类
    • 日常随笔
    • IT技术
    • 系统封装
    • 大航海时代
  • 关于博主
GOD'S IN HIS HEAVEN, ALL'S RIGHT WITH THE WORLD.
  1. 首页
  2. IT技术
  3. C++
  4. 正文

Windows C++ 可操作中文路径的文件/目录的检测、创建、重命名、删除、移动函数

2023-11-07 860点热度 74人点赞 0条评论

想要进行文件/目录的监测、创建、删除等操作,有好几种函数可以实现,但因为不同操作系统不兼容,可能同一个函数在linux可用,windows就不可用,而windows本身又有ansi、utf8、unicode好几种编码,所有函数都支持ANSI路径也就是纯英文路径,但遇到中文路径大部分操作函数就失效,总结就是这些函数简直乱成一锅粥。

这里做个备忘录,整理一下windows下可用的文件/目录操作函数。每个函数的详细介绍、参数解释,请自行前往微软MSDN查看。

优先使用宽字符集版本函数

比如_stat函数有_stat()和_wstat()宽字符集版本,优先使用宽字符集版本,以便更好的支持中文路径或其他非ANSI语言。

判断文件或目录是否存在

_waccess_s()或_stat()都可以,_waccess_s()更简便。

_waccess_s

_waccess_s()是_access()函数的宽字符集更安全版本,可判断文件或目录是否存在(官方链接)。

返回值,0=存在,2或ENOENT=不存在。

C++
1
2
3
4
5
6
7
8
9
// 文件
if (_waccess_s(L"c:\\test\\test.exe", 0) == 0)
 
// 目录
if (_waccess_s(L"c:\\test", 0) == 0)
 
// 用变量
wstring path(L"c:\\test\\test.exe");
if (_waccess_s(path.data(), 0) == 0)

_stat

_stat()也可以判断文件或目录是否存在(官方链接),但是用此函数需要先申明一个结构体变量用于保存文件的详细权限,只用于判断文件是否存在是没必要这么麻烦。

另外不带下划线的stat()函数只能对纯英文路径判断,不能判断带中文的路径,我被这个函数坑了很久。

创建目录

1
2
3
4
5
6
7
// 参数2是指定文件/目录属性,如没有特殊需求可为空指针
 
// 直接用字符串
CreateDirectory(L"c:\\test", nullptr);
 
// 使用变量
CreateDirectory(wstring.data(), nullptr);

移动文件

C++
1
MoveFile(wstring_filepath.data(), wstring_newpath.data());

复制文件

C++
1
CopyFile(wstring_filepath.data(), wstring_newpath.data(), FALSE);

删除文件

C++
1
DeleteFile(wstring_filepath.data());

重命名

网上介绍的rename()函数不支持中文。我直接用复制后删除的办法。

C++
1
2
3
4
if (_waccess_s(wstring_filepath.data(), 0) == 0) {
  if (CopyFile(wstring_filepath.data(), wstring_newfilepath.data(), FALSE))
  DeleteFile(wstring_filepath.data());
}

删除目录

因为函数只能删除空目录,所以可以直接写一个封装函数遍历删除目录内的所有文件和子目录。需要删除目录的时候直接调用此函数即可。

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void remove_allfiles(const wstring& wstrDir) {
  if (wstrDir.empty()) {
    return;
  }
  WIN32_FIND_DATA findData;
  const wstring wstrTempDir = wstrDir + L"\\*";
  const HANDLE hFind = FindFirstFile(wstrTempDir.c_str(), &findData);
  if (hFind == INVALID_HANDLE_VALUE) {
    return;
  }
  do {
    // 忽略"."和".."两个结果
    if (wcscmp(findData.cFileName, L".") == 0 || wcscmp(findData.cFileName, L"..") == 0) {
      continue;
    }
    wstring wstrFileName;
    wstrFileName.assign(wstrDir);
    wstrFileName.append(L"\\");
    wstrFileName.append(findData.cFileName);
    if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)// 是否是目录
    {
      remove_allfiles(wstrFileName);
    }
    else {
      DeleteFile(wstrFileName.c_str());
    }
  }
  while (FindNextFile(hFind, &findData));
  FindClose(hFind);
  RemoveDirectory(wstrDir.c_str());
}
本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: C++
最后更新:2024-12-15

wking

不管博客型博主

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

目录
  • 优先使用宽字符集版本函数
  • 判断文件或目录是否存在
    • _waccess_s
    • _stat
  • 创建目录
  • 移动文件
  • 复制文件
  • 删除文件
  • 重命名
  • 删除目录
标签聚合
大航海时代 wordpress 一支红杏 C++ win10 linux R6300V2 OneNote

COPYRIGHT © 2024 wkings.blog. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang