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

 
Eu me perguntava do que se tratava. Quando eu estiver livre, vou investigar... É claro, eu gostaria de uma declaração mais concisa sobre a tarefa
 
Vladimir Karputov:

Por favor, continue - desde que você escreva no fascinante gênero de "ficção". Esperamos que por volta da página 40 você tenha passado para a literatura técnica.

O erro está implícito. É difícil dar mais detalhes técnicos no momento.
 
Реter Konow:

Tenho todos os arquivos apagados, mesmo sem fechá-los explicitamente. Apagadas porque eu não as criei e elas estavam anteriormente dentro da pasta de Arquivos.

A questão é que, para apagar um arquivo, precisamos de sua alça. Entretanto, se não criamos este arquivo, mas apenas o colocamos na pasta FileClose(), não podemos obtê-lo, e portanto não podemos fechá-lo com FileClose().

Ao mesmo tempo, ainda podemos copiá-lo ou apagá-lo. Entretanto, a pasta não pode ser apagada depois disso, nem programática nem manualmente. Manualmente somente depois de reiniciar o terminal.

Tentarei reproduzir o problema mais claramente mais tarde, com exemplos ilustrativos.

O código só tem que estar completo. Se o arquivo estiver aberto, ele deverá ser fechado antes do desligamento do computador ou fechamento do MT4/5. E de preferência, o cabo deve ser acessível de qualquer lugar do programa. Este é o IMHO. Melhor ainda, feche o arquivo imediatamente após realizar uma operação de leitura/escrita com ele ou mesmo se você não tiver que fazer nada com ele.

A documentação do exemplo parece mostrar como não fazer isso.

Também é muito importante lembrar que ao escrever em um arquivo, o arquivo escrito só pode ser lido lavando todos os dados restantes no buffer de E/S do arquivo para o disco usando FileFlush ou fechando o arquivo. O fechamento do arquivo forçará um reset dos dados em disco.

Resumo: Se você abrir um arquivo, não se esqueça de fechá-lo. E o cabo do arquivo não será perdido.

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Alexey Viktorov:

O código simplesmente precisa estar completo. Se um arquivo estiver aberto, ele deve ser fechado antes de desligar o computador ou fechar o MT4/5. E o cabo, de preferência, deve ser acessível de qualquer lugar do programa. Este é o IMHO. Melhor ainda, feche o arquivo imediatamente após a operação de leitura/escrita com ele ou mesmo se você não tiver que fazer nada com ele.

A documentação do exemplo parece mostrar como não fazer isso.

Também é muito importante lembrar que ao escrever em um arquivo, o arquivo escrito só pode ser lido lavando todos os dados restantes no buffer de E/S do arquivo para o disco usando FileFlush ou fechando o arquivo. O fechamento do arquivo forçará um reset dos dados em disco.

Resumo: Se você abrir um arquivo, não se esqueça de fechá-lo. E o cabo do arquivo não será perdido.

Mais uma vez, posso fechar um arquivo criado por meu programa usando a função FileClose() - eu tenho sua alça.

Eu não posso fechar um arquivo criado por outra pessoa, mas existente na pasta Arquivos, porque não tenho um cabo para ele.

Se eu copiar o arquivo, que não foi criado por mim (não meu programa), então eu não posso fechá-lo após copiar com a função FileClose() (sem alça), MAS eu posso apagá-lo.

Talvez seja por isso que as pastas com arquivos copiados e excluídos não são excluídos pela função FolderClean(). Provavelmente, porque eles não foram fechados depois de serem copiados.

MAS ELES NÃO PODEM SER FECHADOS PORQUE NÃO TÊM ALÇA!

:)))

 

Perguntas para os desenvolvedores:

1. Como obter a manipulação do arquivo que foi criado na pasta Arquivos antes de carregar o script?

2. O problema de apagar pastas usando FolderClean(), depois de apagar arquivos nelas que foram previamente copiados para outra pasta e não fechados após a cópia (porque não há nenhuma alavanca), poderia ter a causa acima?

 
Реter Konow:

Perguntas para os desenvolvedores:

1. Como obter a manipulação do arquivo que foi criado na pasta Arquivos antes de carregar o script?

2. O problema de apagar pastas usando a função FolderClean(), depois de apagar arquivos nelas que foram previamente copiados para outra pasta e não fechados após a cópia (porque não há nenhuma alavanca), poderia ter a razão acima?


Este é mais ou menos o básico do sistema operacional. Se um aplicativo tiver aberto um arquivo para escrita, nem esse arquivo nem a pasta que o contém podem ser apagados. Tente abrir um arquivo no Word e depois usar as ferramentas do sistema operacional para excluir a pasta em que está. O que vai acontecer? Você não poderá fazê-lo, porque não terá acesso a ele.

Bem, você pode obter o arquivador. Mas de que serviria tal ação? Afinal de contas, se o arquivo for aberto por outro aplicativo, você verá a declaração anterior. Receberemos apenas uma alça que seja válida em nossa aplicação.

 
Ihor Herasko:

Este é mais ou menos o básico do sistema operacional. Se um aplicativo tiver aberto um arquivo para escrita, nem o arquivo nem a pasta que o contém podem ser apagados. Tente abrir um arquivo no Word e depois usar o sistema operacional para excluir a pasta onde ele se encontra. O que vai acontecer? Você não poderá fazê-lo, porque não terá acesso a ele.

Bem, você pode obter o arquivador. Mas de que serviria tal ação? Afinal de contas, se o arquivo for aberto por outro aplicativo, você verá a declaração anterior. E só podemos obter uma alça que seja válida em nossa aplicação particular.

O arquivo é aberto por minha aplicação (navegador de arquivos) para ser sobrescrito em outra pasta.

Depois de escrever por cima, preciso fechar o arquivo, mas não posso - (sem alça), então eu simplesmente apago o arquivo.

Não há nenhuma maçaneta porque o arquivo foi criado desconhecido quando e por quem.

Ao mesmo tempo, o arquivo existe dentro da pasta Files e pode ser copiado para outra pasta e depois apagado.

Mas após a cópia, o arquivo não pode ser fechado. Não há alça.

É provavelmente por isso que o apagamento de pastas FolderClean() com arquivos apagados, não funciona.


Questão: como faço para colocar este arquivo no programa MQL?

 

Este parece ser um problema ainda não enfrentado na comunidade. :)

OK, vou pensar em algo.

Eu sempre faço).

 

Mitos desmascaradores.

Portanto, dados terminais no sistema operacional:

2017.08.28 22:20:53.474 Terminal        MetaTrader 5 x64 build 1653 started (MetaQuotes Software Corp.)
2017.08.28 22:20:53.476 Terminal        Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120 M  @ 2.50 GHz, RAM: 4830 / 8077 Mb, HDD: 315702 / 475588 Mb, GMT+02:00
2017.08.28 22:20:53.476 Terminal        C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075

No momento dos testes, a pasta "test" foi criada em [pasta de dados]\MQL5\Files e o arquivo de texto "source.txt" com o seguinte conteúdo foi criado nele:

FileCopy
The function copies the original file from a local or shared folder to another file.
bool  FileCopy( 
   const string  src_file_name,     // Name of a source file 
   int           common_flag,       // Location 
   const string  dst_file_name,     // Name of the destination file 
   int           mode_flags         // Access mode 
   );


Então, passo 1: Cópia do arquivo "source.txt" para outro usando ferramentas MQL5

Roteiro:

//--- display the window of input parameters when launching the script 
#property script_show_inputs 
//--- input parameters 
input string InpSrc="test\\source.txt";       // source 
input string InpDst="test\\destination.txt";  // copy 
input int    InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- display the source contents (it must exist) 
   if(!FileDisplay(InpSrc))
      return;
//--- check if the copy file already exists (may not be created) 
   if(!FileDisplay(InpDst))
     {
      //--- the copy file does not exist, copying without FILE_REWRITE flag (correct copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
   else
     {
      //--- the copy file already exists, try to copy without FILE_REWRITE flag (incorrect copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
      //--- InpDst file's contents remains the same 
      FileDisplay(InpDst);
      //--- copy once more with FILE_REWRITE flag (correct copying if the file exists) 
      if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
//--- receive InpSrc file copy 
   FileDisplay(InpDst);
  }
//+------------------------------------------------------------------+ 
//| Read the file contents                                           | 
//+------------------------------------------------------------------+ 
bool FileDisplay(const string file_name)
  {
//--- reset the error value 
   ResetLastError();
//--- open the file 
   int file_handle=FileOpen(file_name,FILE_READ|FILE_WRITE|FILE_TXT|InpEncodingType);
   if(file_handle!=INVALID_HANDLE)
     {
      //--- display the file contents in the loop 
      Print("+---------------------+");
      PrintFormat("File name = %s",file_name);
      while(!FileIsEnding(file_handle))
         Print(FileReadString(file_handle));
      Print("+---------------------+");
      //--- close the file 
      FileClose(file_handle);
      return(true);
     }
//--- failed to open the file 
   PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
   return(false);
  }
//+------------------------------------------------------------------+


Etapa 2: Limpeza da pasta "teste" usando ferramentas MQL5

Roteiro:

//+------------------------------------------------------------------+
//|                                                  FolderClean.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderClean()." 
//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   foldername="test";  // folder in MQL5/Files/ 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Start to delete files 
   PrintFormat("Trying to delete all files from folder %s",foldername);
   if(FolderClean(foldername,0))
      PrintFormat("Files have been successfully deleted, %d files left in folder %s",
                  foldername,
                  FilesInFolder(foldername+"\\*.*",0));
   else
      PrintFormat("Failed to delete files from folder %s. Error code %d",foldername,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+ 
//| Returns the number of files in the specified folder              | 
//+------------------------------------------------------------------+ 
int FilesInFolder(string path,int flag)
  {
   int count=0;
   long handle;
   string filename;
//--- 
   handle=FileFindFirst(path,filename,flag);
//--- If at least one file found, search for more files 
   if(handle!=INVALID_HANDLE)
     {
      //--- Show the name of the file 
      PrintFormat("File %s found",filename);
      //--- Increase the counter of found files/folders 
      count++;
      //--- Start search in all files/folders  
      while(FileFindNext(handle,filename))
        {
         PrintFormat("File %s found",filename);
         count++;
        }
      //--- Do not forget to close the search handle upon completion 
      FileFindClose(handle);
     }
   else // Failed to get the handle 
     {
      PrintFormat("Files search in folder %s failed",path);
     }
//--- Return the result 
   return count;
  }
//+------------------------------------------------------------------+


Etapa 3: Eliminação da pasta "teste" usando ferramentas MQL5

//+------------------------------------------------------------------+
//|                                                 FolderDelete.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderDelete()." 
#property description "First two folders are created; one of them is empty, the second one contains a file." 
#property description "When trying to delete a non-empty folder, an error is returned and a warning is shown."

//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   InpFolder="test";     // An empty folder 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Delete the comment form the chart 
   Comment("");
//--- Add a message into the "Experts" journal 
   PrintFormat("Trying to delete folder %s",InpFolder);
   ResetLastError();
//--- Delete the empty folder 
   if(FolderDelete(InpFolder))
      //--- The following message should appear since the folder is empty 
      PrintFormat("Folder %s has been successfully deleted",InpFolder);
   else
      PrintFormat("Failed to delete folder %s. Error code=%d",InpFolder,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+


Qual é o problema? Tudo funciona.

Arquivos anexados:
 
Vladimir Karputov:

Qual é o problema? Tudo funciona.

Obrigado por esse exemplo. Descobrirei amanhã de manhã. Eu não tenho energia neste momento).

Vou testar tudo e lhe darei uma resposta.


Adicionado:

Você citou aqui três roteiros diferentes.

Eu tenho um programa e copiar, apagar arquivos e pastas acontece dentro de uma função em dois ciclos.

Entrar no primeiro ciclo: primeiro os arquivos fonte são copiados para outra pasta, depois esses arquivos fonte são apagados. Sair do primeiro ciclo.

Entre no segundo loop: Limpamos a pasta de origem com FolderClean() e apagamos a pasta de origem com -FolderDelete().


Em seguida, olhamos no navegador de arquivos no meta-editor e vemos que a pasta de origem foi parcialmente apagada. As subpastas que não tinham arquivos foram completamente apagadas e aquelas que tinham alguns arquivos não foram apagadas, mas estão vazias.

Tentando remover pastas manualmente - nós a temos:



Em seguida, fechamos o terminal e o iniciamos novamente. Vemos que algumas subpastas desapareceram por conta própria, outras permaneceram. Nós os apagamos manualmente sem nenhum problema. Desta vez.

Razão: