Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема при удалении директории. 
:(
    Опции темы
4ygynOK
Дата 10.10.2013, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Есть вот такой вот код:
Код

BOOL CUGODatabaseMng::DeleteDir(DWORD BUGO_Id)
{
    ASSERT(m_pDatabaseMng);
    if (!m_pDatabaseMng)
        return FALSE;
    
    BOOL bParent = TRUE;
    BOOL bDelParent = TRUE;
    try
    {
        std::list<DWORD> lstIds;

        CString sSQL;
        sSQL.Format(_T("SELECT ID FROM BUGO WHERE PARENT_ID=%d"), BUGO_Id);

        ADODB::_RecordsetPtr spRS = m_pDatabaseMng->OpenRecordset(sSQL);
        long nRecordCount = spRS->GetRecordCount();
        
        for (long nRecord = 0; nRecord < nRecordCount; ++nRecord)
        {
            lstIds.push_back((long)spRS->GetFields()->GetItem(_T("ID"))->GetValue());
            spRS->MoveNext();
        }
        
        if (nRecordCount > 1)
        {
            bParent = TRUE; // проверка наличия вложенных каталогов
        }

        spRS->Close();

        for (std::list<DWORD>::iterator it = lstIds.begin(); it != lstIds.end(); ++it)
        {
            if (bParent)
                bDelParent = FALSE; //если есть вложенные каталоги, то родительская не удаляется
            
            if (!DeleteDir(*it))
                return FALSE;
        }

        if (bDelParent)
        {
            sSQL.Format(_T("DELETE FROM BUGO WHERE ID=%d"), BUGO_Id);
            VERIFY(m_pDatabaseMng->ExecuteSQL(sSQL));
            return TRUE;
        }

    }
    catch (_com_error& e)
    {
        if (AfxMessageBox(CString(_T("Удаление каталога невозможно!\n")) + (LPCTSTR)e.Description() + CString(_T("\nПродолжить удаление?")),MB_OKCANCEL) == IDOK)
        {
            return TRUE;
        }
        else return FALSE;
    }

    return FALSE;
}

предназначен для удаления директории используя базу данных.
 
Код

for (long nRecord = 0; nRecord < nRecordCount; ++nRecord)
        {
            lstIds.push_back((long)spRS->GetFields()->GetItem(_T("ID"))->GetValue());
            spRS->MoveNext();
        }

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

for (std::list<DWORD>::iterator it = lstIds.begin(); it != lstIds.end(); ++it)
        {
            if (!DeleteDir(*it))
                return FALSE;
                        if (bParent)
                bDelParent = FALSE; //если есть вложенные каталоги, то родительская не удаляется
        }

        if (bDelParent)
        {
            sSQL.Format(_T("DELETE FROM BUGO WHERE ID=%d"), BUGO_Id);
            VERIFY(m_pDatabaseMng->ExecuteSQL(sSQL));
            return TRUE;
        }

собственно для удаления каталогов.
Данный код можно использовать до уровня вложенности 2. Для меня стоит задача переделать его до любого уровня вложенности. Помогите пожалуйста все разъяснения дам без проблем.
PM MAIL   Вверх
bsa
Дата 10.10.2013, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Сделай рекурсивную функцию, которая получает путь к каталогу и сначала вызывает себя рекурсивно для всех подкаталогов, а затем удаляет все файлы из указанного каталога и сам каталог, путь к которому передан параметром.
PM   Вверх
4ygynOK
Дата 11.10.2013, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



если можно то поподробнее, с приблизительным примером.
PM MAIL   Вверх
baldina
Дата 11.10.2013, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(4ygynOK @  10.10.2013,  17:14 Найти цитируемый пост)
Данный код можно использовать до уровня вложенности 2

почему? DeleteDir уже вызывает себя рекурсивно
PM MAIL   Вверх
4ygynOK
Дата 11.10.2013, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Цитата(baldina @ 11.10.2013,  13:40)
Цитата(4ygynOK @  10.10.2013,  17:14 Найти цитируемый пост)
Данный код можно использовать до уровня вложенности 2

почему? DeleteDir уже вызывает себя рекурсивно

Да но работает только до 2 уровня вложенности, вот сейчас ищу на каком моменте оно вываливается вместо того чтобы продолжить.
PM MAIL   Вверх
baldina
Дата 11.10.2013, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



последний  return FALSE; замени на TRUE
PM MAIL   Вверх
4ygynOK
Дата 11.10.2013, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Цитата(baldina @ 11.10.2013,  15:05)
последний  return FALSE; замени на TRUE

Ничего не дает, если я правильно понял про return TRUE в самом конце после catch?
PM MAIL   Вверх
baldina
Дата 11.10.2013, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



да. тут
Цитата

 if (!DeleteDir(*it))
                return FALSE;

ожидается, что в случае нормальной работы DeleteDir() возвращает TRUE. Погляди, на чем у тебя заканчивается - это либо данные из базы, либо DeleteDir() не в нужный момент FALSE   возвернул
PM MAIL   Вверх
4ygynOK
Дата 11.10.2013, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Цитата(baldina @ 11.10.2013,  17:30)
да. тут
Цитата

 if (!DeleteDir(*it))
                return FALSE;

ожидается, что в случае нормальной работы DeleteDir() возвращает TRUE. Погляди, на чем у тебя заканчивается - это либо данные из базы, либо DeleteDir() не в нужный момент FALSE   возвернул

Удаление происходит но catch как я понимаю вызывается несколько раз. Так-как окошек выскакивает несколько прежде чем удалится.
PM MAIL   Вверх
baldina
Дата 11.10.2013, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



наверно это не хорошо. что в базе? что в e.Description()?

Добавлено через 2 минуты и 39 секунд
вот это странный фрагмент
Код

if (bParent)
                bDelParent = FALSE; //если есть вложенные каталоги, то родительская не удаляется

логика должна быть такая: сначала удалить потомков, потом себя. никаких проверок при этом не нужно
PM MAIL   Вверх
4ygynOK
Дата 11.10.2013, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Цитата(baldina @ 11.10.2013,  18:00)
наверно это не хорошо. что в базе? что в e.Description()?

e.Description() - представляет собой сообщение из базы. В моем случае оно мне говорит что в папке есть связанные записи с такой-то таблицей. 
База, точнее таблица с которой мы работаем состоит из 4 столбцов ID(именно его мы потом засовываем в it там все по порядку), Parent_ID соответственно указывает на родительский ID, Name - имя папки, Number какое-то числовое значение, но насчет его сказали не парится.
вот ссылка на скрин с базы: http://s2.ipicture.ru/uploads/20131011/5HGGOmlv.bmp

Это сообщение отредактировал(а) 4ygynOK - 11.10.2013, 18:18
PM MAIL   Вверх
baldina
Дата 11.10.2013, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



тут что-то с логикой. 
убери строчки 25-28, 34-35: если есть вложенные папки, их надо удалить, что и делается в цикле. но сама папка не удаляется (из-за проверки и условия), поэтому не удается удалить и родительские. вобщем походу это просто лишнее.
PM MAIL   Вверх
4ygynOK
Дата 12.10.2013, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.10.2013

Репутация: нет
Всего: нет



Цитата(baldina @ 11.10.2013,  18:28)
тут что-то с логикой. 
убери строчки 25-28, 34-35: если есть вложенные папки, их надо удалить, что и делается в цикле. но сама папка не удаляется (из-за проверки и условия), поэтому не удается удалить и родительские. вобщем походу это просто лишнее.

Код

BOOL CUGODatabaseMng::DeleteDir(DWORD BUGO_Id)
{
    ASSERT(m_pDatabaseMng);
    if (!m_pDatabaseMng)
        return FALSE;
    
  
    try
    {
        std::list<DWORD> lstIds;
        CString sSQL;
        sSQL.Format(_T("SELECT ID FROM BUGO WHERE PARENT_ID=%d"), BUGO_Id);
        ADODB::_RecordsetPtr spRS = m_pDatabaseMng->OpenRecordset(sSQL);
        long nRecordCount = spRS->GetRecordCount();
        
        for (long nRecord = 0; nRecord < nRecordCount; ++nRecord)
        {
            lstIds.push_back((long)spRS->GetFields()->GetItem(_T("ID"))->GetValue());
            spRS->MoveNext();
        }
        
        spRS->Close();
        for (std::list<DWORD>::iterator it = lstIds.begin(); it != lstIds.end(); ++it)
                          
            if (!DeleteDir(*it))
                return FALSE;
       
     
            sSQL.Format(_T("DELETE FROM BUGO WHERE ID=%d"), BUGO_Id);
            VERIFY(m_pDatabaseMng->ExecuteSQL(sSQL));
            return TRUE;
       
    }
    catch (_com_error& e)
    {
        if (AfxMessageBox(CString(_T("Удаление каталога невозможно!\n")) + (LPCTSTR)e.Description() + CString(_T("\nПродолжить удаление?")),MB_OKCANCEL) == IDOK)
        {
            return TRUE;
        }
        else return FALSE;
    }
    return FALSE;
}

если сделать так то впринципе удаляется. Вот только не так как надо: допустим у нас есть один родительский каталог и 2 подкаталога, если мы можем удалить только один из двух подкаталогов, то этот код удалит этот 1 подкаталог, а ещё родительский впридачу, что делать не нужно, для этого я и организовал это условие. Вот как-то так пока. Спасибо baldina что помогаешь!!
PM MAIL   Вверх
akizelokro
Дата 12.10.2013, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

Репутация: 1
Всего: 5



Если не делается, как советует baldina, то оберни твой цикл for(...) в цикл

while(lstIds.size() > 0)
{
// твой for, в котором ты будешь удалять каталоги, для которых не указан некий родительский, проверку на это надо будет
// тоже впихнуть. при удалении каталоги будешь удалять из контейнера соответствующий элемент.
}

Это сообщение отредактировал(а) akizelokro - 12.10.2013, 07:36


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
baldina
Дата 12.10.2013, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(4ygynOK @  12.10.2013,  00:21 Найти цитируемый пост)
 Вот только не так как надо: допустим у нас есть один родительский каталог и 2 подкаталога, если мы можем удалить только один из двух подкаталогов, то этот код удалит этот 1 подкаталог, а ещё родительский впридачу

нет. 
ф-ия DeleteDir(DWORD BUGO_Id) должна удалять BUGO_Id и его подкаталоги, но не родительский.
она сейчас так и делает:
Цитата(4ygynOK @  10.10.2013,  17:14 Найти цитируемый пост)
sSQL.Format(_T("SELECT ID FROM BUGO WHERE PARENT_ID=%d"), BUGO_Id);

Цитата(4ygynOK @  10.10.2013,  17:14 Найти цитируемый пост)
sSQL.Format(_T("DELETE FROM BUGO WHERE ID=%d"), BUGO_Id);

так что все в порядке.
если есть два каталога (скажем с id 2 и 3) в родительском (id=1), и мы хотим удалить каталог с id=2, то вызываем DeleteDir(2). каталоги с id=1, id=3 останутся нетронутыми
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0920 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.