I was wondering if there is there a way to flush
the data that is to be written to a file other than closing the file in TwinCAT3?
Usually there is a .Flush()
method that would move all the data from the internal buffers to the files, but in TwinCAT there is no such method and from what I saw, the only way for the content to appear is to close the file. In CodeSys there is such a function, but since that would only work for local files I was wondering if there is another way to do it in TwinCAT3. Currently, my flush
method closes the file and re-opens it without the outside world knowing that the files was closed, but it feels a bit "hacky". Another thing this would be a problem for is, if the file was opened in FOPEN_MODEWRITE OR FOPEN_MODEPLUS
I would also need to re-open it in a mode that does not overwrite the content, which in turn changes the access mode from the primary mode provided when opened.
I never really thought about this, but making tests for a library, I would validate my "write" functions by reading the file and assert the content, but until the files is re-opened the reading would return empty content:
METHOD Test06_WriteLine_FileOpened_Append_ExpectNoError_ExpectOldAndNewContent
VAR_INST
_fileHandler: FB_FileHandler;
content : Tc2_System.T_MaxString;
state : INT;
WRITE_TEST_CONTENT_OVERWRITE_EMPTY_FILE : Tc2_System.T_MaxString := 'Some random text...';
WRITE_TEST_CONTENT_APPEND : Tc2_System.T_MaxString := 'Some more text....';
WRITE_TEST_CONTENT_OVERWRITE_EXTISTING : Tc2_System.T_MaxString := 'Only this text should exist...';
EXPECTED_RESULT_APPEND : Tc2_System.T_MaxString :=
Tc2_Standard.CONCAT(WRITE_TEST_CONTENT_OVERWRITE_EMPTY_FILE, WRITE_TEST_CONTENT_APPEND);
END_VAR
IF TcUnit.TEST_ORDERED('Test06_WriteLine_FileOpened_Append_ExpectNoError_ExpectOldAndNewContent') THEN
CASE state OF
0:
IF _fileHandler.Open(FILE_PATH, NEW_TEXT_FILE_NAME, E_FileOpenMode.TEXT_READ_WRITE_APPEND, NET_ID) THEN
state := state + 1;
END_IF
1:
IF _fileHandler.WriteLine(WRITE_TEST_CONTENT_APPEND) THEN
AssertFalse(_filehandler.Error,
Tc2_Standard.CONCAT('Error writing content: ',_fileHandler.AdsError.Message));
state := state + 1;
END_IF
2:
// Flush the content so that it appears in the file to be read with .Read()
IF _fileHandler.Flush() THEN
state := state + 1;
END_IF
3:
IF _fileHandler.Read(content) THEN
AssertFalse(_filehandler.Error,
Tc2_Standard.CONCAT('Error writing content: ',_fileHandler.AdsError.Message));
AssertEquals_STRING(EXPECTED_RESULT_APPEND, content,
'Written content differs.');
state := state + 1;
END_IF
4:
IF _fileHandler.Close() THEN
TcUnit.TEST_FINISHED();
END_IF
END_CASE
END_IF
I am sure there is a way, but it seems to be hidden in the FB_FileClose
I think.
I am sure passing the handle
from TC3 to CodeSys is not a valid thing to do, correct? I started wondering about this as I was writing.
I think that there is no such (known) way to do it. For that reason closing this thread.