|
Filing
You are welcomed to use our site for your web search.
See the fine products advertised at the bottom of each page too.
DEMONSTRATIVE EXAMPLES
======================
EXAMPLES ON FILING
===================
For many years, filing has been easy and simple. There has been
two types of files:
(1) Sequencial Access Files (SAF)'s: In this type records are read sequencially,
so you can't read a record unless you read all the records located before it in the file.
(2) Random Access Files (RAF)'s: In which you can read a record located
at any place in the file instantly by supplying its record number.
Sequencial Access Files have been good for short files, like "letters"
and "memos". Random Access Files have been good for longer files like "Inventories" and "Personell" files.
Things have become more complicated recently, SAF's have become not
as easy to create and RAF's have been replaced with databases. This is fine for a large business but not as good for
someone who likes to use his programming ability to put his personal data into a file made to his/her specs.
Personal C# is specialized in simplification, so we have developed a
software which returns you to the good old days. Both file types are now available and their creation and use have become
even simpler.
SELECTING THE FILE KEYNAME: If you have already looked at the
examples on "Controls", you know what keynames mean. You know that the keyname "bt0" represents a button since the first
two characters "bt" are for a Button type. You also know that you should supply (cs="bt0") when you call method cm() at
any mode to perform an operation on that button.
In Filing, we have only two types of files SAF and RAF. The two char's
representing each of them are "sf" and "rf" respectively. So, you can name your first SAF "sf0" and you should supply
(fs="sf0") when you call method fm() at any mode to perform an operation on that file.
Filing keynames can also be either 3 or 4 characters long, just like
Control's keynames. So "sf0", "rf08"and "sf89" are all legal keynames. you cannot use numbers which start with 9 since
they are reserved for internal use. So "sf9" and "rf90" are illegal keynames.
FILING OBJECTS:
========================================================================================= EXAMPLE
1: Make a short text file using Notepad and save it under the name "test.txt". We are going to Read the file and display
its contents on the "Text Screen".
We are going to use 2 file read modes "read all" to read it all at once
and "read line" to read it line by line. ========================================================================================= public
class a:pcs { public override void init() { tia=toa="t";
// Select "text screen" display bli=1;
// Start execution at block 1 base.init();
// Initialize PC# classes } public override void run() { if (blp==1) {
// Starting block os="Using Read All mode: ";tm(); // First mode
fls="test.txt";fs="sf0";fm("or"); // Open for read, use keyname "sf0" fm("ra");tm();
// Read it all & display it fm("c");
// Close file
os="\nUsing Read Line mode: ";tm();//
Second mode. fls="test.txt";fs="sf0";fm("or"); // Open for read, use keyname "sf0"
dnb=false;
// Initialize End Of File flag while (!dnb) {
fm("rl");if (!dnb) tm(); // Keep reading lines until EOF
} fm("c");
// Close file } } } ========================================================================================= HOW
TO WRITE, COMPILE AND RUN THE PROGRAM? See Example 1 of the "General Examples". ========================================================================================= TUTORIAL:
Reading a SAF is very easy. At first, we select a keyname for it. Since it is a SAF the keyname must start with "sf". We
called it "sf0" since it is the first file.
The second step is to open the file. There are 3 modes to open a SAF
at:
or Open for read, which is the mode we wanted. ow Open
for write oa Open for append
There are also 3 modes for reading a SAF:
ra Read the entire file and assign its text content to (os) rl
Read one line rb Read one byte
The boolean var (dnb) which is the "done" flag is a general flag used
to indicate whether something we are working on has been completed or not. In filing, dnb changes its state to true
when an end of file (EOF) has been encountered.
So, before we start reading, we make sure that it is (false) then we
keep reading until it changes to (true)
You may have noticed that we has specified the file keyname only when
we opened it, we didn't specify it when we read the file text or when we closed it. Why?. The answer is that method
fm() does not reset (fs) at its end like it resets the GUV's. So we have been able to get away with doing that. However,
this is not a good practice. If we have been working with more than one file, we should have specified the file keyname
at each operation. =========================================================================================

Example 1: Reading SAF using two modes, read all and read line.
EXAMPLE 2: This time, we are not going to write a full class for each
example, we are going to add one block for each new example to the class of example 1. so, this example will be in block
2. After adding block two to the last class, change the startup block request statement in method init() to (bli=2;)
In this example, we are going to erase "test.txt" file contents, open
it in "write" mode, write the line "Text Line Number 1" into it, close it then open it again in "append" mode, write
the line "Text Line Number 2" into it, close it then open it in "read" mode, read and display all its data. =========================================================================================
if (blp==2) { // -----------------------
CREATING THE FILE AND WRITING DATA --------------------- ks="f";fls="test.txt";fm("D");
// delete file. fls="test.txt";fs="sf0";fm("ow"); // open for write
os="Text Line Number 1";fm("wl"); // write line fm("c");
// close os="Data written to file";tm(); // Inform user
fls="test.txt";fs="sf0";fm("oa"); // open for append os="Text Line Number 2";fm("wl"); //
write line fm("c");
// close os="Data appended to fle";tm();// Inform user // ---------------------------------
READING DATA BACK ---------------------------- os="Reading data back:";tm();
fls="test.txt";fs="sf0";fm("or"); // Open for read fm("ra");tm();
// Read all file & display on text screen fm("c");
// close } =========================================================================================

Example 2: Shows how to write text to a file, append to it then read
all its contents.
EXAMPLE 3: Now, we need to add a new block to show how to obtain current
directory name, how to check if a file or dir exists,
how to create files and dir's and delete them, how to
get a list of all files & sub folders in a folder and how to
copy one file to another.
So. add block 3 to your program and change "Startup block request" statement
in method init() to (bli=3;) =========================================================================================
if (blp==3) { //-------------- OBTAINING CURRENT DIRECTORY AND CHECKING ATTRIBUTES --------------
fm(".");os="Current Directory: "+os;tm(); // Get currnt dir name, dsplay it.
fls="x.txt";fm("A");os="Code: "+os;tm(); // Get attributes & dsplys returned
fls="xxxx.cs";fm("A");os="Code: "+os;tm(); // code for 3 items. Should display "f"
fls="c:\\health";fm("A");os="Code: "+os;tm();// if file, "d" if directory, " " if
// non-existing.
//------------------ CREATING AND DELETING
FILES AND DIRECTORIES ------------------ ks="f";fls="testFl";fm("M");os="File created";tm();//
Create file, inform user. ks="f";fls="testFl";fm("D");os="File deleted";tm();// Delete same
file ks="d";fls="testDir";fm("M");os="Dir created";tm();// Create dir, inform user
ks="d";fls="testDir";fm("D");os="Dir deleted";tm();// Delete same dir
//----------- DISPLAYING ALL SUB-FOLDERS
AND FILE CONTENTS OF A FOLDER ----------- os="Reading file list:";tm();
ks="d";fls="c:\\cs";fm("L");
// Get all sub-dir's in OS[] om("fa");
// Convert OS[] to (os) ns=os;
// save (os) temporarely in (ns) ks="f";fls="c:\\cs";fm("L");
// Get all files in OS[] om("fa");
// Convert to (os) os=ns+os;tm();
// Add the 2 lists & display
//-------------------------- COPYING
FILES AND DIRECTORIES ------------------------ fls="c:\\JS\\temp.txt";os="newfile.txt";fm("C");//
copy extrnl fle to local fle os="File copied";tm();
// Inform user with dialog box ks="f";fls="newfile.txt";fm("D");
// Delete new file os="File deleted";tm();
// Inform user } ========================================================================================= TUTORIAL:
So far everything seems to be too easy to require additional explanation. Let us now get into the more important filing
type "The Random Access Filing".
RANDOM ACCESS FILES
===================
The difference between a SAF and RAF is in the record length.
In a text SAF, the strings you write into the file are not of equal lengthes, the only way we can seperate them from
each other is by adding a "new line" code at the end of each string. The new line code which we use is made of two special
characters, a carriage return character (code 13 in decimal form) followed with a line feed character (code 10, decimal)
In a RAF, you specify a record length when you open the file. The record length you choose should be at least equal
to the length of the longest string which you may like to add to the file. When you call method fm() with a string which
you want to write into the file, the method adds at the end of your string as many null characters as it takes to make
its length equal to the record length.
Since all records of a RAF are of same length, it is possible to know where the start and end of any record in the
file are, so we can retrieve the record instantly without having to read all the records which preceed it into the file.
We have two types of RAF's:
(1) Manually read RAF's. (2) Automatically read RAF's
In the first type, you need to supply the record length each time you open the file and you are on your own concerning
how you place your data into your record.
In the second type, at the time you create the file, you supply the filing method fm() with the record length and
data concerning the fields each record should contain. After the file is created, the method writes a header record at
the beginning of the file which contains all data necessary to read its records and to retrieve the field data within
them. So anytime you open the file for read or write thereafter, you don't have to tell the method how to read it or where
fields are located.
Next example will be on the first type of Random Access Files. =========================================================================================

Example 3: Shows how to create, delete, copy and check attributes of
files.
Also shows how to get current directory and to list the contents of
a directory.
EXAMPLE 4: We are going to add a new block to last program to show
how to write 2 lines into a no header Random Access File (RAF)
then read them back. We need to erase file contents before
writing into it. =========================================================================================
// ----------------------- CREATING THE FILE AND WRITING DATA --------------------- if (blp==4) {
fls="test.raf";fm("A"); // check file attributes
if(os != " ") {ks="f";fm("D");} // If exists, delete it fls="test.raf";fs="rf0";rcl=24;ib=true;fm("o");
// open RAF, record len=24,no header rcs="Line number one.";rci=0;fm("w");// Write first
record rcs="Line #2.";rci=1;fm("w"); // Write
second record fm("c");
// Close the file. // --------------------------------- READING DATA BACK ----------------------------
fls="test.raf";fs="rf0";rcl=24;ib=true;fm("o");
// open RAF again n=0;dnb=false;
// Initialize record number counter, eof flag. while (!dnb) {
// Start record reading loop. rci=n;fm("r");
// Read one record. os=rcs;om("c");
// Clean record (remove trailing null chars) tm();
// Then display record. n++;
// increment record number. } fm("c");
// Close the file. } ========================================================================================= TUTORIAL:
As you can see, the records supplied to method fm() to be written into the file have not been equal in length, but the
method made them equal by adding enough null char's to each of them to make the length of each one of them equal to the
record length.
When the records were read back, they came with the null char's attached
to them, so we had to remove the null chars before displaying them.
HOW TO CREATE AN AUTOMATICALLY READ RAF:
The first step is to create the header. To do so, you open the file
as a no header file, write the header then close it.
To create the header, you need to determine the fields necessary.
To simplify things, we use only two types of fields, string and numeric fields. A numeric field always occupies 5 bytes.
The number of bytes a string field requires is the number of characters of the logest string to be writen into it.
Setting the record length:
To calculate the record length, add the bytes which all fields require
together, then add some more spare bytes for future expansion.
Setting the data type:
The double type var (od) is used to indicate the data type for a field.
Here is how to detrmine data types:
(1) For a string field, od=No. of characters occupied by the field. (2)
For a numeric field, (od) is always in the range (0.0 to 0.9) The number to the right of the decimal
point is the number of decimal digits you like the field to have. If the field will be used to represent
money, you would be expected to choose (od=0.2) so your numbers come formatted as Dollars and Cents.
If the field is going to be used to store an integer, you would use (od=0.0) since there will be no
decimal digits.
So, (od) can tell exactly what a field contains. If it was an integer
like (35), we know that the field is a string, upto 35 characters long. If it was zero (0.0), the field is an integer
and if it was a fraction like (0.4) we know that the field is a number of 4 decimal digits (in this case)
How the header data is supplied:
Practically, we don't supply field data one at a time, we supply them
all at once. We supply the array OS[] containing all field names, and array OD[] containing all field types in the same
order at which we like the fields to be placed into the record. =========================================================================================

Example 4: Shows how to write two lines into a Random Access file (RAF)
and read them back.
EXAMPLE 5: Let us add a new block to last program to show how
to make a RAF with a header containing all information
necessary for reading it. We are also going to Enter
two records of data into the file then read them back and display
them on the screen. =========================================================================================
if (blp==5) { // ------------------- CREATING THE FILE AND WRITING THE HEADER ------------------
fls="test.raf";fm("A"); // check file attributes
if(os != " ") {ks="f";fm("D");} // If exists, delete it fs="rf0";rcl=100;ib=true;fm("o");
// open the file as no header file
OS[0]="name";OD[0]=35;
// 35 character string field OS[1]="age";OD[1]=0.0;
// Integer field OS[2]="position";OD[2]=25;
// 25 character string field OS[3]="salary";OD[3]=0.2;
// numeric field with 2-decimal digits fm("wh");
// Write header.
fm("c");
// Close the file. // -------------------------- ENTERING DATA INTO THE FILE -------------------------
fls="test.raf";fs="rf0";fm("o"); // open file and read header information
// Notice that we did not supply rec# OS[0]="John Smith";
// First field data, a string in OS[] OD[1]=25;
// Second field data, a number in OD[] OS[2]="Machine operator";
// Third field data, a string in OS[] OD[3]=35000.50;
// Fourth field data, a number in OD[] rci=1;fm("w");
// Write record #1
OS[0]="Mary Jones";
// OD[1]=20;
// OS[2]="Clerk";
// Field data for second record OD[3]=25000.66;
// rci=2;fm("w");
// Write record #2
fm("c");
// Close the file. // ------------------------------ READING DATA BACK ------------------------------
fls="test.raf";fs="rf0";fm("o"); // open file and read header information
// Notice that we did not supply rec# or any
// field information. The file reads itself. n=1;
// Start by record # 1 while (!dnb) {
// Do until eof encountered. rci=n;fm("r");
// Read one record. (See REMARK) os=OS[0];tm();
// Read and display 1st field os=OS[1];tm();
// Read & display 2nd field os=OS[2];tm();
// Read and display 3rd field os=OS[3];tm();
// Read & display 4th field os="";tm();
// Add blank line to seperate records n++;
// increment record number. } fm("c");
// Close the file. } ========================================================================================= TUTORIAL:
As you can see, at the block of code titeled "CREATING THE FILE AND WRITING THE HEADER", the file did not have a header,
so we opened it as a no header RAF. We wrote the header and closed the file. From this point up, the file is a self read
file, reading it or writing into it does not require supplying any information other than the file name.
At the block of code titled "ENTERING DATA INTO THE FILE", we opened
the file as a RAF with a header (since ib=false), so we did not need to supply rec length. Immediately after the open
statement, we have all field names in OS[] and their type codes in OD[]
If you have forgot what was in the file you can remind yourself by
displaying the two arrays with a code like this:
fls="test.raf";fs="rf0";fm("o");
// open file and read header info; fm("rh");
// Read header for (c=0;c<20;c++) {
// Scan field arrays if (OS[c].Length<1) break;
// Stop at end of data os="Name: "+OS[c]+" Type: "+OD[c];tm();// Display name and type of each field }
This is what you get:
Name: name Type: 35 Name: age Type:
0 Name: position Type: 25 Name: salary Type: 0.2
You may be wondering why we included the read header statement [fm("rh")]
if the open statement have already read the header. The answer is that the open statement reads the header, copies OS[]
and OD[] contents to internal PC# archives then resets OS[] and OD[] so they can be used in the next record read or write
operations.
READING AND WRITING DATA:
You must have noticed that we leave empty gaps into arrays OS[] and
OD[] when we read or write. For example, during writing of the first 3 fields, we skipped
OS[0]="John Smith";
// First field data, a string in OS[] OD[1]=25;
// Second field data, a number in OD[] OS[2]="Machine operator";
// Third field data, a string in OS[]
OD[0],OS[1] and OD[2]. The rule is that when the field is string,
we keep its place in OD[] empty and when the field is numeric we keep its place in OS[] empty. Why do we need these
gaps? In addition to simplicity, After each read operation, numeric field data are formatted according to their type specs
and their string type format is stored into its place in OS[] in addition to their numeric value which is stored in OD[]. =========================================================================================

Example 5: Shows how to write the header of a RAF, write two records
of data into it then read them back.
|