Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие _ Удаление временных файлов в Active Directory

Автор: SABROG 16.5.2009, 21:38

Юзал QTemporaryFile для удаления временных файлов, но если приложение запускают прямо из сети, то временные файлы не удаляются. Точно такая же история и с vim/gvim, его файлики с тильдой "~" остаются на удаленном хосте, чем загаживают папочку с php скриптами на web сервере.

Я так понимаю используются какие-то нативные средства винды для управления временными файлами и Qt сама не удаляет файл, а рассчитывает на то, что это сделает ОС. Никто с этим не сталкивался?

Автор: ViGOur 17.5.2009, 18:59

Цитата(SABROG @ 16.5.2009, 22:38) *
но если приложение запускают прямо из сети
Что значит прямо из сети?

Автор: SABROG 17.5.2009, 19:09

Цитата(ViGOur @ 17.5.2009, 19:59) *
Цитата(SABROG @ 16.5.2009, 22:38) *
но если приложение запускают прямо из сети
Что значит прямо из сети?

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

Автор: ViGOur 17.5.2009, 19:54

Мда, попробуй в ближайшее время. Честно говоря не встречался с таким.

В исходнках класса QTemporaryFile копался? Чтобы узнать почему он так себя ведет.

Автор: Andrewshkovskii 18.5.2009, 16:50

Глупо может, но... Если есть фиксированный список файлов, то удалить все "не нужные" файлики.нет?

Автор: SABROG 19.5.2009, 12:41

Попробуйте такой код. Непонятно почему не удаляет (даже не в Active Directory):

#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QCoreApplication>
#include <QtCore/QTemporaryFile>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTemporaryFile file(QLatin1String("mytemp"));
    file.setAutoRemove(true); // по умолчанию и так true
    if (file.open()) {
        qDebug() << file.fileName();
    }
    return a.exec();
}


Если поменять так, то файл удаляется.
    //return a.exec();
    return 0;


Че за фигня, деструктор QTemporaryFile не вызывается при ctr+c или закрытии консольного окна через крестик?

 temporary.zip ( 592 байт ) : 135
 

Автор: kwisp 19.5.2009, 13:08

SABROG,
думаю может это связанао с тем что не закрываешь файл - он открыт на момент закрытия приложения.

может стоит попробовать закрыть файл.

Цитата(SABROG @ 19.5.2009, 13:41) *
при ctr+c или закрытии консольного окна через крестик?

может код возврата влияет на работу деструктра. ctrl+c выход принудительный срочный, если не ошибаюсь, он не ноль возвращает точно так же и крестик окна консолного приложения.

-----
проверил так оно и есть.
код возврата влияет.

получается нужно найти возможность выходить по qApp->quit() -- наверное так.

Автор: SABROG 19.5.2009, 13:54

Цитата(kwisp @ 19.5.2009, 14:08) *
получается нужно найти возможность выходить по qApp->quit() -- наверное так.


Это бесполезно. Программы крашатся, свет вырубается, роутеры зависают и т.д. По сути класс QTemporaryFile бесполезен. Нужно еще программу допиливать до того, чтобы при запуске проверялись временные файлы и удалялись к чертям. Или папку temp вместе с программой создавать, если она существует при запуске - килять нафиг. Проблема только в том, что некоторыми программами можно пользоваться раз в год и если временный файл на несколько гигов, то будет очень обидно.

P.S.: close() никак не влияет

Автор: kwisp 19.5.2009, 14:30

Цитата(SABROG @ 19.5.2009, 14:54) *
P.S.: close() никак не влияет

это проверил убдился. просто предположение было

Цитата(SABROG @ 19.5.2009, 14:54) *
Это бесполезно. Программы крашатся, свет вырубается, роутеры зависают и т.д.

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

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



SABROG,
а если файлы создавать в темповой папке которая раз в неделю или при перезапуске очищается? ну это уже к вопросу администрирования. тоже вариант.

Автор: Litkevich Yuriy 19.5.2009, 15:19

Цитата(SABROG @ 19.5.2009, 16:41) *
деструктор QTemporaryFile не вызывается при ctr+c или закрытии консольного окна через крестик?
она и будет валится, т.к. Qt необрабатывает события завершения консольного приложения.
Я об этом уже тему заводил (уже забыл какую)

Автор: kwisp 19.5.2009, 15:25

Цитата(Litkevich Yuriy @ 19.5.2009, 16:19) *
Qt необрабатывает события завершения консольного приложения.

а могла бы
в винде SetConsoleCtrlHandler Есть
в линуксе сигналы
по исходникам поискал SetConsoleCtrlHandler нигде не используется. :(
все равно даже если бы тролли включили эту обработку то от ситуации когда шнур питания дернули это не спасёт верно же?
поэтому считаю выход в темповой дирректории.

Автор: Litkevich Yuriy 19.5.2009, 15:44

Цитата(kwisp @ 19.5.2009, 19:25) *
то от ситуации когда шнур питания дернули это не спасёт верно же?
ну это-то понятно - это авария.

Автор: igor_bogomolov 19.5.2009, 15:56

Можно еще воспользоваться void qAddPostRoutine ( QtCleanUpFunction ptr ). Если конечно не пугают глобальные функции и переменные.

Раскрывающийся текст
static QTemporaryFile file(QLatin1String("mytemp"));
static void cleanup_ptr()
{
    file.close();
    file.remove();
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    if (file.open()) {
        qDebug() << file.fileName();
    }

    qAddPostRoutine(cleanup_ptr);

    return app.exec();
}

Файлы удаляются при любом закрытии консоли :) Попробуйте :)

Автор: SABROG 19.5.2009, 15:56

Выход в ОС и её администрировании. В той же винде бывает столько файлов накапливается временных, что просто жуть. Правда там программа по очистке диска, которая всплывает при нехватки памяти на диске.

Но все-равно. Имхо в ОС должен быть специальный тип файлов или список подконтрольных временных файлов, которые должны удаляться автоматически, если процесс его создавший не существует и ни одна другая программа этот файл не держит открытым.

Автор: kwisp 19.5.2009, 15:58

Цитата(kwisp @ 19.5.2009, 15:30) *
а если файлы создавать в темповой папке которая раз в неделю или при перезапуске очищается? ну это уже к вопросу администрирования. тоже вариант.

Цитата(SABROG @ 19.5.2009, 16:56) *
Выход в ОС и её администрировании.

ну вот.

Автор: SABROG 19.5.2009, 16:02

Цитата(SABROG @ 19.5.2009, 16:56) *
Можно еще воспользоваться void qAddPostRoutine ( QtCleanUpFunction ptr ). Если конечно не пугают глобальные функции и переменные.


Дело тут даже не в методе qAddPostRoutine, а в том, что QTemporaryFile статический. Попробуй, деструктор вызывается. Мистика какая-то.

Автор: Авварон 19.5.2009, 21:41

вообще-то в линуксе для того сигналы и нужны, чтобы их перехватывали - нормальная программа ДОЛЖНА отслеживать SIGTERM (ctrl+c) тобы освободить ресурсы. Ясен пень, что если этого не сделать, то деструкторы объектов зваться НЕ будут - ОС всего лишь отчистит память. Хз как с этим в виндовзе, но в линухе переопределить SIGTERM просто необходимо. Другой вопрос, что должна быть какая-то реализация в Qt такого полуэкстренного выхода (эктренный это SIGKILL:)) - нужно смотреть QApplication

Автор: SABROG 19.5.2009, 22:03

А вообще в таких случая ОС кидает исключения какие-нибудь?

Автор: igor_bogomolov 19.5.2009, 22:23

Цитата(SABROG @ 19.5.2009, 23:03) *
А вообще в таких случая ОС кидает исключения какие-нибудь?
Я пробовал исключения отловить, не вышло. Видимо не кидает, или у меня руки кривые.

Еще пробовал http://www.cplusplus.com/reference/clibrary/cstdlib/atexit/ заюзать. Тоже не подошло.

Сейчас вообще задумался над тем, чтобы унаследовать QCoreApplication и переопределить его метод winEventFilter. Для этого пока разбираюсь в libqxt. У них подобным образом сделан отлов событий клавиатуры.

Еще читаю http://www.rsdn.ru/forum/message/3237023.flat.aspx.

Автор: SABROG 19.5.2009, 22:44

Ладно, не думаю, что в этом есть какой-то смысл. Даже если отловить момент, от вырубания электричества это не спасет.

Тут нужен комплекс мер и в пределах одного класса QTemporaryFile проблему не решить. А посему думаю, что тут удобнее будет использовать обычный QFile с известным именем и всякие проверки в момент запуска программы на его существование.

Автор: igor_bogomolov 19.5.2009, 22:47

Цитата(SABROG @ 19.5.2009, 23:44) *
от вырубания электричества это не спасет.
Да уж, такой сигнал нам не отловить :D

Автор: Kagami 19.5.2009, 22:56

Умные упсы рулят :) Они такие сигналы посылать умеют

Автор: SABROG 19.5.2009, 23:08

Цитата(Kagami @ 19.5.2009, 23:56) *
Умные упсы рулят :) Они такие сигналы посылать умеют

Да, давайте снабдим все клиентские станции на которых работает Qtшная программа упсами. Еще можно к мобильнику подрубить упс, чтобы временных файлов случайно не осталось, когда аккумулятор сядет. А упс можно носить в рюкзаке скажем. Они как-раз столько весят - полезно для здоровья, раскачка мышц ног и спины.

Автор: igor_bogomolov 19.5.2009, 23:13

Цитата(Kagami @ 19.5.2009, 23:56) *
Умные упсы рулят Они такие сигналы посылать умеют
Кризис в стране однако. Нема упсов. :)


А события консоли можно отлавливать так:
Раскрывающийся текст
#include <QtCore/QCoreApplication>
#include <windows.h>

BOOL CtrlHandler( DWORD fdwCtrlType )
{
  switch( fdwCtrlType )
  {
    // Handle the CTRL-C signal.
    case CTRL_C_EVENT:
      printf( "Ctrl-C event\n\n" );
      Beep( 750, 300 );
      return( TRUE );

    // CTRL-CLOSE: confirm that the user wants to exit.
    case CTRL_CLOSE_EVENT:
      Beep( 600, 200 );
      printf( "Ctrl-Close event\n\n" );
      return( TRUE );

    case CTRL_SHUTDOWN_EVENT:
      Beep( 750, 500 );
      printf( "Ctrl-Shutdown event\n\n" );
      return FALSE;

    default:
      return FALSE;
  }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
    {
        printf( "\nThe Control Handler is installed.\n" );
        printf( "\n -- Now try pressing Ctrl+C or Ctrl+Break, or" );
        printf( "\n    try logging off or closing the console...\n" );
        printf( "\n(...waiting in a loop for events...)\n\n" );
    }
    else
        printf( "\nERROR: Could not set control handler");

    return a.exec();
}

Автор: Litkevich Yuriy 20.5.2009, 0:10

Цитата(SABROG @ 20.5.2009, 2:44) *
с известным именем
только имя надо случайное генерить.

Автор: SABROG 20.5.2009, 8:21

Цитата(Litkevich Yuriy @ 20.5.2009, 1:10) *
Цитата(SABROG @ 20.5.2009, 2:44) *
с известным именем
только имя надо случайное генерить.

Не надо. Пусть будут от 1 до 1000, лишь бы я смог потом проверить существование этих файлов.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)