LINUX.ORG.RU

Ответ на: комментарий от netcat

Ты ожидал, что тебе укажут на какую-то специальную функцию вроде bool fexist(*char) в стандартной библиотеке? Какой вообще ответ ты ожидал получить? Задумывался ли ты над вопросом, а как проще и быстрее всего проверить существует ли файл (не важно на каком ЯП)?

delete83 ★★
()
Ответ на: комментарий от netcat

> а не костыль ли это?

В чём именно ты здесь видишь «костыль»? О_О

Сколько пишу на С, всё время именно так существование файла проверяю. Хотя чаще возникает задача: если файл существует, открыть, если не существует - создать. Опять же решается open.

Ты всё же почитай man 2 open и man 2 stat и выбери подходящий способ.

OldFatMan
()
Ответ на: комментарий от OldFatMan

Я не вижу костыль, я просто сомневаюсь, что лучше всего вызвать ошибку, чтобы проверить есть ли файл. Будет неприятно, если программа рухнет. Опять же, я не настаиваю на правильности этих сомнений.

netcat ★★
() автор топика

Не слушай их, они не понимают о чем пишут. Используй либо fopen (стандарт), либо access (POSIX).

anonymous
()
Ответ на: комментарий от netcat

> если программа рухнет

Не рухнет, и таки прочитай уже ман.

cipher ★★★★★
()
Ответ на: комментарий от netcat

> сомневаюсь, что лучше всего вызвать ошибку, чтобы проверить есть ли файл. Будет неприятно, если программа рухнет.

/me безнадежно прикладывает ладонь к лицу.

Раз ты боишься, что твоя программа может рухнуть от непонятных причин, значит ты просто не знаешь, почему твоя программа вообще работает. Советую что-то поменять в консерватории.

Это было первое. И второе: что ты будешь делать, если файл будет удалён после проверки его существования? Вылетишь в сегфолт? Подумай об этом. Проверка существования должна осуществляться при открытии. В этом случае ты атомарно получаешь либо дескриптор открытого файла, либо код ошибки. Без неожиданностей.

geekless ★★
()
Ответ на: комментарий от netcat

Программа не рухнет, т.к. open вернёт -1, а из errno ты узнаешь, что произошла ошибка EACCESS. Точнее скажет stat - тоже возвращает -1, но код в errno будет ENOENT (т.е. файл не существует). Ты сам обрабатываешь эту ошибку и принимаешь дальнейшее решение: либо создать такой файл, либо завершить программу корректно, либо что-то ещё. Никаких проблем с «падением» программы.

OldFatMan
()
Ответ на: комментарий от netcat

Почитай ещё man 2 access до кучи:

access() checks whether the calling process can access the file path‐ name. If pathname is a symbolic link, it is dereferenced.

The mode specifies the accessibility check(s) to be performed, and is either the value F_OK, or a mask consisting of the bitwise OR of one or more of R_OK, W_OK, and X_OK. F_OK tests for the existence of the file. R_OK, W_OK, and X_OK test whether the file exists and grants read, write, and execute permissions, respectively.

итого:

#include <unistd.h>

int
exists(const char *path)
{
    return !access(path, F_OK);
}

я просто сомневаюсь, что лучше всего вызвать ошибку

Это не «вызывать ошибку» это errno (man 3 errno, опять же).

quasimoto ★★★★
()
Ответ на: комментарий от netcat

В любом предложенном тебе здесь случае - будь то open, stat, fopen или access - суть методики остаётся одной и той же: отслеживаешь возвращаемый код, и если он = -1, то файл очевидно не существует (уточнить ошибку можно по errno). После этого делаешь то, что тебе нужно.

Ещё раз: man-ы почитай.

OldFatMan
()
Ответ на: комментарий от netcat

Пока ты работаешь с функциями из стандартной библиотеки и системными вызовами, программа у тебя может рухнуть только по одной причине: ты сам накосячишь с памятью или еще чем-нибудь. Любая (не написанная тобой) функция либо отработает корректно и вернет ожидаемый результат, либо вернет признак ошибки (опять же, корректно вернув управление вызвавшему коду) и обработать код ошибки твоя святая обязанность, как программиста... Если ты не обрабатываешь коды завершения функций, то ты ССЗБ. Уж извини.

delete83 ★★
()

и только к 13му сообщению кто-то вспомнил про единственный правильный способ — функцию access

Reset ★★★★★
()
Ответ на: комментарий от Reset

Просто гораздо чаще встречается ситуация (я уже писал выше), когда при открытии файла (open) одновременно проверяется его существование, и если файл не существует, то он создаётся. У меня соотношение таких ситуаций к ситуации с простой проверкой существования примерно 10 к 1. Поэтому и про access вспоминаем гораздо реже. :)

OldFatMan
()
Ответ на: комментарий от Reset

>правильный способ — функцию access
Который не входит в стандарт C...
И про него вспомнили в 4м комментарии.

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

Зато входит в стандарт POSIX и есть даже в венде. Если нужно чистый Си, то только fopen.

Reset ★★★★★
()
Ответ на: комментарий от delete83

> программа у тебя может рухнуть только по одной причине

gcc 2.96 тонко намекает

anonymous
()

всегда использовал stat в таких случаях: она возвращает всё, что нужно для анализа. fopen выглядит костылём для данной задачи.

taker
()

Можно как-то так:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>

…

bool check_file(char *filepath){
    struct stat sb;
    if(stat(argv[1], &sb) == -1) return FALSE;
    if(!S_ISREG(sb.st_mode) return FALSE;
    if(sb.uid_t == getuid() && sb.st_mode & S_IWUSR) return TRUE;
    if(sb.gid_t == getgid() && sb.st_mode & S_IWGRP) return TRUE;
    if(sb.st_mode & S_IWOTH) return TRUE;
    return FALSE;
}

А еще можно проверять является ли файл символической ссылкой и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Reset

> и только к 13му сообщению кто-то вспомнил про единственный правильный способ — функцию access

И еще никто не вспомнил про то, что access неверную информацию дает при euid отличном от ruid.

anonymous
()
Ответ на: комментарий от Reset

>единственный правильный способ

И давно ли он стал «единственно правильным»?

red_eyed_peguin
()
Ответ на: комментарий от netcat

А чего следить-то: у каждого своя точка зрения, в чём-то верная, в чём-то не совсем. После чтения man-ов выбери наиболее подходящий именно тебе в данной конкретной задаче способ и используй его. Я чаще под Unix/Linux на С писал, поэтому по большей части open/stat использовал. Про fopen и access не сразу вспомнил, каюсь. Но это тоже вполне нормальные способы. Выбирай тот, который лучше всего укладывается в задачу, и вперёд. :)

OldFatMan
()
Ответ на: комментарий от netcat

И ещё одно замечание - поскольку ты задачу свою крайне лаконично изложил. :)

Если тебе нужно не просто однократно проверить существование файла, а отследить его создание или удаление, то имеет смысл посмотреть в сторону inotify.

man 7 inotify

inotify - monitoring file system events

OldFatMan
()
Ответ на: комментарий от Eddy_Em

А вот будет ли работать этот код в ситуации, когда владелец файла является членом группы-владельца, и при этом для группы право доступа есть, а для владельца - нету (труднопредставимо , но все же)? Ведь при обращении к файлу сначала вроде как проверяются права для владельца, и если там запрет - владелец к файлу доступа на получит, а вот эта функция вернет TRUE.

anonymous
()
Ответ на: комментарий от anonymous

Не проверял. И даже не представляю, для чего так странно делать...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Откуда трава? У меня на всю музыку на компе права на полный доступ пользователю mpd и группе denis (одноименная с пользователем), однако проблем не испытываю, ни с прослушиванием музыки, ни с редактированием тегов и всей библиотеки в целом?

В Unix проверка прав по умолчанию запретительная, если на любом уровне не встретится разрешительное правило. Отсутствие +r или +w для владельца еще на значит, что он не имеет доступа к файлу. Это значит только, что нужно еще проверить права для группы и для всех.

delete83 ★★
()
Ответ на: комментарий от delete83

Или наоборот. Сначала проверяются права для всех, потом для группы и потом для владельца. Не помню точно.

delete83 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.