닫지 않은 파일이 포함된 폴더는 삭제되지 않습니다. - 페이지 2

 
Rashid Umarov :

어떤 이유로 운영 체제는 파일 삭제를 허용하지 않습니다. 다른 프로그램에서 파일을 열었거나 권한이 충분하지 않습니다.

정확히. 이미 하위 폴더와 파일이 포함된 폴더를 삭제하려고 하면 파일을 먼저 삭제합니다. 하위 폴더만 남습니다. FolderClean()으로 정리한 다음 FolderDelete()를 호출합니다. 그러나 결과적으로 비어 있던 하위 폴더는 잘 삭제되지만 하위 폴더 안에 더 많은 하위 폴더가 있으면 삭제되지 않습니다. 그 후 MetaEditor의 파일 탐색기에서 수동으로 폴더를 삭제하려고 시도하지만 터미널은 폴더를 삭제하지 않고 다음 창을 표시합니다.

"계속"을 클릭하고 변경 사항에 동의하지만 폴더는 여전히 지워지지 않습니다. 터미널을 완전히 닫았다가 다시 열면 삭제했어야 하는 폴더가 저절로 사라지거나 하지 않지만 이미 위의 창 없이 수동으로 삭제할 수 있습니다.

여기에 몇 가지 이상한 점이 있습니다 ...

 
Vladimir Karputov :

입증해야 할 사항: 이전 터미널에는 MQL5 프로그램이 표시되지 않습니다. MQL5 스크립트 에서 다른 사람의 파일 샌드박스를 열려고 합니다.

기능은 두 터미널에서 동일하게 작동합니다. 스크립트가 실행 중인 터미널의 파일 샌드박스가 사용됩니다. 사용 중인 터미널의 기본 파일입니다. 저를 믿으십시오, 이것은 확실히 문제가 아닙니다 ...
 
Rashid Umarov :


추신 그리고 일반적으로 - 프로그램 로그를 제공하지 않음 - 이것은 다른 사람들이 커피 찌꺼기를 추측하도록 하기 위한 것입니다.

이 gif를 보세요.



위의 마지막 페이지에서 이 스크립트의 코드를 제공했습니다.

 

먼저 프로그래밍 방식으로 지운 다음 수동으로 지우려는 폴더가 어디에도 열려 있지 않다는 점을 추가하겠습니다. 더욱이, 그것들은 비어 있고 그로부터의 파일이 이전에 지워졌기 때문에 MetaEditor의 파일 탐색기 자체 이외의 다른 곳에서 열 수 없습니다. 삭제된 파일도 어디에도 열리지 않았습니다.

메타 편집기의 파일 탐색기에서 수동으로 폴더를 삭제하기 위해 관리자 확인이 필요한 창은 이전 에 FolderClean() 및 FolderDelete() 함수를 사용하여 프로그램이 삭제하려고 했던 폴더를 삭제하려고 할 때만 나타납니다. 다른 폴더를 삭제하려고 하면 이 창이 나타나지 않습니다.

 
Реter Konow :

이 스크립트에서 FolderClean() 함수가 작동하지 않는 이유는 무엇입니까?

폴더를 정리하려고 하면 오류 5026이 표시됩니다. (폴더를 지울 수 없음).

이 스크립트는 문서( FolderDelete() 함수 섹션)에서 가져오고 약간 수정했습니다. 다른 하위 폴더나 파일이 포함된 폴더를 완전히 삭제하려면 폴더를 비워야 합니다. 이를 위해 FolderClean() 함수에 대한 호출이 추가되었습니다.

그리고 왜 파일을 닫지 않는지 관심을 가질 수 있습니까? 아니면 나만 안보이나요?

다음은 파일 열기부터 삭제 요청까지의 코드 스니펫입니다...

   handle= FileOpen (filepath, FILE_WRITE | FILE_TXT ); // флаг FILE_WRITE в данном случае обязателен, см. справку к функции FileOpen 
   if (handle!= INVALID_HANDLE ) 
       PrintFormat ( "Открыли файл на чтение %s" ,working_folder+ "\\" +filepath); 
   else 
       PrintFormat ( "Не удалось создать файл %s в папке %s. Код ошибки=" ,filename,secondFolder, GetLastError ());
 
   Comment ( StringFormat ( "Готовимся удалить папки %s и %s" , firstFolder, secondFolder)); 
//--- Небольшая пауза в 5 секунд, чтобы мы могли прочитать сообщение на графике 
   Sleep ( 5000 ); // Sleep() нельзя использовать в индикаторах!
 
//--- выведем диалоговое окно и просим пользователя 
 
Alexey Viktorov :

그리고 왜 파일을 닫지 않는지 관심을 가질 수 있습니까? 아니면 나만 안보이나요?

다음은 파일 열기부터 삭제 요청까지의 코드 스니펫입니다...

내가 아는 한, 파일 함수(예: FileWrite())를 사용하여 파일에 변경 사항이 없으면 파일을 닫을 필요가 없습니다. FileOpen() 함수는 단순히 새 파일을 생성하며 이 작업은 파일을 닫을 필요가 없습니다(이 함수에 대한 설명서에는 생성 후 파일을 닫아야 한다고 나와 있지 않습니다). 또한, 이 스크립트는 문서에서 가져온 것이며 나는 거기에서 어떤 것도 지배하지 않았습니다. FolderClean() 함수 로 라인을 추가했습니다.
 
Реter Konow :
내가 아는 한 FileWrite() 함수를 사용하여 파일에 변경 사항이 없으면 닫을 필요가 없습니다. FileOpen() 함수는 단순히 새 파일을 생성하며 이 작업에서는 파일을 닫을 필요가 없습니다. 또한, 이 스크립트는 문서에서 가져온 것이며 나는 거기에서 어떤 것도 지배하지 않았습니다. FolderClean() 함수 로 라인을 추가했습니다.

그러나 디버거로 코드를 살펴보면 FileOpen() 실행 직후 디스크에 크기가 0인 파일이 있습니다. 그리고 문서에는 많은 오류와 부정확성이 있습니다.

 
Alexey Viktorov :

그러나 디버거로 코드를 살펴보면 FileOpen()을 실행한 직후 디스크에 크기가 0인 파일이 있습니다. 그리고 문서에는 많은 오류와 부정확성이 있습니다.

따라서 이 예에서는 크기가 0이어야 합니다.

이제 스크립트 에 파일의 명시적 닫기 를 추가하고 다시 시도하겠습니다.

 
Реter Konow :

따라서 이 예에서는 크기가 0이어야 합니다.

이제 스크립트 에 파일의 명시적 닫기 를 추가하고 다시 시도하겠습니다.

코드 샘플을 거의 보지 않고 폴더 삭제도 문제 없이 잘 되었습니다. 그래서 나는 이것이 문제라고 99% 확신합니다.
 

결과는 동일합니다.

새 코드는 다음과 같습니다.

 //+------------------------------------------------------------------+ 
//|                                            Demo_FolderDelete.mq5 | 
//|                        Copyright 2011, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "Copyright 2011, MetaQuotes Software Corp." 
#property link        "https://www.mql5.com" 
#property version    "1.00" 
//--- описание 
#property description "Скрипт показывает пример использования FolderDelete()." 
#property description "Сначала создаются две папки, одна пустая, другая содержит файл." 
#property description "При попытке удаления непустой папки получим ошибку и предупреждение."
 
//--- покажем окно входных параметров при запуске скрипта 
#property script_show_inputs 
//--- входные параметры 
input string    firstFolder= "empty" ;     // пустая папка 
input string    secondFolder= "nonempty" ; // папка, в которой будет один файл 
string filename= "delete_me.txt" ;       // имя файла, который мы создадим в папке secondFolder 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart () 
  { 
//--- хендл файла запишем сюда 
   int handle; 
//--- выясним в какой папке мы работаем 
   string working_folder= TerminalInfoString ( TERMINAL_DATA_PATH )+ "\\MQL4\\Files" ; 
//--- отладочное сообщение    
   PrintFormat ( "working_folder=%s" ,working_folder); 
//--- попытка создать пустую папку относительно пути MQL4\Files 
   if ( FolderCreate (firstFolder, 0 )) // 0 означает, что работаем в локальной папке терминала 
     { 
       //--- выведем полный путь до созданной папки 
       PrintFormat ( "Cоздали папку %s" ,working_folder+ "\\" +firstFolder); 
       //--- сбросим код ошибки 
       ResetLastError (); 
     } 
   else 
       PrintFormat ( "Не удалось создать папку %s. Код ошибки %d" ,working_folder+ "\\" +firstFolder, GetLastError ());
 
//--- теперь создадим непустую папку с помощью функции FileOpen() 
   string filepath=secondFolder+ "\\" +filename;   // сформируем путь для файла, который хотим открыть на запись в несуществующей папке 
   handle= FileOpen (filepath, FILE_WRITE | FILE_TXT ); // флаг FILE_WRITE в данном случае обязателен, см. справку к функции FileOpen 
   if (handle!= INVALID_HANDLE ) 
     {
//*************************************************************************     
   //---- Явно закрываем файл.   
       FileClose (handle);
//*************************************************************************           
       PrintFormat ( "Открыли файл на чтение %s" ,working_folder+ "\\" +filepath); 
     } 
   else 
       PrintFormat ( "Не удалось создать файл %s в папке %s. Код ошибки=" ,filename,secondFolder, GetLastError ());
 
   Comment ( StringFormat ( "Готовимся удалить папки %s и %s" , firstFolder, secondFolder)); 
//--- Небольшая пауза в 5 секунд, чтобы мы могли прочитать сообщение на графике 
   Sleep ( 5000 ); // Sleep() нельзя использовать в индикаторах!
 
//--- выведем диалоговое окно и просим пользователя 
   int choice= MessageBox ( StringFormat ( "Удалить папки %s и %s?" , firstFolder, secondFolder), 
                         "Удаление папок" , 
                         MB_YESNO | MB_ICONQUESTION ); //  будут две кнопки - "Yes" и "No"
 
//--- выполним действия в зависимости от выбранного варианта 
   if (choice== IDYES ) 
     { 
       //--- очистим комментарий на графике 
       Comment ( "" ); 
       //--- выведем сообщение в журнал "Эксперты" 
       PrintFormat ( "Пробуем удалить папки %s и %s" ,firstFolder, secondFolder); 
       ResetLastError (); 
       //--- удаляем пустую папку 
       if ( FolderDelete (firstFolder)) 
         //--- должны увидеть это сообщение, так как папка пустая 
         PrintFormat ( "Папка %s успешно удалена" ,firstFolder); 
       else 
         PrintFormat ( "Не удалось удалить папку %s. Код ошибки=%d" , firstFolder, GetLastError ());
 
       ResetLastError (); 

   //***********************************************************************************************************************   
       //--- сначала очищаем папку
       if ( FolderClean (secondFolder))
         PrintFormat ( "Папка %s успешно очищена" , secondFolder);
       else 
         //---  
         PrintFormat ( "Не удалось очистить папку %s. Код ошибки=%d" , secondFolder, GetLastError ());
   //***********************************************************************************************************************   
   
       ResetLastError (); 
        
       //--- удаляем папку, которая содержит файл               
       if ( FolderDelete (secondFolder)) 
         PrintFormat ( "Папка %s успешно удалена" , secondFolder); 
       else 
         //--- 
         PrintFormat ( "Не удалось удалить папку %s. Код ошибки=%d" , secondFolder, GetLastError ()); 
     }  

   else 
       Print ( "Удаление отменено" ); 
//--- 
  }