Watch how to download trading robots for free
Find us on Facebook!
Join our fan page
Interesting script?
So post a link to it -
let others appraise it
You liked the script? Try it in the MetaTrader 5 terminal
Libraries

CDir (MT5) - a class for getting directory contents - library for MetaTrader 5

Views:
3675
Rating:
(20)
Published:
2017.03.22 16:10
\MQL5\Include\WIN_API\
Dir_API.mqh (16.64 KB) view
\MQL5\Scripts\
Need a robot or indicator based on this code? Order it on Freelance Go to Freelance

Sometimes it is necessary to go beyond the sandbox and read the contents to check the existence of a file or directory in the file system. Also, you may need to find a file or directory attributes, file size, creation time, last access or writing. The following code shows an example of how to solve these problems:

A standard prologue and description of variables, as well as a link to the source code of the #include <WIN_API\Dir_API.mqh> include class is am implicit instruction to the compiler that it should look for the file in the folder \MQL5\Include\WIN_API. You are free to change this link, depending on your preference in the organization of work with include files in accordance with the documentation.

//+------------------------------------------------------------------+
//|                                            ExampleDirClass.mq4/5 |
//|                                        Copyright © 2017, Avatara |
//|                            https://www.mql5.com/en/users/avatara |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Avatara"            2017/02/12
#property link      "https://www.mql5.com/en/users/avatara"
#property description "-- Example Dir Class --------------"
#property strict
#include <WIN_API\Dir_API.mqh> 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   File_Def File;            // work structure
   CDir Dir; int total,i;     
   string path = TerminalInfoString(TERMINAL_COMMONDATA_PATH)+
               "\\..\\..\\Terminal";
//---    
  

As we can see, the string variable path contains the path to the folder, which is two levels above the standard location of the running terminal directory, and we (if the /portable option is not used) obtain the path to the directory that contains the user data of all the client terminals of that user.

A thoughtful reader would say that we do extra movements - that it could be enough to get one level up in order to go to the right directory. But what if we want to navigate to another folder, for example Crashes or Tester? This is a more instructive example.

Let us get back to the example code.

/---    
   total = Dir.Create(path);       // init dir
   Print (path," Total=",total-3); //Common,Help && Community not calc
    for (i = 0;i<total;i++)
    {
     string nameFile = Dir.GetNameFile(i);
     if(nameFile == "Common"||nameFile=="Help"||nameFile=="Community")
                                                              continue;
     File = Dir.GetStruct(i);
     Print (StringFormat ("%37s \t%8X\t  %5s\t",nameFile,
     File.FileAttributes,File.isDir?"-SubDir-":""),
     File.isDir?"            ":IntegerToString(File.FileLength,12),
     File.CreationTime,"     ",File.LastWriteTime,"     ",
     File.LastAccessTime);
    }
    Dir.Clear(); 
//---    

Having created a class instance, we receive the number of element (files and subdirectories) in the total variable. By organizing a loop we can print the list of directories of terminals (skipping shared directories). Let us illustrate access to the instance data by accessing a copy of the working data structure of the File class.

  path=TerminalInfoString(TERMINAL_PATH)+
              "\\..";
    Dir.Create(path,"\\M*");   // use filter "M*"       
    Print ("Alternative access:");
    total = Dir.Size(); 
    Print (Dir.Path," Total=",total);
    for (i = 0;i<total;i++)
    {
    Print  (StringFormat("%57s \t%8X \t %s \t",Dir.GetNameFile(i), 
                         Dir.GetStruct(i).FileAttributes,
                         Dir.isDir(i)?"--- SubDir ---": 
                         IntegerToString(Dir.GetFileLength(i),14)),
    "\t   Last modify: ",Dir.GetLastWriteTime(i));
    }
//---    
    Dir.Clear();  

The example of printing part of directory contents (using the selection of elements containing the M letter at the beginning) demonstrates other methods for working with the class members.

In the following part of code, we check the existence of the specific file and find out its length.

//---  Use to check the file
    path="C:";
    Print("------------ Use to check the file ---------------------");
    stringfilter="\\pagefile.sys";
    Dir.Create(path,filter);
    total=Dir.Size();
    PrintFormat("Find %d entry.",total);
    if(total>0)
      for(i =0;i<total;i++)Print("File search \"",path,filter,
        "\" is return:",Dir.isDir(i)?"--- SubDir ---  "+
        Dir.GetNameFile(i):Dir.GetNameFile(i)+
        IntegerToString(Dir.GetFileLength(i),14)+" byte. \t",
        StringFormat("Atributes=%X",Dir.GetAtributes(i)));
    else  Print("File ",path,filter," is absent.");
//---
    Dir.Clear();              

The test script ends with an example of using references to an instance of the class storing the directory contents element:

  //--- use pointer to access data

   path="C:\\Temp";

    //---------------------> pointer declarate     CDir_API *e;        Print("------ Pointer use example. --------");     total =Dir.Create(path);     PrintFormat("%s       Find %d entry.",path,total);     if(total>0)       for(i =0;i<total;i++)       {       e=Dir.GetPointers(i);       Print(StringFormat("%77s \t%8X\t  %5s\t ",e.Name_File,           e.FileDef.FileAttributes,e.FileDef.isDir?"-SubDir-":""),           e.FileDef.isDir?"         ":           IntegerToString(e.FileDef.FileLength,12),"   ",           e.FileDef.CreationTime,"     ",           e.FileDef.LastWriteTime,"     ",           e.FileDef.LastAccessTime);       }       else  Print("File ",path,filter," is absent."); //---     Dir.Clear();     Print("------------- The end. -----------------------"); } //+------------------------------------------------------------------+

I have no doubt that most readers will use this method for accessing class data in their work.

Additional information might be needed for understanding attributes:

FILE_ATTRIBUTE_ARCHIVE 32 (0x20) A file or directory that is an archive file or directory. Applications typically use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED 2048 (0x800) A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_DEVICE 64 (0x40) This value is reserved for system use.
FILE_ATTRIBUTE_DIRECTORY 16 (0x10) The handle that identifies a directory.
FILE_ATTRIBUTE_ENCRYPTED 16384 (0x4000) A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a directory, encryption is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_HIDDEN 2 (0x2) The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_INTEGRITY_STREAM 32768 (0x8000)

The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an ordinary directory listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination file will have integrity set if either the source file or destination directory have integrity set.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported until Windows Server 2012.

FILE_ATTRIBUTE_NORMAL 128 (0x80) A file that does not have other attributes set. This attribute is valid only when used alone.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 (0x2000) The file or directory is not to be indexed by the content indexing service.
FILE_ATTRIBUTE_NO_SCRUB_DATA 131072 (0x20000)

The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only provides inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported until Windows 8 and Windows Server 2012.

FILE_ATTRIBUTE_OFFLINE 4096 (0x1000) The data of a file is not available immediately. This attribute indicates that the file data is physically moved to offline storage. This attribute is used by Remote Storage, which is the hierarchical storage management software. Applications should not arbitrarily change this attribute.
FILE_ATTRIBUTE_READONLY 1 (0x1) A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on directories. For more information, see You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP, in Windows Vista or in Windows 7.
FILE_ATTRIBUTE_REPARSE_POINT 1024 (0x400) A file or directory that has an associated reparse point, or a file that is a symbolic link.
FILE_ATTRIBUTE_SPARSE_FILE 512 (0x200) A file that is a sparse file.
FILE_ATTRIBUTE_SYSTEM 4 (0x4) A file or directory that the operating system uses a part of, or uses exclusively.
FILE_ATTRIBUTE_TEMPORARY 256 (0x100) A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
FILE_ATTRIBUTE_VIRTUAL 65536 (0x10000) This value is reserved for system use.

I hope that this example and the class itself will be useful to you.

Enjoy it!

Translated from Russian by MetaQuotes Ltd.
Original code: https://www.mql5.com/ru/code/17623

HistoryPositionInfo HistoryPositionInfo

Returns position profit in points based on the trading history.

TypePendingOrderTriggered TypePendingOrderTriggered

An example of determining the moment when a pending order has triggered.

XRSXCandleKeltnerPluse XRSXCandleKeltnerPluse

The XRSXCandleKeltner indicator with the breakout indication option

XCCXCandleKeltnerPluse XCCXCandleKeltnerPluse

The XССXCandleKeltner indicator with the breakout indication option