Channel functions read in from or write to a file or a pipe. A pipe acts as an intermediary between one program’s output and another’s input. They allow other actions to be performed on the output rather than simply dumping it all at once. An example use would be like the pipe function in Linux with the ‘ls’ and ‘less’ functions to see the contents of a directory screen by screen. For example:
ls /usr/share/docs
ls /usr/share/docs | less
ls function will send the contents of docs to the pipe which then sends the data to the screen, depending on the function that has been specified after the pipe symbol. In this case, less will send the data to fill the screen and wait until the user prompts the function to send the next screen’s worth of data.
When you specify a file name, be careful with its case.
UNIX is case-sensitive, so it will treat files which names come in different cases as separate files.
These functions are used to achieve the channel functionality:
fgl_channel_open_file(name, filename, mode)
This function takes as its parameters the name of the file to be used within the 4GL code, the actual name of the file and the mode in which the file will be used (for example, read, write, etc.). With all these parameters provided, the function will then open the named file ready for use.
fgl_channel_open_pipe(name, command, mode)
This function requires the pipe name, the command to be performed on the data from the opened file and, again, the mode. It opens a pipe that is to be used to store the data from the file. This data can then be read from the pipe by other programs.
fgl_channel_set_delimiter(name, symbol)
The set_delimiter function takes as its parameters the file name (as created in the fgl_channel_open_file function), and the symbol that is used as a separator in the file. The function tells the program how the data in the file is split up.
fgl_channel_read(name, values)
This function is used to read the values from the named file or pipe into the ‘values’ parameter passed to it. If no delimiter has been set, then all the information in the file is read into the ‘values’ parameter. If, however, there is a delimiter defined then each item of information between these delimiters is entered into the ‘values’ parameter in order. In this instance, a loop is required to define different values to read to.
fgl_channel_write(name, values)
This is similar in functionality to the read function, except that instead of reading the values from file or pipe, those values are written to them.
This function is the same as the write function, except that the write function writes data with a new line, and the cat function writes without a new line.
fgl_channel_close(name)
This file simply closes the file that has been used in the previous functions. It takes as its parameter the name of the file.
mode |
description |
R |
Read mode. This mode opens a file or pipe in preparation for being read. When opened in read mode, a file can only be read using fgl_channel_read(). |
W |
Write mode. This mode opens a file or pipe in preparation for being written to. Write mode can be used only with fgl_channel_write() and fgl_channel_cat(). Any information in the named file or pipe will be overwritten. |
A |
Append mode. This mode opens a file or pipe in preparation for being written to. Append mode can be used only with fgl_channel_write() and fgl_channel_cat(). Append mode will keep the information in the named file or pipe and append the new values onto the end. |
1 (one) |
Raw mode. This mode, like write and append, opens a file or pipe for writing, except that when the data is written all control characters will be enacted and all delimiters will be ignored. Raw mode can be used only with fgl_channel_write() and fgl_channel_cat(). Raw mode will overwrite any data held in the named file or pipe. |
Here is an example of how to use channel methods:
MAIN
DEFINE buffer CHAR(128)
DEFINE input_pipe CHAR(64)
IF fgl_arch() = "nt" THEN
LET input_pipe = "dir"
ELSE
LET input_pipe = "ls -l"
END IF
CALL fgl_channel_open_file("stream", "myfile.txt", "w")
CALL fgl_channel_open_pipe("pipe", input_pipe, "r")
CALL fgl_channel_set_delimiter("pipe",",")
CALL fgl_channel_read("pipe", buffer)
RETURNING ret
CALL fgl_channel_write("stream", buffer)
CALL fgl_channel_close("stream")
DISPLAY "Data read from pipe: " AT 3, 4
DISPLAY buffer AT 4, 4
CALL fgl_winmessage("Dynamic 4gl Channel Functions","Press any key to exit this application", "info")
END MAIN
Opens the file contact.unl located on the working directory /unl/contact.unl and refers to the file in the 4GL as stream. r tells the program that the file is to be opened for reading:
fgl_channel_open_file("stream", "unl/contact.unl", "r")
This code will create a pipe called pipe and depending on the input_pipe variable will either pass all the data, or pass it element at a time
fgl_channel_open_pipe("pipe", input_pipe, "r")
The above will tell the program that in the file stream, values are separated by a pipe symbol:
fgl_channel_set_delimiter("stream", "|")
This will read the contents of stream into the variable buffer. If the values in stream are split up by a delimiter then only the first value will be put into buffer:
fgl_channel_read("stream", buffer)
In order to read all values in a file into buffer you would need to define buffer as an array and set up a loop to populate it:
DEFINE buffer ARRAY[20] OF CHAR[30]
LET i = 1
FOR i = 1 TO 20
fgl_channel_read("stream", buffer[i])
END FOR
fgl_channel_write() will write the contents of ‘buffer’ to ‘stream’. This is writing to the actual file that was opened earlier:
fgl_channel_write("stream", buffer)
fgl_channel_cat() will write the contents of ‘buffer’ to ‘stream’, except that data written to ‘stream’ will be written without new lines:
fgl_channel_cat("stream", buffer)
This function will close the file stream so that any further attempts to access it will fail:
fgl_channel_close("stream")
4J’s requires you to add the ‘USE CHANNEL’ construct at the start of your 4GL module if you want to use any of the channel functions. This construct is not needed with Lycia.
4J’s also requires the use of square brackets when using a variant amount of arguments in a function call – Lycia does not require these square brackets, and does not support them.