Я предполагал, что fopen
возвращает указатель NULL
, если файл уже открыт. Но похоже, что fopen
не возвращает NULL
, если файл уже открыт в режиме "w"
. Ниже приведен код, который я использовал, чтобы попробовать это, и я не получаю никаких ошибок. Я пробовал использовать компиляторы mingw32 и TDM-GCC-64. Если не ошибаюсь, C++ выдает ошибку, если файл уже открыт.
#include<stdio.h>
int main()
{
FILE *fp1, *fp2;
fp1 = fopen("file1.txt", "w");
fp2 = fopen("file1.txt", "w");
if (fp2 == NULL)
{
printf("Error in opening file\n");
return(0);
}
// Edit: added following code to check the behavior if write operation
// is performed simultaneously
fputc('A', fp1);
fputc('M', fp1);
fputc('S', fp1);
fputc('B', fp2);
fclose(fp1);
fclose(fp2);
return 0;
}
Обновлено: добавлен дополнительный код для записи данных в fp1
и fp2
и просмотра поведения. Если выполняется, file1.txt
содержит данные BMS
и кажется правильным поведением, а fp1
и fp2
перемещаются независимо, как и ожидалось. Сначала AMS
записывается с использованием fp1
, затем A
заменяется на B
с использованием fp2
, и конечный результат - BMS
.
@Rajesh Речь идет о совместном использовании файлов, в Windows, если ваша реализация lib вызывает _fsopen
с SH_DENYNO
(например), тогда другая программа (или та же самая ...) может открывать файл несколько раз (также для записи). Что произойдет, зависит как от реализации, так и от базовой ОС (одновременная запись не так проста, по крайней мере, в Windows). Обратите внимание, однако, что fopen()
по умолчанию предполагает совместное использование, потому что обычно * nix OS использует другие примитивы синхронизации (см. fcntl()
)
Cit: В большинстве реализаций библиотек для переменной errno
также устанавливается системный код ошибки при сбое.
Согласно стандарту C (7.19.3.8) он определяется реализацией:
Functions that open additional (nontemporary) files require a file name, which is a string. The rules for composing valid file names are implementation-defined. Whether the same file can be simultaneously open multiple times is also implementation-defined.
Кроме того, это не рекомендуется по другим причинам, см., Например, Рекомендация FIO24-C стандарта кодирования SEI CERT C:
Some implementations do not allow multiple copies of the same file to be open at the same time. Consequently, portable code cannot depend on what will happen if this rule is violated. Even on implementations that do not outright fail to open an already-opened file, a TOCTOU (time-of-check, time-of-use) race condition exists in which the second open could operate on a different file from the first due to the file being moved or deleted (see FIO45-C. Avoid TOCTOU race conditions while accessing files for more details on TOCTOU race conditions).
Я добавил дополнительный код и отредактировал сообщение. Если мы попытаемся писать одновременно с использованием обоих файловых указателей, оба будут записаны, и файловые указатели будут обрабатываться независимо, и я думаю, что это правильное поведение.
Так что же происходит в опубликованном коде?