ответвлён от airat77786/MQL5Book
203 строки
7,1 КиБ
MQL5
203 строки
7,1 КиБ
MQL5
//+------------------------------------------------------------------+
| |||
//| FileCursor.mq5 |
| |||
//| Copyright 2021, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#include "..\..\Include\PRTF.mqh"
| |||
#include "..\..\Include\StructPrint.mqh"
| |||
| |||
const string fileraw = "MQL5Book/cursor.raw";
| |||
const string filetxt = "MQL5Book/cursor.csv";
| |||
const string file100 = "MQL5Book/k100.raw";
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Produce a string with file current position, and EOF, EOL flags |
| |||
//+------------------------------------------------------------------+
| |||
string FileState(int handle)
| |||
{
| |||
return StringFormat("P:%I64d, F:%s, L:%s",
| |||
FileTell(handle),
| |||
(string)FileIsEnding(handle),
| |||
(string)FileIsLineEnding(handle));
| |||
}
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| Script program start function |
| |||
//+------------------------------------------------------------------+
| |||
void OnStart()
| |||
{
| |||
int handle;
| |||
Print("\n * Phase I. Binary file");
| |||
// create new file or open existing one for appending data
| |||
// the file will grow a bit on every start
| |||
handle = PRTF(FileOpen(fileraw, FILE_BIN | FILE_WRITE | FILE_READ));
| |||
Print(FileState(handle));
| |||
// moving file cursor to the end ensures that we will append data,
| |||
// not overwrite it from very beginning
| |||
PRTF(FileSeek(handle, 0, SEEK_END));
| |||
Print(FileState(handle));
| |||
| |||
// if file isn't empty, we can read existing data
| |||
// at specific position (relative or absolute)
| |||
// here we try to move for 1 int value back
| |||
if(PRTF(FileSeek(handle, -1 * sizeof(int), SEEK_CUR)))
| |||
{
| |||
Print(FileState(handle));
| |||
// read day_of_year from MqlDateStruct previously stored in the file
| |||
PRTF(FileReadInteger(handle));
| |||
}
| |||
| |||
// write current timestamp (datetime is 8 bytes long)
| |||
datetime now = TimeLocal();
| |||
PRTF(FileWriteLong(handle, now));
| |||
Print(FileState(handle));
| |||
// try to step back for 4 bytes and read (this will fail)
| |||
PRTF(FileSeek(handle, -4, SEEK_CUR));
| |||
long x = PRTF(FileReadLong(handle));
| |||
Print(FileState(handle));
| |||
// if step back for 8 bytes, another read will succeed
| |||
PRTF(FileSeek(handle, -8, SEEK_CUR));
| |||
Print(FileState(handle));
| |||
x = PRTF(FileReadLong(handle));
| |||
PRTF((now == x));
| |||
| |||
// now write MqlDateTime structure (note how position will change)
| |||
MqlDateTime mdt;
| |||
TimeToStruct(now, mdt);
| |||
StructPrint(mdt);
| |||
PRTF(FileWriteStruct(handle, mdt)); // 32 = sizeof(MqlDateTime)
| |||
Print(FileState(handle));
| |||
FileClose(handle);
| |||
| |||
Print(" * Phase II. Text file");
| |||
srand(GetTickCount());
| |||
// create new or open existing text file for writing (re-writing) it
| |||
// from very beginning with CSV-data (Unicode) and then reading
| |||
handle = PRTF(FileOpen(filetxt, FILE_CSV | FILE_WRITE | FILE_READ, ','));
| |||
// '\n' will be replaced with '\r\n' automatically,
| |||
// note that the last element doesn't have a '\n'
| |||
string content = StringFormat(
| |||
"%02d,abc\n%02d,def\n%02d,ghi",
| |||
rand() % 100, rand() % 100, rand() % 100);
| |||
PRTF(FileWriteString(handle, content));
| |||
PRTF(FileSeek(handle, 0, SEEK_SET));
| |||
Print(FileState(handle));
| |||
// let's count lines by FileIsLineEnding flag
| |||
int lineCount = 0;
| |||
while(!FileIsEnding(handle))
| |||
{
| |||
PRTF(FileReadString(handle));
| |||
Print(FileState(handle));
| |||
// FileIsLineEnding is also true if FileIsEnding is true and
| |||
// there is no trailing '\n'
| |||
if(FileIsLineEnding(handle)) lineCount++;
| |||
}
| |||
FileClose(handle);
| |||
PRTF(lineCount);
| |||
| |||
Print(" * Phase III. Allocate large file");
| |||
// create new or reset existing file and expand it to 1Mbyte
| |||
handle = PRTF(FileOpen(file100, FILE_BIN | FILE_WRITE));
| |||
PRTF(FileSeek(handle, 1000000, SEEK_END));
| |||
// we need to write something at current position
| |||
PRTF(FileWriteInteger(handle, 0xFF, 1));
| |||
PRTF(FileTell(handle));
| |||
FileClose(handle);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
/*
| |||
Example outputs
| |||
+-----------------------+
| |||
First run:
| |||
| |||
* Phase I. Binary file
| |||
FileOpen(fileraw,FILE_BIN|FILE_WRITE|FILE_READ)=1 / ok
| |||
P:0, F:true, L:false
| |||
FileSeek(handle,0,SEEK_END)=true / ok
| |||
P:0, F:true, L:false
| |||
FileSeek(handle,-1*sizeof(int),SEEK_CUR)=false / INVALID_PARAMETER(4003)
| |||
FileWriteLong(handle,now)=8 / ok
| |||
P:8, F:true, L:false
| |||
FileSeek(handle,-4,SEEK_CUR)=true / ok
| |||
FileReadLong(handle)=0 / FILE_READERROR(5015)
| |||
P:8, F:true, L:false
| |||
FileSeek(handle,-8,SEEK_CUR)=true / ok
| |||
P:0, F:false, L:false
| |||
FileReadLong(handle)=1629683392 / ok
| |||
(now==x)=true / ok
| |||
2021 8 23 1 49 52 1 234
| |||
FileWriteStruct(handle,mdt)=32 / ok
| |||
P:40, F:true, L:false
| |||
* Phase II. Text file
| |||
FileOpen(filetxt,FILE_CSV|FILE_WRITE|FILE_READ,',')=1 / ok
| |||
FileWriteString(handle,content)=44 / ok
| |||
FileSeek(handle,0,SEEK_SET)=true / ok
| |||
P:0, F:false, L:false
| |||
FileReadString(handle)=08 / ok
| |||
P:8, F:false, L:false
| |||
FileReadString(handle)=abc / ok
| |||
P:18, F:false, L:true
| |||
FileReadString(handle)=37 / ok
| |||
P:24, F:false, L:false
| |||
FileReadString(handle)=def / ok
| |||
P:34, F:false, L:true
| |||
FileReadString(handle)=96 / ok
| |||
P:40, F:false, L:false
| |||
FileReadString(handle)=ghi / ok
| |||
P:46, F:true, L:true
| |||
lineCount=3 / ok
| |||
* Phase III. Allocate large file
| |||
FileOpen(file100,FILE_BIN|FILE_WRITE)=1 / ok
| |||
FileSeek(handle,1000000,SEEK_END)=true / ok
| |||
FileWriteInteger(handle,0xFF,1)=1 / ok
| |||
FileTell(handle)=1000001 / ok
| |||
| |||
+-----------------------+
| |||
Second run:
| |||
| |||
* Phase I. Binary file
| |||
FileOpen(fileraw,FILE_BIN|FILE_WRITE|FILE_READ)=1 / ok
| |||
P:0, F:false, L:false
| |||
FileSeek(handle,0,SEEK_END)=true / ok
| |||
P:40, F:true, L:false
| |||
FileSeek(handle,-1*sizeof(int),SEEK_CUR)=true / ok
| |||
P:36, F:false, L:false
| |||
FileReadInteger(handle)=234 / ok
| |||
FileWriteLong(handle,now)=8 / ok
| |||
P:48, F:true, L:false
| |||
FileSeek(handle,-4,SEEK_CUR)=true / ok
| |||
FileReadLong(handle)=0 / FILE_READERROR(5015)
| |||
P:48, F:true, L:false
| |||
FileSeek(handle,-8,SEEK_CUR)=true / ok
| |||
P:40, F:false, L:false
| |||
FileReadLong(handle)=1629683397 / ok
| |||
(now==x)=true / ok
| |||
2021 8 23 1 49 57 1 234
| |||
FileWriteStruct(handle,mdt)=32 / ok
| |||
P:80, F:true, L:false
| |||
* Phase II. Text file
| |||
FileOpen(filetxt,FILE_CSV|FILE_WRITE|FILE_READ,',')=1 / ok
| |||
FileWriteString(handle,content)=44 / ok
| |||
FileSeek(handle,0,SEEK_SET)=true / ok
| |||
P:0, F:false, L:false
| |||
FileReadString(handle)=34 / ok
| |||
P:8, F:false, L:false
| |||
FileReadString(handle)=abc / ok
| |||
P:18, F:false, L:true
| |||
FileReadString(handle)=20 / ok
| |||
P:24, F:false, L:false
| |||
FileReadString(handle)=def / ok
| |||
P:34, F:false, L:true
| |||
FileReadString(handle)=02 / ok
| |||
P:40, F:false, L:false
| |||
FileReadString(handle)=ghi / ok
| |||
P:46, F:true, L:true
| |||
lineCount=3 / ok
| |||
* Phase III. Allocate large file
| |||
FileOpen(file100,FILE_BIN|FILE_WRITE)=1 / ok
| |||
FileSeek(handle,1000000,SEEK_END)=true / ok
| |||
FileWriteInteger(handle,0xFF,1)=1 / ok
| |||
FileTell(handle)=1000001 / ok
| |||
| |||
*/
| |||
//+------------------------------------------------------------------+
|