plctwincatcodesysstructured-text

"File.Flush()" alternative in TwinCAT3


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.


Solution

  • I think that there is no such (known) way to do it. For that reason closing this thread.