博文1
转载自:
/grey_csdn/article/details/76944630
仅供学习使用,禁止转载,如果有侵权请联系及时删除。
GNU的C语言库其实功能还是很强大的,不过这方面我了解学习的确实是不多。最近又接触到了一个文件访问操作的函数,之前觉得只有高级语言才能够实现,没想到借用glibc用C语言实现起来也蛮简单的。这个函数的声明在io.h中,但是网络上的很多文章都写错了。不过,他们说的头文件恰好包含了io.h文件,因此代码上倒是没有什么大的问题。
关于文件的访问模式,在io.h文件中有如下宏定义:
/* Some defines for _access nAccessMode (MSdoesn't define them, but
* it doesn't seem to hurt to add them). */
#define F_OK 0 /* Check for file existence */
#define X_OK 1 /* Check for execute permission. */
#define W_OK 2 /* Check for write permission */
#define R_OK 4 /* Check for read permission *
从代码的注释中可以看到,在Windows系统中这个似乎是没有用的。看来,这个功能是专门为unix-linke的系统设计的。不过,相应的参数应该还是可以使用,只是结果或许不是我们想要的。
函数的原型如下:
_CRTIMP int __cdecl _access(const char*_Filename,int _AccessMode)
写一段测试代码如下:
#include"stdio.h"
#include"io.h"
int main(void)
{
if(access("./access_demo.c",F_OK)==0)
{
printf("fileexists!\n");
}
if(access("./access_demo.c",X_OK)==0)
{
printf("file can beexecuted!\n");
}
if(access("./access_demo.c",W_OK)==0)
{
printf("file can bewritten!\n");
}
if(access("./access_demo.c",R_OK)==0)
{
printf("file can beread!\n");
}
return 0;
}
代码编译后程序执行结果如下:
E:\01_workSpace\02_programme_language\01_clang\\08\08>gccaccess_demo.c
E:\01_workSpace\02_programme_language\01_clang\\08\08>a
file exists!
file can beexecuted!
file can bewritten!
file can be read!
从上面的结果可以看出,在Windows下面其实这个函数只是提供了这样的一个接口,其实并没有相应的功能。
grant-bobo:博主,你确定有#include"io.h"这个头文件吗?2年前回复
码农grey_csdn回复Ciruy B.Heimerdinger:C:\Strawberry\c\x86_64-w64-mingw32\include 版本:This is perl 5, version 30, subversion 0 (v5.30.0) built for MSWin32-x64-multi-thread1年前回复
Ciruy B.Heimerdinger回复:这就很有意思了= =1年前回复
码农grey_csdn回复:如果找不到的话,可能我们用的环境不同。你可以下载安装Strawberry Perl,里面内置了C的一些工具和库文件。我使用的是这样的环境。2年前回复
xin_lingxiao:通过man命令看,access函数是在unistd.h里的,不知题主是在哪看的?2年前回复
码农grey_csdn回复:这个是我自己找到的,我使用的环境跟你不一样。你说了你用man,那应该是在UNIX或者Linux或者是其仿真环境中做的,而我是用的Windows。具体的文件查看是在Strawberry Perl中自带的GNU工具中看到的。2年前回复
博文2
在Linux下,access函数的声明在<unistd.h>文件中,声明如下:
int access(const char *pathname, int mode);
access函数用来判断指定的文件或目录是否存在(F_OK),已存在的文件或目录是否有可读(R_OK)、可写(W_OK)、可执行(X_OK)权限。F_OK、R_OK、W_OK、X_OK这四种方式通过access函数中的第二个参数mode指定。如果指定的方式有效,则此函数返回0,否则返回-1。
在Windows下没有access函数,但在<io.h>文件中有_access函数,声明如下:
int _access(const char* _Filename, int _AccessMode);
windows下的函数_access与linux下的access函数功能类似,用来判断指定的文件或目录是否仅存在(00),已存在的文件或目录是否有仅读(04)、仅写(02)、既可读又可写(06)权限。这四种方式通过_access函数中的第二个参数mode指定,如果mode传入的值不是0或2或4或6,调用此函数则会crash。如果指定的方式有效,则此函数返回0,否则返回-1。
以下是测试代码(access.cpp):
#include "access.hpp"
#include <iostream>
#include <vector>
#include <string>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif
namespace access_ {
int test_access_1()
{
#ifdef _MSC_VER
const std::string path{ "E:/GitCode/Messy_Test/" };
const std::vector<const std::string> names {"testdata", ".gitignore", "src", "invalid"};
for (auto& name : names) {
const std::string tmp = path + name;
fprintf(stdout, "file or directory name: \"%s\": ", name.c_str());
if (_access(tmp.c_str(), 0) == 0) fprintf(stdout, "exist, ");
else fprintf(stdout, "not exist, ");
if (_access(tmp.c_str(), 4) == 0) fprintf(stdout, "only has read premission, ");
else fprintf(stdout, "does not have read premission, ");
if (_access(tmp.c_str(), 2) == 0) fprintf(stdout, "only has write premission, ");
else fprintf(stdout, "does not have write premission, ");
if (_access(tmp.c_str(), 6) == 0) fprintf(stdout, "has both read and write premission\n");
else fprintf(stdout, "has neither read nor write premission\n");
}
#else
const std::vector<const char*> names {"testdata", "CMakeLists.txt", "build.sh", "invalid"};
for (auto name : names) {
fprintf(stdout, "file or directory name: \"%s\": ", name);
if (access(name, F_OK) == 0) fprintf(stdout, "exist, ");
else fprintf(stdout, "not exist, ", name);
if (access(name, R_OK) == 0) fprintf(stdout, "has read premission, ");
else fprintf(stdout, "does not have read premission, ");
if (access(name, W_OK) == 0) fprintf(stdout, "has write premission, ");
else fprintf(stdout, "does not have write premission, ");
if (access(name, X_OK) == 0) fprintf(stdout, "has execute premission\n");
else fprintf(stdout, "does not have execute premission\n");
}
#endif
return 0;
}
} // namespace access_
在Linux下的执行结果如下:
GitHub://fengbingchun/Messy_Test
————————————————
版权声明:本文为CSDN博主「fengbingchun」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:/fengbingchun/article/details/100342049/
自己增加如果文件不存在创建文件:
#include <sys/stat.h>#include <sys/types.h>if(access(file_name, F_OK) != 0){int mkdir_ret = mkdir(file_name, 0777);ASSERT(mkdir_ret != 0);}