Здравствуйте, B0FEE664, Вы писали:
BFE>·>Нельзя, конечно, если ты пишешь код с защитой от сбоев. А иначе... с ровно таким же успехом таргет можно удалять и без проверки. BFE>При работе с файловой системой от всех возможных сбоев защититься невозможно, насколько я понимаю,
Возможно, конечно. Ну кроме каких-то системных отказов (т.е. железо или баги в драйверах), равзе только. Иначе, как по-твоему СУБД, например, работают?
BFE>но вот ситуация с правами — она довольно распространённая и мне кажется логичным проверить возможность копирования до удаления таргета просто потому, что эта ситуация встречается часто по сравнению с другими сбоями. А это даже не сбой, а разумное поведение.
Тут ты всё правильно сказал: тебе кажется.
Саракстически смеёшься над std::filesystem, но демонстрируешь непонимание как собственно файловые системы работают.
BFE>По крайней мере я бы ожидал от, скажем, файлового менеджера, что такая проверка делается.
Самое простое — открывает исходный файл на чтение и, если успешно, открывает таргет-файл на запись. Собственно всё. Зачем в принципе делать какие-то проверки перед открытием — я не понимаю.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, m2user, Вы писали:
BFE>>Мне надо знать пройдёт ли операция копирования до того, как таргет (symlink или каталог) будут удалены. Как это сделать не открывая исходный файл на чтение? M>Хм, тебе прниципиально нужно избежать "лишнего" открытия на чтение?
Нет, просто как-то неожиданно, что даже зная права на файл невозможно их никак сопоставить с теми операциями, которые позволены приложению.
M>Так то, файловый дескриптор на чтение (оригинальный файл) и файловый дескриптор на запись/удаление (копия с временным именем) это самый очевидный способ определить есть ли достаточные права.
Если бы я сам, используя функциональность ввода-вывода занимался копированием файлов, то так бы и было, но если есть std::filesystem, то разумно ожидать наличие функции, типа, std::filesystem::access(path), которая возвращает набор прав, которыми обладает приложение по отношению к указанному файлу. Есть разумная причина, почему такой функции нет?
Здравствуйте, B0FEE664, Вы писали:
BFE>Нет, просто как-то неожиданно, что даже зная права на файл невозможно их никак сопоставить с теми операциями, которые позволены приложению.
Так права могут и быть, но файл может быть эксклюзивно залочен другим процессом, например.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
BFE>>·>Нельзя, конечно, если ты пишешь код с защитой от сбоев. А иначе... с ровно таким же успехом таргет можно удалять и без проверки. BFE>>При работе с файловой системой от всех возможных сбоев защититься невозможно, насколько я понимаю, ·>Возможно, конечно. Ну кроме каких-то системных отказов (т.е. железо или баги в драйверах), равзе только. Иначе, как по-твоему СУБД, например, работают?
А причём тут СУБД? В работу СУБД вмешиваются сторонние приложения, удаляют, подменяют файлы базы данных?
BFE>>но вот ситуация с правами — она довольно распространённая и мне кажется логичным проверить возможность копирования до удаления таргета просто потому, что эта ситуация встречается часто по сравнению с другими сбоями. А это даже не сбой, а разумное поведение. ·>Тут ты всё правильно сказал: тебе кажется.
Объясните, почему кажется?
·>Саракстически смеёшься над std::filesystem, но демонстрируешь непонимание как собственно файловые системы работают.
Я не очень глубоко знаю как работают файловые системы, но знаю, что они бывают совершенно разные. Однако речь не про файловые системы, а про функциональность std::filesystem.
BFE>>По крайней мере я бы ожидал от, скажем, файлового менеджера, что такая проверка делается. ·>Самое простое — открывает исходный файл на чтение и, если успешно, открывает таргет-файл на запись. Собственно всё. Зачем в принципе делать какие-то проверки перед открытием — я не понимаю.
А я не понимаю. зачем мне вообще что-то открывать, если я не собираюсь заниматься вводом-выводом.
Здравствуйте, ·, Вы писали:
BFE>>Нет, просто как-то неожиданно, что даже зная права на файл невозможно их никак сопоставить с теми операциями, которые позволены приложению. ·>Так права могут и быть, но файл может быть эксклюзивно залочен другим процессом, например.
Может. А ещё его может удалить другой процесс. Создать заново. Писать во время копирования. А в некоторых системах, даже удалить во время исполнения. Не знаю, можно ли поменять права доступа во время копирования, но, наверное, такое тоже возможно. И что с того? Ситуация, при которой два процесса одновременно работают с одним и тем же файлом довольно редкая по сравнению с той, когда можно считать, что есть ровно один процесс работающий с файловой системой и этот наш процесс. Многие файловые менеджеры работают именно так — не отслеживают изменения производимые другими процессами.
Здравствуйте, B0FEE664, Вы писали:
BFE>·>Возможно, конечно. Ну кроме каких-то системных отказов (т.е. железо или баги в драйверах), равзе только. Иначе, как по-твоему СУБД, например, работают? BFE>А причём тут СУБД? В работу СУБД вмешиваются сторонние приложения, удаляют, подменяют файлы базы данных?
Какие-нибудь тулзы субд и такое могут.
BFE>>>но вот ситуация с правами — она довольно распространённая и мне кажется логичным проверить возможность копирования до удаления таргета просто потому, что эта ситуация встречается часто по сравнению с другими сбоями. А это даже не сбой, а разумное поведение. BFE>·>Тут ты всё правильно сказал: тебе кажется. BFE>Объясните, почему кажется?
Не надо так делать. Если тебе надо сохранить целостность, то обычно делают через переименование. Скопировать файл рядом с новым именем и переименовать, перезаписав старое. Если таргет можно терять, то просто открывай его на перезапись после того, как открылся исходный файл на чтение.
BFE>·>Саракстически смеёшься над std::filesystem, но демонстрируешь непонимание как собственно файловые системы работают. BFE>Я не очень глубоко знаю как работают файловые системы, но знаю, что они бывают совершенно разные. Однако речь не про файловые системы, а про функциональность std::filesystem.
Функциональность std::filesystem соответствует тому как работают файловые системы.
BFE>·>Самое простое — открывает исходный файл на чтение и, если успешно, открывает таргет-файл на запись. Собственно всё. Зачем в принципе делать какие-то проверки перед открытием — я не понимаю. BFE>А я не понимаю. зачем мне вообще что-то открывать,
_Тебе_? Я тоже не понимаю. Ты задал вопрос о том как могут работать файловые менеджеры.
BFE>если я не собираюсь заниматься вводом-выводом.
Ты уж определись. Удаление файла — это тоже ввод-вывод.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
BFE>>·>Возможно, конечно. Ну кроме каких-то системных отказов (т.е. железо или баги в драйверах), равзе только. Иначе, как по-твоему СУБД, например, работают? BFE>>А причём тут СУБД? В работу СУБД вмешиваются сторонние приложения, удаляют, подменяют файлы базы данных? ·>Какие-нибудь тулзы субд и такое могут.
Прямо во время работы?
BFE>>>>но вот ситуация с правами — она довольно распространённая и мне кажется логичным проверить возможность копирования до удаления таргета просто потому, что эта ситуация встречается часто по сравнению с другими сбоями. А это даже не сбой, а разумное поведение. BFE>>·>Тут ты всё правильно сказал: тебе кажется. BFE>>Объясните, почему кажется? ·>Не надо так делать. Если тебе надо сохранить целостность, то обычно делают через переименование. Скопировать файл рядом с новым именем и переименовать, перезаписав старое. Если таргет можно терять, то просто открывай его на перезапись после того, как открылся исходный файл на чтение.
Если таргет — каталог, а на его место надо записать файл с тем же именем, то так сделать не получится.
BFE>>·>Саракстически смеёшься над std::filesystem, но демонстрируешь непонимание как собственно файловые системы работают. BFE>>Я не очень глубоко знаю как работают файловые системы, но знаю, что они бывают совершенно разные. Однако речь не про файловые системы, а про функциональность std::filesystem. ·>Функциональность std::filesystem соответствует тому как работают файловые системы.
Ну, я бы так не сказал. Хотя, тут, конечно, вопрос: что значит "соответствуют"?
BFE>>·>Самое простое — открывает исходный файл на чтение и, если успешно, открывает таргет-файл на запись. Собственно всё. Зачем в принципе делать какие-то проверки перед открытием — я не понимаю. BFE>>А я не понимаю. зачем мне вообще что-то открывать, ·>_Тебе_? Я тоже не понимаю. Ты задал вопрос о том как могут работать файловые менеджеры.
Исходный вопрос о другом.
BFE>>если я не собираюсь заниматься вводом-выводом. ·>Ты уж определись. Удаление файла — это тоже ввод-вывод.
Хорошо: мне не нужны операции с содержимым файлов.
BFE>но если есть std::filesystem, то разумно ожидать наличие функции, типа, std::filesystem::access(path), которая возвращает набор прав, которыми обладает приложение по отношению к указанному файлу. Есть разумная причина, почему такой функции нет?
На уровне API OS (MS Windows) такие функции есть. Но работа с ними сложнее.
Т.е. возможно различие в поведении такого API для разных OS осложняет включение его в std::filesystem.
IMHO, если нужна нетривиальная работа с файловой системой, то лучше сразу брать системное API.
·>>Ты уж определись. Удаление файла — это тоже ввод-вывод. BFE>Хорошо: мне не нужны операции с содержимым файлов.
ну тогда открытие файлового дескриптора это ещё не операция с содержимым.
И между прочим удаление и переименование тоже предполагает открытие файлового дескриптора (хотя возможно это и специфично для ОС).
Более того — для того, чтобы прочитать права на файл тебе уже нужно открыть дескриптор файла или родительского каталога.
Здравствуйте, B0FEE664, Вы писали:
BFE>>>Объясните, почему кажется? BFE>·>Не надо так делать. Если тебе надо сохранить целостность, то обычно делают через переименование. Скопировать файл рядом с новым именем и переименовать, перезаписав старое. Если таргет можно терять, то просто открывай его на перезапись после того, как открылся исходный файл на чтение. BFE>Если таргет — каталог, а на его место надо записать файл с тем же именем, то так сделать не получится.
Ок. Тогда: Скопировать файл рядом с новым именем и переименовать, перезаписав старое. Если переименование обломалось, удалить старое, переименовать опять.
BFE>>>Я не очень глубоко знаю как работают файловые системы, но знаю, что они бывают совершенно разные. Однако речь не про файловые системы, а про функциональность std::filesystem. BFE>·>Функциональность std::filesystem соответствует тому как работают файловые системы. BFE>Ну, я бы так не сказал. Хотя, тут, конечно, вопрос: что значит "соответствуют"?
Мне неизвестна файловая система в которой есть операция операция "проверить можно ли открыть файл на чтение без открытия файла". Почему ты хочешь, чтобы такое было в std::filesystem — неясно. И главное — как оно в принципе может быть реализовано и для чего использовано (написание бажных ненадёжных программулек не в счёт).
BFE>Исходный вопрос о другом.
Ну ты почему-то ожидал что-то странное от файлового менеджера. Я пояснил, что твои ожидания какие-то странные.
BFE>>>если я не собираюсь заниматься вводом-выводом. BFE>·>Ты уж определись. Удаление файла — это тоже ввод-вывод. BFE>Хорошо: мне не нужны операции с содержимым файлов.
А что по-твоему делает операция копирования файла?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, B0FEE664, Вы писали:
BFE>>>Нет, просто как-то неожиданно, что даже зная права на файл невозможно их никак сопоставить с теми операциями, которые позволены приложению. BFE>·>Так права могут и быть, но файл может быть эксклюзивно залочен другим процессом, например. BFE>Может. А ещё его может удалить другой процесс. Создать заново. Писать во время копирования. А в некоторых системах, даже удалить во время исполнения. Не знаю, можно ли поменять права доступа во время копирования, но, наверное, такое тоже возможно. И что с того? Ситуация, при которой два процесса одновременно работают с одним и тем же файлом довольно редкая по сравнению с той, когда можно считать, что есть ровно один процесс работающий с файловой системой и этот наш процесс. Многие файловые менеджеры работают именно так — не отслеживают изменения производимые другими процессами.
Вот поэтому и не отслеживают, потому что бессмысленно. Просто делают заданную задачу и обрабатывают ошибочные результаты, запрашивают интерактивно что делать дальше.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Ок. Тогда: Скопировать файл рядом с новым именем и переименовать, перезаписав старое. Если переименование обломалось, удалить старое, переименовать опять.
Да. я буду делать именно так, но тут надо понимать, что это не оптимальный вариант, так как в этом случае может не хватить места.
·>Мне неизвестна файловая система в которой есть операция операция "проверить можно ли открыть файл на чтение без открытия файла".
Ладно, я переформулирую вопрос. Я не хотел спрашивать "можно ли открыть файл на чтение без открытия файла". Я спрашиваю: есть ли у исполняемого кода такие права, что позволяют открыть указанный файл на чтение.
·>Почему ты хочешь, чтобы такое было в std::filesystem — неясно. И главное — как оно в принципе может быть реализовано и для чего использовано (написание бажных ненадёжных программулек не в счёт).
Надо просто сравнить права, с которыми исполняется приложение, с правами файла. Что в этом сложного и зачем при этом открывать файл?
·>А что по-твоему делает операция копирования файла?
Копирует файл. Как она это делает — дело десятое и может зависить от чего угодно: от файловой системы, от операционной системы, от драйвера, от устройства. ЕМНИП DVD-ROM можно было организовать так, что при записи одинаковых файлов создаётся "hard link" вместо копирования файла, файловая система поддерживала. Я вполне могу представить файловое хранилище в облаке, которое просто увеличивает счётчик у файла и прописывает имя в каталог. Поэтому для меня даже копирование файла и копирование содержимого файла — это две разные операции, не говоря уж о вводе-выводе.
Здравствуйте, ·, Вы писали:
·>Вот поэтому и не отслеживают, потому что бессмысленно. Просто делают заданную задачу и обрабатывают ошибочные результаты, запрашивают интерактивно что делать дальше.
Обычно, когда я копирую файл, а в указанном каталоге уже есть файл с таким именем, то файловый менеджер спрашивает подтверждения на перезапись. Это не обработка ошибочной ситуации и это обычное поведение.
Впрочем, у меня есть лучше пример. Если от лица пользователя с правами root пытаться перезаписать файлы, что принадлежат другому пользователю, то ЕМНИП некоторые утилиты выдают предупреждение что-то вроде: эти файлы принадлежат не вам, уважайте права других, вы уверены, что хотите их перезаписать? Вполне разумный запрос. Как реализовать такую функциональность используя std::filesystem ?
Здравствуйте, m2user, Вы писали:
M>На уровне API OS (MS Windows) такие функции есть. Но работа с ними сложнее. M>Т.е. возможно различие в поведении такого API для разных OS осложняет включение его в std::filesystem.
Ну, если есть права, то и функции должны быть.
M>IMHO, если нужна нетривиальная работа с файловой системой, то лучше сразу брать системное API.
Вот как раз этого хочется избежать.
BFE>Ну, если есть права, то и функции должны быть.
В расчёте эффективных прав много нюансов.
Даже работая напрямую с API конкретной ОС нужно тщательно изучать документацию (область применимости API и интерпретацию результата).
Иными словами, даже если бы это API было включено в std::filesystem, не знаю нюансов ты мог бы получить как ложно-отрицательный, так и ложно-положительный результат.
Напомню также, что права на ФС могут быть настроена так, что у пользователя нет прав на чтение пермиссий, но есть права на чтение контента файла.
(такое делается из соображений безопасности)
Здравствуйте, B0FEE664, Вы писали:
BFE>·>Вот поэтому и не отслеживают, потому что бессмысленно. Просто делают заданную задачу и обрабатывают ошибочные результаты, запрашивают интерактивно что делать дальше. BFE>Обычно, когда я копирую файл, а в указанном каталоге уже есть файл с таким именем, то файловый менеджер спрашивает подтверждения на перезапись. Это не обработка ошибочной ситуации и это обычное поведение.
В хорошо спроектированном софте обработка ошибочных результатов — это обычное поведение.
И, кстати, твоя хотелка удалять диру — необычна. Известные мне файловые менеджеры это не делают. Либо копируют внутрь диры, либо отказывается выполнять операцию — удаляй диру явно, если так хочется. Например cp говорит "cannot overwrite directory with non-directory".
BFE>Впрочем, у меня есть лучше пример. Если от лица пользователя с правами root пытаться перезаписать файлы, что принадлежат другому пользователю, то ЕМНИП некоторые утилиты выдают предупреждение что-то вроде: эти файлы принадлежат не вам, уважайте права других, вы уверены, что хотите их перезаписать? Вполне разумный запрос. Как реализовать такую функциональность используя std::filesystem ?
Насколько я знаю, в std нет возможности определения овнера. Только rwx атрибуты можно поглядеть. Так что без системно-зависимых api в Плюсах имхо не обойтись.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
M>>Оффтоп. std::filesystem — это какой-то выкидыш здравого смысла, стараюсь держаться от него подальше BFE>Да, у меня тоже сложилось впечатление, что авторы ничего сложного с её помощью написать даже не пытались.
А поясните, почему?
Я касался ее не очень подробно, но для простых вещей вроде норм было.
Здравствуйте, m2user, Вы писали: BFE>>Ну, если есть права, то и функции должны быть. M>В расчёте эффективных прав много нюансов.
Скрытый текст
M>Даже работая напрямую с API конкретной ОС нужно тщательно изучать документацию (область применимости API и интерпретацию результата). M>Иными словами, даже если бы это API было включено в std::filesystem, не знаю нюансов ты мог бы получить как ложно-отрицательный, так и ложно-положительный результат. M>Напомню также, что права на ФС могут быть настроена так, что у пользователя нет прав на чтение пермиссий, но есть права на чтение контента файла. M>(такое делается из соображений безопасности)
Так как все эти утверждения полны внутренних противоречий, я ничего не понимаю из того, что здесь написано.
1) Вы пишите, что сложно реализовать такую функциональность. Ну так библиотека для того и нужна, чтобы реализовывать сложную функциональность. Простую функциональность можно и в прикладном коде написать.
2) Вы пишите, что "права на ФС могут быть настроена так, что у пользователя нет прав на чтение пермиссий, но есть права на чтение контента файла". Может. И что? Это ведь не то, о чём я пишу.
Функцией в одну строчку:
можно проверить право на чтение файла. Для записи, думаю, тоже не сложно написать. Сложнее — на исполнение, но ведь в конечном итоге у системы точно есть эта информация. Так почему её нельзя получить прямым способом, а можно только окольными путями? M>Простой std::fopen кратно проще и надежнее.
"Настоящие герои всегда идут в обход"
Здравствуйте, ·, Вы писали:
BFE>>·>Вот поэтому и не отслеживают, потому что бессмысленно. Просто делают заданную задачу и обрабатывают ошибочные результаты, запрашивают интерактивно что делать дальше. BFE>>Обычно, когда я копирую файл, а в указанном каталоге уже есть файл с таким именем, то файловый менеджер спрашивает подтверждения на перезапись. Это не обработка ошибочной ситуации и это обычное поведение. ·>В хорошо спроектированном софте обработка ошибочных результатов — это обычное поведение.
Согласен, но я не считаю, что запрос на перезаписывание файла является обработкой ошибки.
·>И, кстати, твоя хотелка удалять диру — необычна. Известные мне файловые менеджеры это не делают. Либо копируют внутрь диры, либо отказывается выполнять операцию — удаляй диру явно, если так хочется. Например cp говорит "cannot overwrite directory with non-directory".
Да, я понимаю, что хотелка заменить директорию файлом необычна. Я понимаю, обоснованность отсутствия такой возможности у интерактивных утилит.
·>Насколько я знаю, в std нет возможности определения овнера. Только rwx атрибуты можно поглядеть. Так что без системно-зависимых api в Плюсах имхо не обойтись.
Так об этом я и пишу.
Здравствуйте, B0FEE664, Вы писали:
BFE>·>В хорошо спроектированном софте обработка ошибочных результатов — это обычное поведение. BFE>Согласен, но я не считаю, что запрос на перезаписывание файла является обработкой ошибки.
Запрос на перезаписывание файла может не выполниться и выдать ошибочный результат. Его обычно надо обрабатывать. Даже если ты перед самим запросом ты всё десять раз перепроверил и вроде как ожидаешь, что всё должно сработать. Поэтому неясно зачем запрашивать какие-то права и делать другие танцы перед запросом.
BFE>·>Насколько я знаю, в std нет возможности определения овнера. Только rwx атрибуты можно поглядеть. Так что без системно-зависимых api в Плюсах имхо не обойтись. BFE>Так об этом я и пишу.
По-моему ты писал, что тебе надо проверить "права, что позволяют открыть указанный файл на чтение" — это можно в std, для этого не нужно определять овнера. Но это не нужно делать для решения задачи, которую я понял как "перезаписать файл". Я видимо совершенно перестал понимать какую же задачу ты пытаешься решить.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, DTF, Вы писали:
BFE>>Да, у меня тоже сложилось впечатление, что авторы ничего сложного с её помощью написать даже не пытались. DTF>А поясните, почему? DTF>Я касался ее не очень подробно, но для простых вещей вроде норм было.
До тех пор, пока идёт работа с отдельными файлами, особых сложностей не возникает, но если начинается работа с каталогами...
Ну, например, в общем случае нет возможности получить список файлов каталога. Единственный способ — это пытаться использовать std::filesystem::directory_iterator, но в процессе перечисления файлов операция инкремента может завершится с ошибкой, например потому, что следующий файл был удалён (или добавлен, это не специфицировано) другим процессом. В этом случае процесс перечисления надо начинать заново. На больших каталогах, где постоянно добавляются/удаляются файлы это процесс до конца вообще, наверно, никогда не дойдёт. Впрочем я пишу про реализацию gcc для ext4, возможно для других систем работа идёт как-то иначе (что тоже не удобно, нет идинообразия). Понятно, что в любом случае полученный список файлов может быть не актуален ещё в момент построения, но зачем останавливаться на первом же удалённом файле? Почему через него нельзя перескочить и продолжить построение списка?
Или, например, std::filesystem::path не различает имя файла и имя каталога. Вернее так: имя файла и имя директории — это один и тот же объект: std::filesystem::path. Это не удобно использовать. Было бы логично иметь три типа объектов: путь, имя файла и путь_с_файлом.