Привет всем!
Мужики, помогите советом!
В общем, либо туплю, либо просто спать пора. Ну не могу никак справиться...
Ситуация такова:
программно захожу в каталог, нахожу там файлик и хочу его заюзать. Только вот не знаю об его статусе: дописан ли он? или его еще продолжают писать? т.е он как бы уже есть, но его как бы еще нет, простите за каламбур
Кто и как пишет -- понятия не имею. Могут даже по сети лить.
Вотс... Надеюсь, ясно изложил суть проблемы. теперь немного усложним...
Из инструментов -- только страндартные с++'ные библиотеки. Ибо код обязан работать и под линуксом (хотя... в принципе, можно и разный код влепить для разных осей. Но, надеюсь, существуют и другие варианты, чтобы можно было двух зайцев одним выстрелом завалить).
Ну, и добавлю масла в огонь -- директория с правами только на чтение.
Кто что толкового может посоветовать?
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
Но не факт, что сработает.
[Ответ]
например для 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
А может само условие задачи переформулировать? если само условие кривовато, в решение тоже соответственно без танцев с бубнами не обойдёшься.
[Ответ]