Kapatılmamış dosyalar içeriyorsa klasör silinmez - sayfa 8

 

Biraz sonra sorunu yeniden üreten bir komut dosyası yayınlayacağım.

Sorun bir şekilde çözülürse, her şeyi ayrıntılı olarak belirteceğim.

 
Реter Konow :

1. Tutamaç yalnızca FileClose işlevi için gereklidir. Dosyayı açmıyorum. Benden önce yaratıldı. Sadece kopyalayıp yapıştırıyorum. Kulp olmadığı için kapatamıyorum.

2. Kopyalama (FileCopy), taşıma (FileMove) için dosya tanıtıcısına gerek yoktur. Belgelere bakın.

3. Daha önce biri tarafından oluşturulan bir dosyayı FileOpen işleviyle açarsam, tutamağını alamayacağım. Hangi kolu alacağım hiç bilinmiyor. Onun olabilir veya tamamen farklı olabilir. Bir başkasının dosyasını, kopyalama işleminden sonra FileClose tarafından kapatılacak şekilde ele almaya çalıştım. Hiç bir şey.

4. Kopyalama sırasında tutamaç gerekli değildir. Sorunsuz kopyalandı. Ancak dosya kopyalamak için otomatik olarak açılır. Ayrıca, tutamaç olmadığı için FileClose s ile kapatamıyorum. Bu muhtemelen, kopyalanan dosyaları sildikten sonra FolderClean'in çalışmamasının nedenidir.

5. Kopyaladıktan sonra dosyanın açılmadığını nasıl anlarsınız? Açıkça FileOpen işlevi tarafından açılmadı, ancak onunla kopyalandı, yani açık. Bu nedenle kopyalandıktan sonra ve hatta silindikten sonra açık kalır. Muhtemelen.

1. Bir dosya tanıtıcısı yalnızca onu kapatmak için değil, aynı zamanda bir dosyayı okumak ve dosyaya yazmak, belirli bir satırdan okumak veya belirli bir satıra yazmak için bir dosya işaretçisini yönetmek için de gereklidir. Dosya tanıtıcısı gerektiren diğer işlevler belgelerde bulunabilir.

2. Bir dosyayı kopyalamanın veya taşımanın bu dosya için bir tanıtıcı gerektirdiğini söyleyemem? Bir şeyi yanlış anladın.

3. Herhangi bir dosyayı açarsanız, onu kimin ve ne zaman oluşturduğuna bakılmaksızın, FileOpen yürütmesi sırasında tutamağını alırsınız.

Sapın ne olduğunu yanlış anladığınızdan şüpheleniyorum. Deney için 2 dosya alın, hazır hale getirebilir, yazıya açıp tutamaçlarını alabilirsiniz. Bire bir farklılık gösterecekler. Ardından bu dosyaları açma sırasını değiştirin, aynı tutamaçları göreceksiniz, ancak bunlar başka dosyalara ait olacak. İkinci seçenek: Bir dosya açın, bir tanıtıcı =1 alın, bu dosyayı kapatın ve başka bir tane açın... ve bu diğer dosyanın tanıtıcısı da =1 olacaktır.

Bir tanıtıcı, yalnızca program içindeki dosyaların numaralandırılmasıdır ve hiçbir şekilde dosyanın içeriği veya diğer öznitelikleri ile bağlantılı değildir.

4. Dosya kopyalama sırasında açılmıyor. Ve bir dosyayı okuyarak ve tüm içeriği başka bir dosyaya yazarak kopyalarsanız, bu dosyalarla daha fazla çalışmak için bu dosyaların tutamaçları uygun değişkenlere yerleştirilmelidir.

5. Kopyalama sırasında, dosyanın diske kaydedilmesi kadar sürmesi birkaç milisaniye sürebilir. O zaman gökyüzünde bir kuş kadar özgürdür... Olasılıksız.

 

Sorunun tamamen çözüldüğünü bildirmekten mutluluk duyuyorum!

Sebeb olmak:

Dizideki dosya hiyerarşisinin bir kopyasını oluştururken, kullanıcıda yeniden oluşturmak için. dosya gezgini, özel bir işlev FileFindFirst() ve FileFindNext() işlevlerini kullanarak bu hiyerarşiyi okur.

Başlangıçta, her klasörün taranması tamamlandıktan sonra, döngünün sonunda FileFindClose() işlevi çağrılır ve bu işlev, her belirli klasör için arama tutamacını kapatır.

Açıkçası, dosya hiyerarşisini okuyan fonksiyonla uzun ve karmaşık manipülasyonlar sonucunda bu FileFindClose() girişini yanlışlıkla sildim ve fark etmedim. Klasörleri yeniden adlandırmaya çalışmaya başlayana kadar gezginimin çalışmasını etkilemedi. İşte sorun burada başladı.

Dosyaların, ortaya çıktığı gibi, bu durumda onunla hiçbir ilgisi yok. Ameliyat olmasalar bile zorunlu olarak kapatılmalarının gerekliliğini öğrenmem elbette çok faydalı oldu. Gelecekte, bu beni benzer hatalardan kurtaracak.


Genel olarak, FolderClean() işlevinin benim için çalışmamasının nedeni, kullanımından çok önce, program başlatma aşamasında bile, klasörleri taradıktan sonra başka bir işlevin FileFindFirst() işlevinin arama tutamaçlarını kapatmamasıydı.

Görünen o ki, bu şeyler bağlantılı...


Sorunu yeniden oluşturmak için bir komut dosyası oluşturdum, ancak bu komut dosyasında nedense bu sorun yeniden oluşturulmuyor. Yani programımda "FileFindClose (search_handle)" satırını eklemek/silmek sorunu gerçekten etkiliyor, ancak komut dosyasında nedense değil.

Scripti aşağıya ekliyorum. Dosyalar klasöründe bir "1" klasörü oluşturun ve başka herhangi bir klasör veya dosyayı oraya yerleştirin. Komut dosyasını yüklerken, klasör silinmelidir. "FileFindClose(search_handle)" satırını yorumlarsanız, komut dosyası klasörü silecektir, ancak programımda bu satır olmadan klasörler silinmez. Nedeni açık değil.

 //+------------------------------------------------------------------+
//|                                             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" );
     } 
  }
//+------------------------------------------------------------------+