Read and write files example

From DataFlex Wiki
Revision as of 16:04, 22 February 2021 by Mikepeat (talk | contribs) (Added link to blog)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Listing for the "Read and write files example" view:

(From the Unicorn blog post: Working with binary files in DataFlex)

Use Windows.pkg
Use DFClient.pkg
Use cCharTranslate.pkg
Use seq_chnl.pkg
Use File_dlg.pkg
Use cTextEdit.pkg

Deferred_View Activate_oReadWriteFiles for ;
Object oReadWriteFiles is a dbView

    Set Border_Style to Border_Thick
    Set Size to 155 533
    Set Location to 1 2
    Set Label to "Read and write files example"
    
    Property String  psMyFile
    Property Integer piOldSize
    
    // This is what provides the means to encode/decode base64:
    Object oTrans is a cCharTranslate
    End_Object

    // These two functions - ReadMyFile and WriteMyFile - are where the work
    // gets done.
    
    Function ReadMyFile String sFilePathName Returns Boolean
        Integer iChn
        UChar[] ucaData
        String  sFile
        Boolean bExists
        
        // For timing test
        DateTime dtStart dtEnd
        Timespan tsDiff
        
        // Check file exists
        File_Exist sFilePathName bExists
        
        If not bExists Begin
            Send UserError ('File "' + sFilePathName + '" was not found') "File not found"
            Function_Return False
        End
        
        Get Seq_New_Channel to iChn
        Direct_Input channel iChn ("Binary:" + sFilePathName)
        
        If not (SeqEof) Begin
            
            // Timing test
            Move (CurrentDateTime()) to dtStart
            
            Read_Block channel iChn ucaData -1
            Move (Base64EncodeUCharArray(oTrans(Self), ucaData)) to ucaData
            Set_Argument_Size (SizeOfArray(ucaData) + 1)
            Move (UCharArrayToString(ucaData)) to sFile

            // Timeing test
            Move (CurrentDateTime()) to dtEnd
            Move (dtEnd - dtStart) to tsDiff
//            Showln ("Read: " * String(SpanTotalMilliseconds(tsDiff)) + "ms")
        End
        Else Begin
            Send UserError ('File "' + sFilePathName + '" does not exist or was empty') "File Error"
            Function_Return False
        End
        
        Close_Output channel iChn
        Send Seq_Release_Channel iChn
        Set psMyFile to sFile
        
        Function_Return True
    End_Function

    Function WriteMyFile String sFilePathName Returns Boolean
        Integer iChn iPos iResp
        UChar[] ucaFile
        String  sPath sDir sFile
        Boolean bExists
        
        // For timing test
        DateTime dtStart dtEnd
        Timespan tsDiff

        Move (RightPos("\", sFilePathName)) to iPos
        
        If not iPos Begin
            Send UserError "Could not find folder" "Folder Error"
            Function_Return False
        End
        
        Move (Left(sFilePathName, (iPos - 1))) to sPath
        
        File_Exist sPath bExists
        
        If not bExists Begin
            Send UserError ('Folder "' + sPath + '" does not exist') "Folder Error"
            Function_Return False
        End
        
        Move (Right(sFilePathName, (Length(sFilePathName) - iPos))) to sFile
        File_Exist sFilePathName bExists
        
        If bExists Begin
            Move (Right(sFilePathName, (Length(sFilePathName) - iPos))) to sFile
            Get YesNo_Box ;
                ('The file "' + sFile + '" already exists in folder' * sPath + '. Do you wish to overwrite it?') ;
                "Overwrite file?" to iResp
                
            If (iResp = MBR_NO) ;
                Function_Return False
        End
                
        Move (StringToUCharArray(psMyFile(Self))) to ucaFile
        Move (Base64DecodeUCharArray(oTrans(Self), ucaFile)) to ucaFile
        
        // If some other program has the file open (and in some cases, has even
        // previously had the file open), writing to it may fail, so we catch
        // that error in order to deal with it ourselves and return "failure"
        // rather "success", resetting it after the write operation, and use the
        // ERR global indicator to detect the problem.
        Send Ignore_Error of Error_Object_Id 32
        Move False to Err
        
        // Timing test
        Move (CurrentDateTime()) to dtStart

        Get Seq_New_Channel to iChn
        Direct_Output channel iChn ("Binary:" + sFilePathName)
        Write channel iChn ucaFile
        Close_Output channel iChn
        Send Seq_Release_Channel iChn
        Send Trap_Error of Error_Object_Id 32
        
        // Timing test
        Move (CurrentDateTime()) to dtEnd
        Move (dtEnd - dtStart) to tsDiff
//        Showln ("Write:" * String(SpanTotalMilliseconds(tsDiff)) + "ms")
        
        If (Err) Begin
            Send UserError ('There was an error writing to file "' + sFilePathName + '"') "Write Error"
            Function_Return False
        End
        
        Function_Return True
    End_Function
    
    // The user interface...
    
    Object oOpenDialog is a OpenDialog
    End_Object

    Object oSaveAsDialog is a SaveAsDialog
    End_Object
    
    Object oRead is a Form
        Set Size to 13 390
        Set Location to 3 86
        Set Label to "File path-name to read:"
        Set psToolTip to "File path-name to read"
        Set Label_Justification_Mode to JMode_Right
        Set Label_Col_Offset to 2
        Set Value to ;
            "C:\Program Files (x86)\DataFlex 19.1\Documentation\Installation_and_Environment_Guide.pdf"
        Set Prompt_Button_Mode to PB_PromptOn
        Set peAnchors to anTopLeftRight
        
        Procedure Prompt
            Boolean bOK
            String  sFile
            
            Get Show_Dialog of oOpenDialog      to bOK
            
            If bOK Begin
                Get File_Name of oOpenDialog    to sFile
                Set Value                       to sFile
            End
            
        End_Procedure
        
    End_Object

    Object oDoRead is a Button
        Set Size to 14 47
        Set Location to 3 480
        Set Label to "Read file"
        Set peAnchors to anTopRight
    
        Procedure OnClick
            String  sFile
            Boolean bOK
            Integer iOldSize iNewSize
            
            Get_Argument_Size                   to iOldSize
            Set piOldSize                       to iOldSize
            Set Value of oBase64File            to ""
            
            Get Value of oRead   to sFile
            Get ReadMyFile sFile to bOK
            
            Set Enabled_State of oWrite         to bOK
            Set Enabled_State of oDoWrite       to bOK
            
            If bOK Begin
                Get_Argument_Size               to iNewSize
                Set piMaxChars of oBase64File   to iNewSize
                Set Value of oBase64File to (If(bOK, psMyFile(Self), ""))
            End
            Else Begin
                Set_Argument_Size (piOldSize(Self))
                Set piMaxChars of oBase64File   to (piOldSize(Self))
            End
            
            Send Info_Box ('File "' + sFile + ;
                If(bOK, '" was read successfully', '" could not be read')) ;
                (If(bOK, "Success", "Failure"))            
        End_Procedure
    
    End_Object

    Object oWrite is a Form
        Set Size to 13 390
        Set Location to 20 86
        Set Label to "File path-name to write:"
        Set Label_Justification_Mode to JMode_Right
        Set Label_Col_Offset to 2
        Set Enabled_State to False
        Set Value to "C:\Temp\MyTestFile.pdf"
        Set Prompt_Button_Mode to PB_PromptOn
        Set peAnchors to anTopLeftRight
                
        Procedure Prompt
            Boolean bOK
            String  sFile
            
            Get Show_Dialog of oSaveAsDialog    to bOK
            
            If bOK Begin
                Get File_Name of oSaveAsDialog  to sFile
                Set Value                       to sFile
            End
            
        End_Procedure
        
    End_Object

    Object oDoWrite is a Button
        Set Size to 14 47
        Set Location to 20 480
        Set Label to "Write file"
        Set Enabled_State to False
        Set peAnchors to anTopRight
    
        Procedure OnClick
            String  sFile
            Boolean bOK
            
            Get Value of oWrite                 to sFile
            
            If (sFile = "") Begin
                Send Info_Box "You must enter a file path and name to write to" "Enter Filepath"
                Procedure_Return
            End
            
            Get WriteMyFile sFile               to bOK
            
            Set Enabled_State of oWrite         to (not(bOK))
            Set Enabled_State of oDoWrite       to (not(bOK))
            
            If bOK Begin
                Set Value of oBase64File        to ""
                Set psMyFile                    to ""
                Set_Argument_Size (piOldSize(Self))
                Set piMaxChars of oBase64File   to (piOldSize(Self))
            End
            
            Send Info_Box ('File "' + sFile + ;
                     If(bOK, '" was written successfully', '" was not written')) ;
                    (If(bOK, "Success", "Failure"))
        End_Procedure
    
    End_Object

    Object oBase64File is a cTextEdit
        Set Size to 101 520
        Set Location to 46 6
        Set Read_Only_State to True
        Set Label to "Base64 Encoded File (will be gibberish... unless vous parlez base64!):"
        Set peAnchors to anAll
    End_Object

CD_End_Object