Handy tools give great resultsThe ProblemThere are such tasks, in which the program makes record of data into text files from time to time. You can find many examples for this case. As rule, programmers use '?' command for such output. Of course, if program outputs line by line then usage of command is very easy. That's a horse of a different color, when you need make output of a single line, close file and a little later make output for another line and so on. Even worse, if you need output lines by turns in different files. The 'SET' commands are flashing before your eyes.
The SolutionAll becomes simpler if you have some class, which controls data stream to specific file and uses 'SET' commands itself according situation. Such class helps to create objects which will control output streams into files. Now you can forget about 'SET' commands and output data very easy.
Approximate properties and methodsProperties:- File name for the output channel
- Output mode: .T. = additive, .F. = overwrite
- Status of the channel: .T. = opened, .F. = closed
Methods:- Open channel for output
- Open channel, output text line and close channel
- Output text line and retain channel status
- Close channel
Approximate class definition
DEFINE CLASS textfile AS CUSTOM
NAME = "textfile"
*-- File name for output channel
filename = "output.txt"
*-- Path
PATH = ""
*-- Output mode: .T. - add records, .F. - create new file
ADDITIVE = .F.
*-- Channel status: .T.-opened, .F.-closed
STATUS = .F.
*-- Internal status
HIDDEN intstatus
*-- Console state before channel opening
HIDDEN CONSOL
*-- Output line openning and closing channel
PROCEDURE OUTPUT
LPARAMETERS lcString, llMode
LOCAL lnParam
lnParam=PARAMETER()
IF lnParam < 2
llMode=.T.
ENDIF
THIS.OpenOutput()
IF llMode
? lcString
ELSE
?? lcString
ENDIF
THIS.CloseOutput()
ENDPROC
*-- Open output channel
PROCEDURE OpenOutput
IF THIS.ADDITIVE
SET ALTERNATE TO (ALLT(THIS.PATH)+'\'+ALLT(THIS.filename)) ;
ADDITIVE
ELSE
SET ALTERNATE TO (ALLT(THIS.PATH)+'\'+ALLT(THIS.filename))
ENDIF
SET ALTERNATE ON
SET CONSOLE OFF
THIS.intstatus=.T.
ENDPROC
*-- Close output channel
PROCEDURE CloseOutput
SET ALTERNATE OFF
SET ALTERNATE TO
SET CONSOLE ON
THIS.intstatus=.F.
ENDPROC
PROCEDURE additive_assign
LPARAMETERS vNewVal
IF THIS.STATUS
THIS.CloseOutput()
ENDIF
THIS.ADDITIVE = m.vNewVal
ENDPROC
PROCEDURE filename_assign
LPARAMETERS vNewVal
IF THIS.STATUS
THIS.CloseOutput()
ENDIF
THIS.filename = m.vNewVal
ENDPROC
PROCEDURE path_assign
LPARAMETERS vNewVal
IF THIS.STATUS
THIS.CloseOutput()
ENDIF
THIS.PATH = m.vNewVal
ENDPROC
PROCEDURE status_assign
LPARAMETERS vNewVal
THIS.STATUS = THIS.intstatus
ENDPROC
*-- Output line does not changing channel state
PROCEDURE listoutput
LPARAMETERS lcString, llMode
LOCAL lnParam
lnParam=PARAMETER()
IF lnParam < 2
llMode=.T.
ENDIF
IF llMode
? lcString
ELSE
?? lcString
ENDIF
ENDPROC
PROCEDURE status_access
RETURN THIS.intstatus
ENDPROC
PROCEDURE RELEASE
RELEASE THIS
ENDPROC
PROCEDURE INIT
LPARAMETERS lcPath,lcFile,llAdd
IF TYPE('lcPath')='C'
THIS.PATH=lcPath
ENDIF
IF TYPE('lcFile')='C'
THIS.filename=lcFile
ENDIF
IF TYPE('llAdd')='L'
THIS.ADDITIVE=llAdd
ENDIF
ENDPROC
ENDDEFINE
The example of usageIt creates two output channels into different text files.
#DEFINE CR .T.
#DEFINE NOCR .F.
LOCAL loChannelOne, loChannelTwo
* create output channels
loChannelOne=CREATEOBJECT('TextFile',CURDIR(),'First.txt',.T.)
loChannelTwo=CREATEOBJECT('TextFile',CURDIR(),'Second.txt',.T.)
loChannelOne.ADDITIVE=.F.
loChannelOne.OUTPUT('The Memoirs of Sherlock Holmes. Silver Blaze.',NOCR)
loChannelOne.ADDITIVE=.T.
loChannelOne.OUTPUT('',CR)
loChannelTwo.ADDITIVE=.F.
loChannelTwo.OUTPUT('The Return of Sherlock Holmes.',NOCR)
loChannelTwo.ADDITIVE=.T.
loChannelTwo.OUTPUT('The Adventury of the Empty House',CR)
loChannelTwo.OUTPUT('',CR)
* ... some code lines
loChannelOne.OpenOutput()
loChannelOne.ListOutput('...And so it happened that an hour '+;
'or so later I found myself in the',CR)
loChannelOne.ListOutput('corner of a first-class carriage flying '+;
'along en route for Exeter, while',CR)
loChannelOne.ListOutput('Sherlock Holmes, with his sharp, eager '+;
'face framed in his ear-flapped...',CR)
loChannelOne.CloseOutput()
* ... some code lines
loChannelTwo.OUTPUT(' '+;
'... Even now, after this long interval, I',CR)
loChannelTwo.OUTPUT('find myself thrilling as I think of it, '+;
'and feeling once more that sudden',CR)
* ... some code lines
loChannelTwo.OUTPUT('flood of joy, amazement, and incredulity which '+;
'utterly submerged my',CR)
loChannelTwo.OUTPUT('mind...',CR)
RETURN
The resultThe Memoirs of Sherlock Holmes. Silver
Blaze.
...And so it happened that an hour or so later I found myself in the
corner of a first-class carriage flying along en route for Exeter, while
Sherlock Holmes, with his sharp, eager face framed in his ear-flapped...
File SECOND.TXT
The Return of Sherlock Holmes.
The Adventury of the Empty House
... Even now, after this long interval, I
find myself thrilling as I think of it, and feeling once more that sudden
flood of joy, amazement, and incredulity which utterly submerged my
Download codeYou can download this article and the program sample
here. The download is a zipfile. Its size is 17.953 bytes.