C++ 为什么在windows下将属性更改为只读后可以写入文件?

C++ 为什么在windows下将属性更改为只读后可以写入文件?,c++,windows,C++,Windows,给定一个普通文件,它可以被读取和写入。然后我将此文件属性更改为只读 但是,该文件仍然可以通过文件处理程序写入。这是我的密码 #define CREATE_FILE_OPT FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS std::string name("test.txt"); HANDLE hfile = ::CreateFile(name.c_str(), GENERIC_READ

给定一个普通文件,它可以被读取和写入。然后我将此文件属性更改为
只读

但是,该文件仍然可以通过文件处理程序写入。这是我的密码

#define CREATE_FILE_OPT FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS
std::string name("test.txt");
HANDLE hfile = ::CreateFile(name.c_str(),
    GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, CREATE_FILE_OPT, NULL);

if (hfile == INVALID_HANDLE_VALUE) {
    hfile = ::CreateFile(name.c_str(),
        GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_NEW, CREATE_FILE_OPT, NULL);
    if (hfile == INVALID_HANDLE_VALUE) {
        printf("so sad, invalid file handler....");
        return -1;
    }
}

int i = 0;
char rbuf[] = "you are";
DWORD bytesWritten;
do {
    Sleep(5000);
    ++i;
    bytesWritten = 0;
    BOOL bret = ::WriteFile(hfile, rbuf, strlen(rbuf), &bytesWritten, NULL);
    if (bret == FALSE) {
        printf("Cannot write bytes into file.....");

        DWORD err = GetLastError();

        printf("The error code is %d\n", err);
    }
    else
        printf("write %d bytes to file\n", bytesWritten);

    DWORD ret = GetFileAttributes(name.c_str());
    printf("The file attribute is %d\n", ret);

} while (i < 10000);
#定义创建文件选择文件属性|正常|文件标志|写入|文件标志|随机访问|
std::字符串名称(“test.txt”);
HANDLE hfile=::CreateFile(name.c_str(),
泛型|泛型|写,NULL,NULL,打开|存在,创建|文件| OPT,NULL);
if(hfile==无效的句柄值){
hfile=::CreateFile(name.c_str(),
泛型|泛型|写,空,空,创建|新,创建|文件|选项,空);
if(hfile==无效的句柄值){
printf(“非常糟糕,无效的文件处理程序…”);
返回-1;
}
}
int i=0;
char rbuf[]=“你是”;
德沃德·拜特斯莱特;
做{
睡眠(5000);
++一,;
字节数=0;
BOOL-bret=::WriteFile(hfile、rbuf、strlen(rbuf)和byteswrited,NULL);
if(bret==FALSE){
printf(“无法将字节写入文件…”);
DWORD err=GetLastError();
printf(“错误代码是%d\n”,err);
}
其他的
printf(“将%d字节写入文件\n”,字节写入);
DWORD ret=GetFileAttributes(name.c_str());
printf(“文件属性为%d\n”,ret);
}而(i<10000);
在我将其更改为只读之前,文件属性是
32
,但在此文件为只读之后,它将是
33

我想知道为什么将文件更改为只读后可以写入该文件?我的测试代码有问题吗


PS:在windows 7下的VS2015中进行测试。

对不起,我终于明白你的意思了。我想你是说先创建一个文件,在不关闭程序的情况下将其设置为只读。
READONLY
属性检查仅在
CreateFile
例程中进行

在Windows内核中,每个对象在创建后都会被分配一个临时访问权限列表,除非显式刷新,否则在固定磁盘上的实际文件上很少发生这种情况。因此,即使您使用NTFS访问控制在
CreateFile
之后拒绝所有权限,您的程序的行为也将与调用
CreateFile
时一样


总之,在您将其热更改为“只读”后,您的程序仍然可以写入该文件是很自然的,它只将信息写入磁盘,而不更改内核访问表。

对不起,我终于明白您的意思了。我想你是说先创建一个文件,在不关闭程序的情况下将其设置为只读。
READONLY
属性检查仅在
CreateFile
例程中进行

在Windows内核中,每个对象在创建后都会被分配一个临时访问权限列表,除非显式刷新,否则在固定磁盘上的实际文件上很少发生这种情况。因此,即使您使用NTFS访问控制在
CreateFile
之后拒绝所有权限,您的程序的行为也将与调用
CreateFile
时一样


总之,在将文件热更改为
READONLY
后,您的程序仍然可以写入该文件,这是很自然的,因为该文件只将信息写入磁盘,而不更改内核访问表。

使用
std::fstream
时也会出现同样的问题?这有什么奇怪的?您使用写访问权限打开了文件
句柄
。这就是验证访问权限的时候@JPO38:C++标准库是使用Windows API实现的。当然行为是一样的。@I不可检测,是的,我理解。但是,在我将文件更改为只读之后。然后将新数据写入该文件。Windows是否应该阻止这种书面行为?@zangw No read-only不是由操作系统强制执行的,它只是要求了解标志的程序表现良好。如果要强制执行文件访问控制,则需要设置文件的安全属性。@RichardCriten很抱歉,您错了。只读将阻止使用
GENERIC\u WRITE
访问等进行简单的
CreateFile
调用。使用
std::fstream
也会出现同样的问题?这有什么奇怪的?您使用写访问权限打开了文件
句柄
。这就是验证访问权限的时候@JPO38:C++标准库是使用Windows API实现的。当然行为是一样的。@I不可检测,是的,我理解。但是,在我将文件更改为只读之后。然后将新数据写入该文件。Windows是否应该阻止这种书面行为?@zangw No read-only不是由操作系统强制执行的,它只是要求了解标志的程序表现良好。如果要强制执行文件访问控制,则需要设置文件的安全属性。@RichardCriten很抱歉,您错了。只读将阻止使用
GENERIC\u WRITE
访问权限进行简单的
CreateFile
调用。在程序运行时通过
GetFileAttributes
检查文件属性是否更改是否正确?在程序运行时通过
GetFileAttributes
检查文件属性是否更改是否正确?