Большой Воронежский Форум
» Программирование>с++ проблема файлы
MHC 04:40 29.08.2008
Привет всем!
Мужики, помогите советом!
В общем, либо туплю, либо просто спать пора. Ну не могу никак справиться...
Ситуация такова:
программно захожу в каталог, нахожу там файлик и хочу его заюзать. Только вот не знаю об его статусе: дописан ли он? или его еще продолжают писать? т.е он как бы уже есть, но его как бы еще нет, простите за каламбур
Кто и как пишет -- понятия не имею. Могут даже по сети лить.
Вотс... Надеюсь, ясно изложил суть проблемы. теперь немного усложним...
Из инструментов -- только страндартные с++'ные библиотеки. Ибо код обязан работать и под линуксом (хотя... в принципе, можно и разный код влепить для разных осей. Но, надеюсь, существуют и другие варианты, чтобы можно было двух зайцев одним выстрелом завалить).
Ну, и добавлю масла в огонь -- директория с правами только на чтение.
Кто что толкового может посоветовать?
PS: Желательно без извращений.
[Ответ]
Part!zan 19:50 29.08.2008
Можно сделать
fseek( stream, 0, SEEK_END); a=ftell( stream );
fseek( stream, 0, SEEK_END); b=ftell( stream );
с некоторым интервалом между ними и сравнить a и b
Но не факт, что сработает. [Ответ]
J++ 20:39 29.08.2008
попробовать заблокировать файл монопольно каким-нибудь хитрым образом?

например для read (не помню есть ли монопольные блокировки для read, а не write/append)

если такое есть и файл удалось заблокировать, то скорее всего его (уже) никто не "держит" открытым [Ответ]
MHC 21:06 29.08.2008

Сообщение от Part!zan:
Можно сделать
fseek( stream, 0, SEEK_END); a=ftell( stream );
fseek( stream, 0, SEEK_END); b=ftell( stream );
с некоторым интервалом между ними и сравнить a и b
Но не факт, что сработает.

Ну эт уже извращение, если честно Эх, а я думал, что есть выход. Гм... Ну что ж. прийдётся тогда извращаться В принципе, хрен с ним, лишь бы работало. Кстати, а если файлу при записи долго не делать flush (допустим, он тоже потоком пишется), сработает ли данный метод, интересно?

Сообщение от J++:
попробовать заблокировать файл монопольно каким-нибудь хитрым образом?
например для read (не помню есть ли монопольные блокировки для read, а не write/append)
если такое есть и файл удалось заблокировать, то скорее всего его (уже) никто не "держит" открытым

гм. надо завтра будет попробовать.. вполне возможно, думаю..
[Ответ]
J++ 21:21 29.08.2008
В смысле попытаться открыть на чтение с флагом монопольной блокировки

но могут быть неожиданные нюансы в разных ОС, к тому же работа идет на сетевом устройстве (в сетевой файловой системе), так?...

надо очень внимательно читать доки для всех нужных ОСей - что происходит при попытке открыть файл таким образом [Ответ]
Part!zan 21:59 29.08.2008
В VС есть _fsopen, которая умеет задавать права на разделение доступа c вариантом

Сообщение от :
_SH_DENYRD Denies read access to the file.

Но под линух, ее, вроде, нет.

Сообщение от MHC:
сработает ли данный метод, интересно

а фиг его знает ) проверь

имхо, проще написать для разных осей разный код для этого и не мучаться. [Ответ]
MHC 10:57 04.09.2008
в винде довольно быстро исхитрился. Винда много чего там не разрешает, когда кто-то чё-то пишет в файл. А вот в Линухах извращался как мог. Вроде б, работает пока, но так... кривенько.

Сообщение от J++:
попробовать заблокировать файл монопольно каким-нибудь хитрым образом?
например для read (не помню есть ли монопольные блокировки для read, а не write/append)
если такое есть и файл удалось заблокировать, то скорее всего его (уже) никто не "держит" открытым

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

Сообщение от Part!zan:
В VС есть _fsopen, которая умеет задавать права на имхо, проще написать для разных осей разный код для этого и не мучаться.

ды теперь я уж всеми руками/ногами за
хоть как-нибудь бы сделать. Доступ, кста, теперь и на запись тоже есть на этот путь! Может, теперь какие идеи появятся у кого? [Ответ]
MHC 10:59 04.09.2008
уточню... проблема не в том, чтобы "не дать кому-то записать", наоборот, пусть пишет на здоровье и мешать ему не надо. Проблема в том, чтобы выяснить: юзает ли кто файло с флагами доступа на запись? [Ответ]
Part!zan 22:02 04.09.2008

Сообщение от MHC:
Доступ, кста, теперь и на запись тоже есть

Хм, ну тогда проблем быть не должно. Открыть файл 2 раза на запись, кажись, нельзя никак... [Ответ]
MHC 22:21 04.09.2008

Сообщение от Part!zan:
Хм, ну тогда проблем быть не должно. Открыть файл 2 раза на запись, кажись, нельзя никак...

ды вообще-т легко можно, оказывается В чём, собсна, и проблема. В винде-то ладно, я обошёл эту проблему. Легко решилась, но вот в убунтухе -- до сих пор парюсь... [Ответ]
J++ 01:07 05.09.2008
Дык если разрешили доступ в каталог на ЗАПИСЬ, можно попробовать практически идеальный вариант: попытку заблокировать файл МОНОПОЛЬНО НА ЗАПИСЬ. Не просто ОТКРЫТЬ НА ЗАПИСЬ, а МОНОПОЛЬНО.

Если удалось - предположительно никто другой не держит файл НА ЗАПИСЬ (на чтение открывать можно).

Должно сработать в любой ОС. Если какие-нибудь внутренние хитрости UBUNTU и сетевой FS не помешают я просто деталей не знаю, не работала с ними. Возможно плевать они хотели на POSIX и т.п.



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

а) обрабатывать файл либо через временнУю паузу (со времени последней модификации; паузу можно настраивать параметрами программы, если известна примерная длительность записи файла),

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

Для последнего файла в каталоге в этом случае придется применять алгоритм а) или похожий.
[Ответ]
MHC 01:33 05.09.2008

Сообщение от J++:
Дык если разрешили доступ в каталог на ЗАПИСЬ, можно попробовать практически идеальный вариант: попытку заблокировать файл МОНОПОЛЬНО НА ЗАПИСЬ. Не просто ОТКРЫТЬ НА ЗАПИСЬ, а МОНОПОЛЬНО.

Это вы про flock? Если да -- пробовал, не спасает. Без проблем "лочит". На самом деле -- хз чё там происходит. Но, сдаётся мне, вы совсем о другом. Нельзя ли подробнее?

Сообщение от J++:
Возможны еще варианты, если время обработки файла не критично

к сожалению, очень критично.

Сообщение от J++:
б) либо только тогда, когда появится следующий (по времени создания или модификации, надо уточнить) файл в этом каталоге.
...
Для последнего файла в каталоге в этом случае придется применять алгоритм а) или похожий.

а если сразу два, а то и больше файлов начнут писаться? в моём случае и такое возможно Очень даже. Собственно, это очень штатная ситуация для данного проекта... [Ответ]
J++ 22:55 12.09.2008
ну тут уж блин надо извращенно выворачиваться ... раз ей чихать на блокировки

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

Но это годится только когда файл пишут так: приконнектились-написали файл-отконнектились.. и возможны траблы если вдруг коннект порвался по независящим от тебя причинам (сеть).


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

типа, есть новый файл. подхватываем его на чтение, читаем до какого-то места, записываем свой протокол - какой файл и до какого места прочитали и обработали. Через промежуток времени лезем в протокол, смотрим - может в этот файл еще что-то записалось (или просто дочитываем конец файла), обрабатываем новую порцию... потом ищем "новоприбывшие" файлы, которых еще в протоколе не было...
и так до потери пульса. неудобство - каждый раз читать имена и длины всех файлов в каталоге, ну и что, можно например раз в месяц чистить каталог и соответственно протокол. [Ответ]
Part!zan 14:53 13.09.2008
MHC, а в линухе че, нельзя никак посмотреть какие кем файлы открыты? [Ответ]
netwind 19:00 13.09.2008
<fcntl.h> относится к стандарту POSIX, а значит, это почти везде заработает и почти всегда правильно.
Если код всех программ написан вами, и вы всегда используете fcntl() и при чтении и при записи, то заработает. Многие почему-то думают, что вся работа с файлом будет блокироваться.
Блокировать произвольные файлы для всех ос единообразно нельзя. [Ответ]
MHC 22:30 14.09.2008

Сообщение от Part!zan:
MHC, а в линухе че, нельзя никак посмотреть какие кем файлы открыты?

дык вот я и хочу узнать это сам программно, ессно [Ответ]
MHC 22:31 14.09.2008

Сообщение от netwind:
<fcntl.h> относится к стандарту POSIX, а значит, это почти везде заработает и почти всегда правильно.
Если код всех программ написан вами, и вы всегда используете fcntl() и при чтении и при записи, то заработает. Многие почему-то думают, что вся работа с файлом будет блокироваться.
Блокировать произвольные файлы для всех ос единообразно нельзя.

не, тут немного другая ситуация. я вообще отношения не имею к тому, что пишется. моё дело -- только читать записанное (до конца). [Ответ]
Part!zan 22:51 14.09.2008

Сообщение от MHC:
дык вот я и хочу узнать это сам

Я в линухе с программной точки зрения не силен, но подозреваю, что там это все делается проще, чем в винде. У них там вообще все очень просто... [Ответ]
MHC 23:20 14.09.2008

Сообщение от Part!zan:
У них там вообще все очень просто...

при условии, что знаешь, как это делается
а я с Линуксом чуть больше полу-месяца лишь пытаюсь познакомиться...
[Ответ]
netwind 11:19 15.09.2008
Список открытых файлов можно получить программой lsof. Только это ничего не даст так как промежутках между запуском программы может что-нибудь произойти.

Вообще-то в линуксе есть специфическая опция при монтировании файловой системы, это -o mand и блокировки работают даже для тех программ, в которых не были предусмотрены.
начать читать отсюда http://en.wikipedia.org/wiki/File_locking, продолжить man mount и man fcntl.
в остальных unix наверное нет. [Ответ]
quice 23:38 15.09.2008
А может само условие задачи переформулировать? если само условие кривовато, в решение тоже соответственно без танцев с бубнами не обойдёшься. [Ответ]
Вверх