C++ 为什么在使用_访问时只读测试对读写文件有效?

C++ 为什么在使用_访问时只读测试对读写文件有效?,c++,c,posix,msdn,C++,C,Posix,Msdn,在一个使用一些Microsoft文件I/O函数的CPP应用程序中,我遇到了一些类似于POSIXAPI的访问函数的用法。它似乎不是一个标准的C函数。为了确保我理解它是如何工作的,我编写了以下单元测试函数 TEST_F(TestFileIOApis, FileReadWriteTest) { const char* fileName = "newfile.txt"; FILE *fp = fopen(fileName, "w+"); // It's rather strange to

在一个使用一些Microsoft文件I/O函数的CPP应用程序中,我遇到了一些类似于POSIXAPI的访问函数的用法。它似乎不是一个标准的C函数。为了确保我理解它是如何工作的,我编写了以下单元测试函数

TEST_F(TestFileIOApis, FileReadWriteTest)
{
  const char* fileName = "newfile.txt";
  FILE *fp = fopen(fileName, "w+");

  // It's rather strange to me that the read-only and write-only tests work this way
  // for a read-write efile.
  auto result = _access(fileName, 4);
  EXPECT_EQ(result, 0);
  EXPECT_EQ(errno, EINVAL);

  result = _access(fileName, 2);
  EXPECT_EQ(result, 0);
  EXPECT_EQ(errno, EINVAL);

  result = _access(fileName, 0);
  EXPECT_EQ(result, 0);
  EXPECT_EQ(errno, EINVAL);

  result = _access(fileName, 6);
  EXPECT_EQ(result, 0);
  EXPECT_EQ(errno, EINVAL);

  fclose(fp);
  fp = 0;
}
也许文档的措辞不清楚,但对我来说只读意味着只读,不可读。因为我创建了一个读/写文件,所以我希望只读和只读测试失败。这显然不是Microsoft实现的工作方式。我可以找到的关于access函数的posix文档并没有以相同的方式描述修饰符,因为unix/posix文档使用了F_OK、R_OK等常量

作为后续:我看到的行为是否与这里描述的在Linux机器上的工作方式一致?

Microsoft文档在这里。

是的,Linux
access
将以同样的方式工作

问题在于您如何看待“只读”。检查只读访问方式

仅检查我是否可以读取该文件

不是

检查我是否只能读取该文件

它不是在寻找只读权限,而是在预测以只读模式打开文件是否会成功

请注意,它实际上也没有做到这一点;文件上说

它不检查文件系统安全设置

这使得
\u access()
在Windows上完全一文不值



此外,您似乎认为创建文件时
fopen
参数“w+”
对以后的
\u access()
调用有一定影响。事实并非如此
access()
正在测试文件名在打开时可以使用的模式,而不是测试打开句柄(Linux等价物:文件描述符)的打开模式。新创建的文件的权限受其所在目录和umask权限的影响,而不是初始模式。

在POSIX系统上,被称为
R_OK
W_OK
X_OK
;这使得他们检查是否可以打开文件进行读、写或执行更加清楚了。@AlexP:是的,但是要想知道你是否有两种能力,你应该将它们与
bitor
而不是
结合起来<代码>如果(访问(文件名,R_OK和W_OK))
没有测试它的建议…@BenVoigt:这是一个位掩码。当然,您可以将它们与
|
组合在一起。我突然想到,您对流状态的看法是正确的。我必须使用_chmod设置读写位,以便访问检查工作。然而,如果微软实现了它,它怎么可能在windows上一文不值呢?为什么要实现一个毫无价值的功能?我还不确定我是否买了它,但我会再测试一点,看看会发生什么。@shawn1874:实现一个没有价值的函数的一个原因是为了让为使用它而编写的代码(可能是首先为Linux编写的)能够编译和运行。在
access()
的特殊情况下,由于TOCTOU问题,它在任何操作系统上都几乎没有用处,在所有情况下简单地返回成功可能会使许多软件工作,而忽略该函数会导致链接错误。在执行全套单元测试后,chmod和access在windows上似乎工作正常。在消除了对只读意味着什么的误解后,我的测试现在开始工作。@shawn1874:您是使用当前用户没有权限的文件进行测试,还是只是切换只读属性?只是使用_chmod切换读/写属性。看起来我试图弄清楚的遗留代码只使用访问来确定文件是否存在。有时_chmod用于设置只读位。该代码似乎没有对权限或安全属性执行任何操作。