Пожалуйста продолжайте - пока Вы пишите в увлекательном жанре "художественная литература". Надеюсь, что эдак к странице 40-й перейдёте на жанр "техническая литература".
Ошибка неявная. Сейчас пока трудно дать больше технических подробностей.
У меня все файлы стираются даже без явного закрытия. Стираются, потому что я их не создавал и они были до этого внутри папки Files.
Дело в том, что чтобы стереть файл, нужен его хендл. Однако, если мы не создавали этот файл, а только поместили его в папку Files, то мы не можем получить его Хэндл, а следовательно и закрыть функцией FileClose() не можем.
При этом, мы все равно можем его скопировать или стереть. Однако, папку после этого удалить не удается ни программно, ни вручную. Вручную только после перезапуска терминала.
Позже попробую воспроизвести проблему более четко, с наглядными примерами.
Просто код должен быть полным. Если открыт файл, значит должен быть и закрыт до выключения компьютера или закрытия МТ4\5. И хендл желательно, должен быть доступен из любого места программы. Это такое ИМХО. А ещё лучше, закрывать файл сразу после проведённой с ним операции чтения\записи, или даже если ничего не пришлось с ним делать.
В примере документации, видимо показали как делать не надо.
Ещё очень важно помнить, что при записи в файл, прочесть записанное можно только скинув на диск все данные, оставшиеся в файловом буфере ввода-вывода функцией FileFlush или закрыв файл. Во время закрытия происходит принудительный сброс данных на диск.
Резюме: Если открыли файл - не забудьте его закрыть. И хендл файла потерян не будет.
Просто код должен быть полным. Если открыт файл, значит должен быть и закрыт до выключения компьютера или закрытия МТ4\5. И хендл желательно, должен быть доступен из любого места программы. Это такое ИМХО. А ещё лучше, закрывать файл сразу после проведённой с ним операции чтения\записи, или даже если ничего не пришлось с ним делать.
В примере документации, видимо показали как делать не надо.
Ещё очень важно помнить, что при записи в файл, прочесть записанное можно только скинув на диск все данные, оставшиеся в файловом буфере ввода-вывода функцией FileFlush или закрыв файл. Во время закрытия происходит принудительный сброс данных на диск.
Резюме: Если открыли файл - не забудьте его закрыть. И хендл файла потерян не будет.
Еще раз: файл созданный моей программой я могу закрыть функцией FileClose() - у меня есть его хэндл.
Файл созданный ранее кем то, но существующий в папке Files, закрыть функцией FileClose() не могу, потому что у меня нет его хендла.
Если я копирую файл созданный не мной (не моей программой), то я не могу его закрыть после копирования функцией FileClose() (нет хэндла), НО МОГУ ЕГО СТЕРЕТЬ.
Возможно, поэтому папки со скопированными и после стертыми файлами, не удаляются функцией FolderClean(). Возможно, потому что они небыли закрыты после копирования.
1. как получить хэндл файла, который был создан в папке Files до загрузки скрипта?
2. Может ли проблема удаления папок с помощью функции FolderClean(), после стирания в них файлов, которые до этого были скопированы в другую папку и не закрыты после копирования (потому что нет хэндла), иметь вышеописанную причину?
1. как получить хэндл файла, который был создан в папке Files до загрузки скрипта?
2. Может ли проблема удаления папок с помощью функции FolderClean(), после стирания в них файлов, которые до этого были скопированы в другую папку и не закрыты после копирования (потому что нет хэндла), иметь вышеописанную причину?
Это, как бы, азы ОС. Если какое-либо приложение открыло файл для записи, то ни этот файл, ни папку, его содержащую, удалить нельзя. Попробуйте открыть файл в Word, а потом средствами ОС удалить папку, в которой он находится. Что будет? Не получится, т. к. нет доступа.
Ну а хендл файла получить можно. Только какой прок от этого действия? Ведь если файл открыт другим приложением, то см. предыдущее высказывание. А хендл мы получим только тот, который валиден именно в нашем приложении.
Это, как бы, азы ОС. Если какое-либо приложение открыло файл для записи, то ни этот файл, ни папку, его содержащую, удалить нельзя. Попробуйте открыть файл в Word, а потом средствами ОС удалить папку, в которой он находится. Что будет? Не получится, т. к. нет доступа.
Ну а хендл файла получить можно. Только какой прок от этого действия? Ведь если файл открыт другим приложением, то см. предыдущее высказывание. А хендл мы получим только тот, который валиден именно в нашем приложении.
Файл открывается моим приложением (файловым навигатором) для перезаписи в другую папку.
После перезаписи мне нужно закрыть файл , но я не могу - (нет хэндла) и просто стираю файл.
Хендла нет, потому что файл был создан неизвестно когда и неизвестно кем.
При этом, файл существует внутри папки Files и может быть скопирован в другую папку и после стерт.
Но после копирования нельзя закрыть этот файл. Нет хэндла.
Вероятно, поэтому дальнейшее стирание папок FolderClean() со стертыми файлами, не срабатывает.
Вопрос: как получить хэндл этого файла в MQL-программу?
2017.08.2822:20:53.474 Terminal MetaTrader 5 x64 build 1653 started (MetaQuotes Software Corp.)
2017.08.2822:20:53.476 Terminal Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120M @ 2.50GHz, RAM: 4830 / 8077 Mb, HDD: 315702 / 475588 Mb, GMT+02:002017.08.2822:20:53.476 Terminal C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075
На момент тестов в папке [data folder]\MQL5\Files создана заранее папка "test" и в ней создан текстовой файл "source.txt" следующего содержания:
FileCopy
The function copies the original file from a local or shared folder to another file.
boolFileCopy(
conststring src_file_name, // Name of a source file int common_flag, // Location conststring dst_file_name, // Name of the destination file int mode_flags // Access mode
);
Итак, шаг 1: Копирование файла "source.txt" в другой файл средствами MQL5
Скрипт:
//--- display the window of input parameters when launching the script #property script_show_inputs//--- input parameters inputstring InpSrc="test\\source.txt"; // source inputstring InpDst="test\\destination.txt"; // copy inputint InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64 //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ voidOnStart()
{
//--- 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!");
elsePrint("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!");
elsePrint("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!");
elsePrint("File is not copied!");
}
//--- receive InpSrc file copy
FileDisplay(InpDst);
}
//+------------------------------------------------------------------+ //| Read the file contents | //+------------------------------------------------------------------+ bool FileDisplay(conststring 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);
}
//+------------------------------------------------------------------+
Спасибо за этот пример. Завтра с утра разберусь. Сейчас уже сил нет.)
Протестирую все и дам ответ.
Добавлено:
Тут Вы привели три разных скрипта.
У меня же одна программа и копирование, стирание файлов и папок происходит внутри одной функции в двух циклах.
Входим в первый цикл: Сначала копируются исходные файлы в другую папку, затем эти файлы-исходники стираются. Выходим из первого цикла.
Входим во второй цилк: Очищаем исходную папку с помощью FolderClean() и стираем исходную папку -FolderDelete().
Далее смотрим в файловый навигатор в метаэдитор и видим, что исходная папка стерлась частично. Подпапки в которых небыло файлов стерлись полностью, а те, в которых были - остались не стертыми, но пустыми.
Пытаемся удалить папки вручную - получаем:
Далее закрываем терминал и запускаем снова. Видим - некоторые подпапки исчезли сами, другие остались. Стираем их вручную без проблем. На этот раз.
Пожалуйста продолжайте - пока Вы пишите в увлекательном жанре "художественная литература". Надеюсь, что эдак к странице 40-й перейдёте на жанр "техническая литература".
У меня все файлы стираются даже без явного закрытия. Стираются, потому что я их не создавал и они были до этого внутри папки Files.
Дело в том, что чтобы стереть файл, нужен его хендл. Однако, если мы не создавали этот файл, а только поместили его в папку Files, то мы не можем получить его Хэндл, а следовательно и закрыть функцией FileClose() не можем.
При этом, мы все равно можем его скопировать или стереть. Однако, папку после этого удалить не удается ни программно, ни вручную. Вручную только после перезапуска терминала.
Позже попробую воспроизвести проблему более четко, с наглядными примерами.
Просто код должен быть полным. Если открыт файл, значит должен быть и закрыт до выключения компьютера или закрытия МТ4\5. И хендл желательно, должен быть доступен из любого места программы. Это такое ИМХО. А ещё лучше, закрывать файл сразу после проведённой с ним операции чтения\записи, или даже если ничего не пришлось с ним делать.
В примере документации, видимо показали как делать не надо.
Ещё очень важно помнить, что при записи в файл, прочесть записанное можно только скинув на диск все данные, оставшиеся в файловом буфере ввода-вывода функцией FileFlush или закрыв файл. Во время закрытия происходит принудительный сброс данных на диск.
Резюме: Если открыли файл - не забудьте его закрыть. И хендл файла потерян не будет.
Просто код должен быть полным. Если открыт файл, значит должен быть и закрыт до выключения компьютера или закрытия МТ4\5. И хендл желательно, должен быть доступен из любого места программы. Это такое ИМХО. А ещё лучше, закрывать файл сразу после проведённой с ним операции чтения\записи, или даже если ничего не пришлось с ним делать.
В примере документации, видимо показали как делать не надо.
Ещё очень важно помнить, что при записи в файл, прочесть записанное можно только скинув на диск все данные, оставшиеся в файловом буфере ввода-вывода функцией FileFlush или закрыв файл. Во время закрытия происходит принудительный сброс данных на диск.
Резюме: Если открыли файл - не забудьте его закрыть. И хендл файла потерян не будет.
Еще раз: файл созданный моей программой я могу закрыть функцией FileClose() - у меня есть его хэндл.
Файл созданный ранее кем то, но существующий в папке Files, закрыть функцией FileClose() не могу, потому что у меня нет его хендла.
Если я копирую файл созданный не мной (не моей программой), то я не могу его закрыть после копирования функцией FileClose() (нет хэндла), НО МОГУ ЕГО СТЕРЕТЬ.
Возможно, поэтому папки со скопированными и после стертыми файлами, не удаляются функцией FolderClean(). Возможно, потому что они небыли закрыты после копирования.
НО ЗАКРЫТЬ ИХ НЕЛЬЗЯ, ПОТОМУ ЧТО НЕТ ИХ ХЭНДЛА!
:)))
Вопросы к разработчикам:
1. как получить хэндл файла, который был создан в папке Files до загрузки скрипта?
2. Может ли проблема удаления папок с помощью функции FolderClean(), после стирания в них файлов, которые до этого были скопированы в другую папку и не закрыты после копирования (потому что нет хэндла), иметь вышеописанную причину?
Вопросы к разработчикам:
1. как получить хэндл файла, который был создан в папке Files до загрузки скрипта?
2. Может ли проблема удаления папок с помощью функции FolderClean(), после стирания в них файлов, которые до этого были скопированы в другую папку и не закрыты после копирования (потому что нет хэндла), иметь вышеописанную причину?
Это, как бы, азы ОС. Если какое-либо приложение открыло файл для записи, то ни этот файл, ни папку, его содержащую, удалить нельзя. Попробуйте открыть файл в Word, а потом средствами ОС удалить папку, в которой он находится. Что будет? Не получится, т. к. нет доступа.
Ну а хендл файла получить можно. Только какой прок от этого действия? Ведь если файл открыт другим приложением, то см. предыдущее высказывание. А хендл мы получим только тот, который валиден именно в нашем приложении.
Это, как бы, азы ОС. Если какое-либо приложение открыло файл для записи, то ни этот файл, ни папку, его содержащую, удалить нельзя. Попробуйте открыть файл в Word, а потом средствами ОС удалить папку, в которой он находится. Что будет? Не получится, т. к. нет доступа.
Ну а хендл файла получить можно. Только какой прок от этого действия? Ведь если файл открыт другим приложением, то см. предыдущее высказывание. А хендл мы получим только тот, который валиден именно в нашем приложении.
Файл открывается моим приложением (файловым навигатором) для перезаписи в другую папку.
После перезаписи мне нужно закрыть файл , но я не могу - (нет хэндла) и просто стираю файл.
Хендла нет, потому что файл был создан неизвестно когда и неизвестно кем.
При этом, файл существует внутри папки Files и может быть скопирован в другую папку и после стерт.
Но после копирования нельзя закрыть этот файл. Нет хэндла.
Вероятно, поэтому дальнейшее стирание папок FolderClean() со стертыми файлами, не срабатывает.
Вопрос: как получить хэндл этого файла в MQL-программу?
Похоже, с такой проблемой в сообществе еще не сталкивались... :)
Ладно, что нибудь придумаю.
Как всегда.))
Развенчиваем мифы.
Итак, данные по терминалу о операционной системе:
На момент тестов в папке [data folder]\MQL5\Files создана заранее папка "test" и в ней создан текстовой файл "source.txt" следующего содержания:
Итак, шаг 1: Копирование файла "source.txt" в другой файл средствами MQL5
Скрипт:
Шаг 2: очистка папки "test" средствами MQL5
Скрипт:
Шаг 3: Удаление папки "test" средствами MQL5
Какие сложности-то? Всё работает.
Какие сложности-то? Всё работает.
Спасибо за этот пример. Завтра с утра разберусь. Сейчас уже сил нет.)
Протестирую все и дам ответ.
Добавлено:
Тут Вы привели три разных скрипта.
У меня же одна программа и копирование, стирание файлов и папок происходит внутри одной функции в двух циклах.
Входим в первый цикл: Сначала копируются исходные файлы в другую папку, затем эти файлы-исходники стираются. Выходим из первого цикла.
Входим во второй цилк: Очищаем исходную папку с помощью FolderClean() и стираем исходную папку -FolderDelete().
Далее смотрим в файловый навигатор в метаэдитор и видим, что исходная папка стерлась частично. Подпапки в которых небыло файлов стерлись полностью, а те, в которых были - остались не стертыми, но пустыми.
Пытаемся удалить папки вручную - получаем:
Далее закрываем терминал и запускаем снова. Видим - некоторые подпапки исчезли сами, другие остались. Стираем их вручную без проблем. На этот раз.