Jak najlepiej sprawdzić, czy plik istnieje w C?
Czy jest lepszy sposób niż po prostu próba otwarcia pliku?
int exists(const char *fname)
{
FILE *file;
if ((file = fopen(fname, "r")))
{
fclose(file);
return 1;
}
return 0;
}
9 answers
Wyszukaj access()
funkcję znajdującą się w unistd.h
. Możesz zastąpić swoją funkcję
if( access( fname, F_OK ) == 0 ) {
// file exists
} else {
// file doesn't exist
}
Możesz również użyć R_OK
, W_OK
, i X_OK
zamiast F_OK
, aby sprawdzić uprawnienia do odczytu, uprawnienia do zapisu i uprawnienia do wykonywania (odpowiednio) zamiast istnienia, i możesz lub dowolna z nich razem (tj. sprawdź zarówno uprawnienia do odczytu , jak i} używając R_OK|W_OK
)
Update : zauważ, że w systemie Windows nie możesz używać W_OK
do niezawodnego testowania uprawnień do zapisu, ponieważ Funkcja dostępu nie uwzględnia DACL. access( fname, W_OK )
może zwrócić 0 (sukces), ponieważ plik nie ma ustawionego atrybutu Tylko do odczytu, ale nadal możesz nie mieć uprawnień do zapisu do pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-03 11:06:46
Użyj stat
w ten sposób:
#include <sys/stat.h> // stat
#include <stdbool.h> // bool type
bool file_exists (char *filename) {
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
I nazwij to tak:
#include <stdio.h> // printf
int main(int ac, char **av) {
if (ac != 2)
return 1;
if (file_exists(av[1]))
printf("%s exists\n", av[1]);
else
printf("%s does not exist\n", av[1]);
return 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-19 16:59:12
Zazwyczaj, gdy chcesz sprawdzić, czy plik istnieje, to dlatego, że chcesz utworzyć ten plik, jeśli nie. Graeme Perrow odpowiedź jest dobra, jeśli nie chcesz utworzyć tego pliku, ale jest podatny na warunki wyścigu, jeśli to zrobisz: inny proces może utworzyć plik pomiędzy Tobą, sprawdzając, czy istnieje, a ty faktycznie otwierasz go, aby do niego napisać. (Nie śmiej się... może to mieć złe implikacje dla bezpieczeństwa, jeśli utworzony plik był / align = "left" / )
Jeśli chcesz sprawdzić istnienie i Utwórz plik, jeśli nie istnieje, atomicznie , aby nie było warunków rasowych, użyj tego:
#include <fcntl.h>
#include <errno.h>
fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
/* failure */
if (errno == EEXIST) {
/* the file already existed */
...
}
} else {
/* now you can use the file */
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-29 03:56:48
Tak. Użyj stat()
. Zobacz stronę man dlastat(2)
.
stat()
nie powiedzie się, jeśli plik nie istnieje, w przeciwnym razie najprawdopodobniej się powiedzie. Jeśli istnieje, ale nie masz dostępu do odczytu do katalogu, w którym istnieje, również się nie powiedzie, ale w takim przypadku każda metoda zawiedzie (jak możesz sprawdzić zawartość katalogu, którego możesz nie zobaczyć zgodnie z prawami dostępu? Po prostu nie możesz).
Oh, jak ktoś inny wspomniał, możesz również użyć access()
. Jednak wolę stat()
, jakby plik istnieje to natychmiast uzyskać mi wiele przydatnych informacji (kiedy był ostatnio aktualizowany, jak duży jest to, właściciel i / lub grupa, która jest właścicielem pliku, uprawnienia dostępu, i tak dalej).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-05 16:32:46
FILE *file;
if((file = fopen("sample.txt","r"))!=NULL)
{
// file exists
fclose(file);
}
else
{
//File not found, no memory leak since 'file' == NULL
//fclose(file) would cause an error
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-23 06:25:13
Możesz użyć funkcji realpath ().
resolved_file = realpath(file_path, NULL);
if (!resolved_keyfile) {
/*File dosn't exists*/
perror(keyfile);
return -1;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-08 06:14:20
Z Visual C++ help, zwykle wybieram
/* ACCESS.C: This example uses _access to check the
* file named "ACCESS.C" to see if it exists and if
* writing is allowed.
*/
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
void main( void )
{
/* Check for existence */
if( (_access( "ACCESS.C", 0 )) != -1 )
{
printf( "File ACCESS.C exists\n" );
/* Check for write permission */
if( (_access( "ACCESS.C", 2 )) != -1 )
printf( "File ACCESS.C has write permission\n" );
}
}
Warto również zwrócić uwagę na wartości trybu_access(const char *path,
int mode
)
:
-
00: tylko istnienie
-
02: uprawnienia zapisu
-
04: uprawnienia do odczytu
-
06: uprawnienia do odczytu i zapisu
Ponieważ twój fopen
może zawieść w sytuacjach, w których plik istniał, ale nie można go otworzyć zgodnie z żądaniem.
Edit: wystarczy przeczytać post Meckiego. stat()
wygląda jak porządniejszy sposób. Ho hum.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-05 15:34:02
Myślę, że access () funkcja, która znajduje się w unistd.h
jest dobrym wyborem dla Linux
(Możesz również użyć stat).
Możesz go użyć tak:
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
void fileCheck(const char *fileName);
int main (void) {
char *fileName = "/etc/sudoers";
fileCheck(fileName);
return 0;
}
void fileCheck(const char *fileName){
if(!access(fileName, F_OK )){
printf("The File %s\t was Found\n",fileName);
}else{
printf("The File %s\t not Found\n",fileName);
}
if(!access(fileName, R_OK )){
printf("The File %s\t can be read\n",fileName);
}else{
printf("The File %s\t cannot be read\n",fileName);
}
if(!access( fileName, W_OK )){
printf("The File %s\t it can be Edited\n",fileName);
}else{
printf("The File %s\t it cannot be Edited\n",fileName);
}
if(!access( fileName, X_OK )){
printf("The File %s\t is an Executable\n",fileName);
}else{
printf("The File %s\t is not an Executable\n",fileName);
}
}
I otrzymujesz następujące wyjście:
The File /etc/sudoers was Found
The File /etc/sudoers cannot be read
The File /etc/sudoers it cannot be Edited
The File /etc/sudoers is not an Executable
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-26 15:45:17
Nie pamiętam skąd mam to, że użyłem w moim zadaniu (Zwykle kopiuję wklejać adres URL, gdzie znalazłem to jako łatwą formę cytowania) i nie mogę rozszyfrować, co końcowe (file) = 0
jest, chociaż moje najlepsze przypuszczenie jest redundancja, aby ustawić wszelkie odniesienia do pliku na 0.
#define fclose(file) ((file) ? fclose(file) : 0, (file) = 0)
file
Jeśli wskaźnik zadeklarowany jako:
FILE *file=NULL;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-19 02:43:44