Não apagar uma pasta se ela contiver arquivos não fechados - página 8

 

Publicarei um roteiro reproduzindo o problema mais tarde.

Se o problema for resolvido de alguma forma, explicarei tudo em detalhes.

 
Реter Konow:

1. o cabo só é necessário para a função FileClose. Eu não abro o arquivo. Foi criado antes de mim. Eu apenas o copio e excluo. Não posso fechá-lo porque não há alça.

2. O cabo de arquivo não é necessário para copiar (FileCopy), para mover (FileMove). Veja a documentação.

3. Se eu abrir um arquivo criado por outra pessoa usando a função FileOpen, eu não conseguirei seu controle. Não se sabe de modo algum qual o manuseio que vou conseguir. Pode ser dele ou pode ser bem diferente. Eu tentei pegar o arquivo de outra pessoa para poder fechar FileClose depois da operação de cópia. Não funcionou.

4. Ao copiar, o cabo não é necessário. É copiado sem nenhum problema. Mas o arquivo é automaticamente aberto para cópia. Além disso, não posso fechá-lo com FileClose porque não há alça. É provavelmente por isso que o FolderClean não funciona depois de apagar os arquivos copiados.

5. Como você sabe que o arquivo não está aberto após a cópia? Não foi explicitamente aberto pela função FileOpen, mas estava sendo copiado com, o que significa que está aberto. Portanto, permanece aberta após a cópia e mesmo após o apagamento. Provavelmente.

É necessário um cabo de arquivo não apenas para fechar um arquivo, mas também para ler e escrever em um arquivo, gerenciar um ponteiro de arquivo para ler de uma linha especificada ou escrever em uma linha especificada. Outras funções que requerem uma manipulação de arquivo podem ser encontradas na documentação.

2. Eu não poderia lhe dizer que para copiar ou mover um arquivo você precisa de um cabo para esse arquivo? Você entendeu mal alguma coisa.

Se você abrir qualquer arquivo, não importa por quem ou quando foi criado, você terá seu controle quando FileOpen for executado.

Suspeito que você tenha entendido mal o que é um cabo. Leve 2 arquivos para uma experiência, você pode tê-los prontos, você pode abri-los para escrever e obter suas alças. Eles serão diferentes por um. Então inverta a ordem de abertura desses arquivos e você verá as mesmas alças, mas elas pertencerão a arquivos diferentes. Segunda opção: Abra um arquivo, pegue o handle = 1, feche esse arquivo e abra outro... e o cabo do outro arquivo também será =1.

Um cabo é a numeração dos arquivos dentro do programa e não tem nada a ver com o conteúdo do arquivo ou seus outros atributos.

4. O arquivo não será aberto durante o processo de cópia. E se você estiver copiando lendo um arquivo e escrevendo todo o conteúdo para outro arquivo, os cabos desses arquivos devem ser colocados nas variáveis apropriadas para posterior manipulação desses arquivos.

5. Um arquivo pode levar alguns milissegundos durante a cópia, exatamente o tempo necessário para salvá-lo em disco. De lá é tão livre como um pássaro no céu. Nenhuma chance de que algo aconteça.

 

Tenho o prazer de informar que o problema está completamente resolvido!)

A razão:

Ao construir uma cópia da hierarquia de arquivos na matriz, a fim de reproduzi-la em um navegador de arquivos utilizável, uma função especial lê esta hierarquia usando FileFindFirst() e FileFindNext().

Inicialmente, após cada pasta ser escaneada, a função FileFindClose() foi chamada no final do loop para fechar a alça de busca de cada pasta específica.

Obviamente, devido a longas e complexas manipulações com a função que lê a hierarquia do arquivo, eu apaguei acidentalmente esta entrada FileFindClose() e não notei. Isso não afetou o desempenho do meu navegador, até que comecei a tentar renomear pastas. Foi aí que o problema começou.

Os arquivos, como se viu, não tiveram nada a ver com isso neste caso. É claro que é muito útil que eu tenha aprendido que eles devem ser fechados, mesmo que eu não tenha feito nada a eles. No futuro, isso me impedirá de cometer os mesmos erros.


Em geral, a razão pela qual minha função FolderClean() não funcionou foi muito antes de eu usá-la, durante a fase de inicialização do programa, outra função não fechou as alças de busca FileFindFirst() após a digitalização das pastas.

Como se viu, estas coisas estão relacionadas...


Eu fiz um roteiro para reproduzir o problema, mas por alguma razão, neste roteiro, este problema não é reproduzido. Isto é, em meu programa, adicionar/remover a linha "FileFindClose(search_handle)" afeta o problema, mas no script, por alguma razão, não afeta.

Estou anexando o roteiro abaixo. Crie uma pasta "1" na pasta Arquivos e coloque lá qualquer outra pasta ou arquivo. Ao carregar o script, a pasta deve ser apagada. Se você comentar a linha "FileFindClose(search_handle)", o script ainda irá apagar a pasta, mas em meu programa sem esta linha as pastas não são apagadas. A razão não é clara.

//+------------------------------------------------------------------+
//|                                             Demo_FolderClean.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//Данный скрипт, сразу после загрузки должен стереть все содержимое 
//папки "1\\" внутри директории "Files".
//Однако, если хэндл поиска, открытый сразу после запуска скрипта функцией
//"FileFindFirst()" не закрыт, то скрипт не сможет стереть папку "1\\".

//Данный скрипт создан для демонстрации взаимосвязи закрытия хэндла поиска
//возвращаемого функцией "FileFindFirst()" и успешной работы функции "FolderClean()".
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   
   //---- Переменная необходимая для функции  "FileFindFirst()" 
   string file_name;
   //-----------------------------
   //Открываем поиск внутри папки "1\\".
   //-----------------------------
   long search_handle=FileFindFirst("1\\",file_name); 
   //--- проверим, успешно ли отработала функция FileFindFirst() 
   if(search_handle!=INVALID_HANDLE) 
     { 
      int i = 0;
      //--- в цикле проверим являются ли переданные строки именами файлов или директорий 
      do 
        { 
         ResetLastError(); 
         //--- если это файл, то функция вернет true, а если директория, то функция генерирует ошибку ERR_FILE_IS_DIRECTORY 
         FileIsExist(file_name); 
         PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "File",file_name); 
         i++; 
        } 
      while(FileFindNext(search_handle,file_name)); 
      //--- закрываем хэндл поиска 
      FileFindClose(search_handle); 
     } 
   else 
      Print("Files not found!");/**/ 
   //-----------------------------
   //Переходим к очищению папки "1\\" и ее последующему стиранию.
   //-----------------------------
   if(!FolderClean("1\\"))
   //--- Очищаем папку.
     Print("FolderClean  Error ",GetLastError());
   
   else 
     {//--- Стираем папку.
      if(!FolderDelete("1\\"))
        Print("FolderDelete  Error ",GetLastError());
      
      else 
       Print("Folder was cleaned and removed");
     } 
  }
//+------------------------------------------------------------------+